diff --git a/packages/frontend/assets/room/objects/ceiling-fan-light/ceiling-fan-light.blend b/packages/frontend/assets/room/objects/ceiling-fan-light/ceiling-fan-light.blend new file mode 100644 index 0000000000..b75b5a0ebf Binary files /dev/null and b/packages/frontend/assets/room/objects/ceiling-fan-light/ceiling-fan-light.blend differ diff --git a/packages/frontend/assets/room/objects/ceiling-fan-light/ceiling-fan-light.glb b/packages/frontend/assets/room/objects/ceiling-fan-light/ceiling-fan-light.glb new file mode 100644 index 0000000000..9d02b14b37 Binary files /dev/null and b/packages/frontend/assets/room/objects/ceiling-fan-light/ceiling-fan-light.glb differ diff --git a/packages/frontend/src/pages/room.vue b/packages/frontend/src/pages/room.vue index 502469cdae..cfaaf80bcf 100644 --- a/packages/frontend/src/pages/room.vue +++ b/packages/frontend/src/pages/room.vue @@ -171,6 +171,11 @@ onMounted(() => { type: 'bed', position: [-30, 0, -100], rotation: [0, 0, 0], + }, { + id: 'v', + type: 'ceiling-fan-light', + position: [0, 250, 0], + rotation: [0, 0, 0], }], }, { canvas: canvas.value!, diff --git a/packages/frontend/src/utility/room/engine.ts b/packages/frontend/src/utility/room/engine.ts index c416107cb8..603881b099 100644 --- a/packages/frontend/src/utility/room/engine.ts +++ b/packages/frontend/src/utility/room/engine.ts @@ -37,7 +37,9 @@ type RoomDef = { }; type ObjectDef = { - placement: 'top' | 'side'; + placement: 'top' | 'side' | 'bottom'; + receiveShadows?: boolean; + castShadows?: boolean; onInit?: (room: RoomEngine, o: RoomDef['objects'][0], obj: BABYLON.ISceneLoaderAsyncResult) => void; }; @@ -251,10 +253,16 @@ const OBJECTS = { ps.start(); }, }, - desk: { + 'desk': { placement: 'top', }, - chair: { + 'chair': { + placement: 'top', + }, + 'chair2': { + placement: 'top', + }, + 'energy-drink': { placement: 'top', }, 'banknote': { @@ -269,6 +277,26 @@ const OBJECTS = { 'monitor': { placement: 'top', }, + 'keyboard': { + placement: 'top', + }, + 'ceiling-fan-light': { + placement: 'bottom', + receiveShadows: false, + castShadows: false, + onInit: (room, o, obj) => { + const rotor = obj.meshes[0].getChildMeshes().find(m => m.name === 'Rotor') as BABYLON.Mesh; + rotor.rotationQuaternion = null; + console.log(obj.meshes, obj.meshes[0].getChildMeshes().map(x => x.name), rotor, rotor.getChildMeshes()); + const anim = new BABYLON.Animation('', 'rotation.y', 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE); + anim.setKeys([ + { frame: 0, value: 0 }, + { frame: 100, value: Math.PI * 2 }, + ]); + rotor.animations = [anim]; + room.scene.beginAnimation(rotor, 0, 100, true); + }, + }, } as Record; function vecToLocal(vector: BABYLON.Vector3, mesh: BABYLON.Mesh): BABYLON.Vector3 { @@ -445,7 +473,7 @@ export class RoomEngine { this.envMapIndoor = BABYLON.CubeTexture.CreateFromPrefilteredData('/client-assets/room/indoor.env', this.scene); this.envMapIndoor.boundingBoxSize = new BABYLON.Vector3(500/*cm*/, 300/*cm*/, 500/*cm*/); - this.envMapOutdoor = BABYLON.CubeTexture.CreateFromPrefilteredData(this.time === 2 ? '/client-assets/room/outdoor-night.env' : '/client-assets/room/outdoor-dayw.env', this.scene); + this.envMapOutdoor = BABYLON.CubeTexture.CreateFromPrefilteredData(this.time === 2 ? '/client-assets/room/outdoor-night.env' : '/client-assets/room/outdoor-day.env', this.scene); this.envMapOutdoor.level = this.time === 0 ? 0.5 : this.time === 1 ? 0.3 : 0.1; if (this.enableReflectionProbe) { @@ -855,6 +883,8 @@ export class RoomEngine { } private async loadObject(o: RoomDef['objects'][0]) { + const def = OBJECTS[o.type]; + const obj = await BABYLON.ImportMeshAsync(`/client-assets/room/objects/${o.type}/${o.type}.glb`, this.scene); obj.meshes[0].scaling = new BABYLON.Vector3(-100, 100, 100); obj.meshes[0].bakeCurrentTransformIntoVertices(); @@ -889,9 +919,11 @@ export class RoomEngine { mesh.isVisible = false; } else { //if (mesh.name === '__root__') continue; - mesh.receiveShadows = true; - this.shadowGenerator1.addShadowCaster(mesh); - this.shadowGenerator2.addShadowCaster(mesh); + if (def.receiveShadows !== false) mesh.receiveShadows = true; + if (def.castShadows !== false) { + this.shadowGenerator1.addShadowCaster(mesh); + this.shadowGenerator2.addShadowCaster(mesh); + } mesh.renderOutline = false; mesh.outlineWidth = 0.003;