diff --git a/src/components/InteractiveObjects/GltfObject.js b/src/components/InteractiveObjects/GltfObject.js new file mode 100644 index 0000000..1478aa8 --- /dev/null +++ b/src/components/InteractiveObjects/GltfObject.js @@ -0,0 +1,49 @@ +import { Vector3, AnimationMixer } from "three"; +import { assignMaterial } from "@/lib/MeshUtils"; + +class GltfObject { + constructor(engine, obj) { + return new Promise(async(resolve, reject)=>{ + let gltf = await engine.load(obj.value, obj.path); + let gltfObj = gltf.scene; + gltfObj.traverse(function (object) { + object.frustumCulled = false; + if (obj.name && obj.name == object.name) { + gltfObj = object; + } + }); + + assignMaterial(gltfObj, obj); + if (gltf.animations && gltf.animations.length) { + let mixer = new AnimationMixer(gltfObj); + engine.mixers.push(mixer); + let action = mixer.clipAction(gltf.animations[0]); + action.setLoop(LoopPingPong); + action.play(); + } + this.object = gltfObj; + this.source = gltf; + + if (obj.distance) { + const o = this.object; + let dstm = obj.distance; + var oldBR = o.onBeforeRender; + o.visible = false; + engine.addEventListener('beforeRender', function () { + oldBR && oldBR.apply(this, arguments); + var v = new Vector3(); + o.getWorldPosition(v); + var dst = engine.camera.position.distanceTo(v); + if (dst <= dstm && !o.visible) { + o.visible = true; + }else if (dst > dstm && o.visible){ + o.visible = false; + } + }); + } + resolve(this) + }) + } +} + +export { GltfObject } \ No newline at end of file diff --git a/src/components/InteractiveObjects/InteractiveObject.js b/src/components/InteractiveObjects/InteractiveObject.js index 63ea557..25f946e 100644 --- a/src/components/InteractiveObjects/InteractiveObject.js +++ b/src/components/InteractiveObjects/InteractiveObject.js @@ -3,6 +3,7 @@ import { Group, EventDispatcher, MeshStandardMaterial, Mesh, SphereGeometry } fr import { GenericObject } from "./GenenricObject"; import { TextObject } from "./TextObject"; import { ImageObject } from "./ImageObject"; +import { GltfObject } from "./GltfObject"; import { CharacterObject } from "./CharacterObject"; import { VideoPlayer } from "./VideoPlayer"; import { PuzzleGame1 } from "./PuzzleGame1"; @@ -18,7 +19,7 @@ import { assignMaterial, assignParams, wrapInGroup, getBoundingBoxMaxLength } fr import { GameEngine } from "@/lib/GameEngine"; const InteractiveObjectsImports = { - GenericObject, CharacterObject, TextObject, ImageObject, VideoPlayer, Particles, + GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles, PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame, ClassicPuzzle }; @@ -35,30 +36,7 @@ class InteractiveObject extends EventDispatcher{ this.object.add(gameMesh.object); } break; - case 'Gltf': - let gltf = await gameEngine.load(obj.value, ''); - let gltfObj = gltf.scene; - gltfObj.traverse(function (object) { - object.frustumCulled = false; - if (obj.name && obj.name == object.name) { - gltfObj = object; - } - // object.castShadow = true; - // object.receiveShadow = true; - }); - - assignMaterial(gltfObj, obj); - if (gltf.animations && gltf.animations.length) { - let mixer = new AnimationMixer(gltfObj); - gameEngine.mixers.push(mixer); - let action = mixer.clipAction(gltf.animations[0]); - action.setLoop(LoopPingPong); - action.play(); - } - this.object = gltfObj; - this.source = gltf; - break; - + case 'GltfObject': case 'TextObject': case 'ImageObject': case 'GenericObject': @@ -84,6 +62,11 @@ class InteractiveObject extends EventDispatcher{ this.locker.lock(); } assignParams(this.object, obj); + if (obj.motion){ + gameEngine.motionQueue.add({ + o: this.object, ...obj.motion + }); + } resolve(this); }); } diff --git a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js index 9f43a19..bd89212 100644 --- a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js +++ b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js @@ -102,9 +102,10 @@ class MazeQuizGame extends EventDispatcher { userData: { finish: true }, objects:[ { - type: 'Gltf', + type: 'GltfObject', position:[0,.22,len + .52], scale: [0.33, 0.33, 0.33], rotation: [0, Math.PI/4, 0], - value: '/static/meshes/quiz/trophy.glb' + value: 'trophy.glb', path: imgParams.path, distance: params.wallSize*2, + motion: { a:{rotation: { y: k=>k*Math.PI*2 }}, r: true, t: 4 } } ] };