diff --git a/packages/frontend/assets/room/objects/books/books.blend b/packages/frontend/assets/room/objects/books/books.blend index 1a44ec676e..2d9fb150d1 100644 Binary files a/packages/frontend/assets/room/objects/books/books.blend and b/packages/frontend/assets/room/objects/books/books.blend differ diff --git a/packages/frontend/assets/room/objects/books/books.glb b/packages/frontend/assets/room/objects/books/books.glb index a820d4f96f..7ef2e6cb4e 100644 Binary files a/packages/frontend/assets/room/objects/books/books.glb and b/packages/frontend/assets/room/objects/books/books.glb differ diff --git a/packages/frontend/src/utility/room/engine.ts b/packages/frontend/src/utility/room/engine.ts index 9350784b05..9c88947b03 100644 --- a/packages/frontend/src/utility/room/engine.ts +++ b/packages/frontend/src/utility/room/engine.ts @@ -103,6 +103,8 @@ type ObjectDef = { default: GetOptionsSchemaValues; }; placement: 'top' | 'side' | 'bottom' | 'wall' | 'ceiling' | 'floor'; + //groupingMeshes: string[]; // multi-materialなメッシュは複数のメッシュに分割されるが、それだと不便な場合に追加の親メッシュでグルーピングするための指定 + mergeMeshes?: string[] | null; // multi-materialなメッシュは複数のメッシュに分割されるが、それだと不便な場合にメッシュをマージするための指定 isChair?: boolean; createInstance: (args: { room: RoomEngine; @@ -793,6 +795,20 @@ export class RoomEngine { const loaderResult = await BABYLON.ImportMeshAsync(`/client-assets/room/objects/${camelToKebab(args.type)}/${camelToKebab(args.type)}.glb`, this.scene); + // babylonによって自動で追加される右手系変換用ノード + const subRoot = loaderResult.meshes[0]; + subRoot.scaling = subRoot.scaling.scale(WORLD_SCALE);// cmをmに + + if (def.mergeMeshes != null) { + for (const groupingMeshKeyword of def.mergeMeshes) { + const meshes = loaderResult.meshes.filter(m => m.name.includes(groupingMeshKeyword)); + const merged = BABYLON.Mesh.MergeMeshes(meshes as BABYLON.Mesh[], true, true, undefined, false, true); + merged.name = `${groupingMeshKeyword}.grouped`; + merged.setParent(subRoot); + loaderResult.meshes.push(merged); + } + } + let hasCollisionMesh = false; for (const mesh of loaderResult.meshes) { if (mesh.name.includes('__COLLISION__')) { @@ -808,10 +824,6 @@ export class RoomEngine { isCollision: !hasCollisionMesh, }; - // babylonによって自動で追加される右手系変換用ノード - const subRoot = loaderResult.meshes[0]; - subRoot.scaling = subRoot.scaling.scale(WORLD_SCALE);// cmをmに - root.addChild(subRoot); root.position = args.position.clone(); @@ -1071,20 +1083,35 @@ export class RoomEngine { const materials = new WeakMap(); - for (const m of ghost.getChildMeshes()) { + for (const m of ghost.getChildMeshes() as BABYLON.Mesh[]) { m.metadata = { isGhost: true }; m.checkCollisions = false; - if (m.material) { - if (materials.has(m.material)) { - m.material = materials.get(m.material)!; - } else { - const mat = m.material.clone(`${m.material.name}_ghost`); - mat.alpha = 0.3; - mat.transparencyMode = BABYLON.Material.MATERIAL_ALPHABLEND; - materials.set(m.material, mat); - m.material = mat; + if (m.material == null) continue; + + if (materials.has(m.material)) { + m.material = materials.get(m.material)!; + continue; + } + + if (m.subMeshes != null && m.subMeshes.length > 0 && m.material.subMaterials != null) { + const multiGhostMaterial = m.material.clone(`${m.material.name}_ghost`) as BABYLON.MultiMaterial; + + for (let i = 0; i < multiGhostMaterial.subMaterials.length; i++) { + const subMaterial = multiGhostMaterial.subMaterials[i]; + const ghostMaterial = subMaterial.clone(`${subMaterial.name}_ghost`); + ghostMaterial.alpha = 0.3; + ghostMaterial.transparencyMode = BABYLON.Material.MATERIAL_ALPHABLEND; + multiGhostMaterial.subMaterials[i] = ghostMaterial; + materials.set(m.material, multiGhostMaterial); + m.material = multiGhostMaterial; } + } else { + const ghostMaterial = m.material.clone(`${m.material.name}_ghost`); + ghostMaterial.alpha = 0.3; + ghostMaterial.transparencyMode = BABYLON.Material.MATERIAL_ALPHABLEND; + materials.set(m.material, ghostMaterial); + m.material = ghostMaterial; } } diff --git a/packages/frontend/src/utility/room/objects/books.ts b/packages/frontend/src/utility/room/objects/books.ts index 6afad2dcdb..61b49c9095 100644 --- a/packages/frontend/src/utility/room/objects/books.ts +++ b/packages/frontend/src/utility/room/objects/books.ts @@ -13,7 +13,28 @@ export const books = defineObject({ default: {}, }, placement: 'top', - createInstance: () => { + mergeMeshes: ['__X_BOOK_1__', '__X_BOOK_2__', '__X_BOOK_3__', '__X_BOOK_4__', '__X_BOOK_5__', '__X_BOOK_6__', '__X_BOOK_7__', '__X_BOOK_8__', '__X_BOOK_9__', '__X_BOOK_10__'], + createInstance: ({ findMesh, root }) => { + console.log(root.getChildMeshes().map((m) => m.name)); + + const bookMeshes = [ + findMesh('__X_BOOK_1__'), + findMesh('__X_BOOK_2__'), + findMesh('__X_BOOK_3__'), + findMesh('__X_BOOK_4__'), + findMesh('__X_BOOK_5__'), + findMesh('__X_BOOK_6__'), + findMesh('__X_BOOK_7__'), + findMesh('__X_BOOK_8__'), + findMesh('__X_BOOK_9__'), + findMesh('__X_BOOK_10__'), + ]; + + for (const mesh of bookMeshes) { + mesh.position.z -= Math.random() * 0.005/*cm*/; + mesh.position.y += Math.random() * 0.0025/*cm*/; + } + return { interactions: {}, };