From 3678ad0cfb33ffd01638298c2e965f126f8b561b Mon Sep 17 00:00:00 2001 From: goynov Date: Mon, 24 Nov 2025 08:27:04 +0200 Subject: [PATCH] resolves #21 --- .../InteractiveObjects/CharacterObject.js | 3 +- .../MazeQuizGame/MazeObject.js | 4 +-- src/lib/Hero.js | 31 +++++++++---------- src/lib/MeshUtils.js | 8 ++++- src/mixins/GameEnvironmentMixin.js | 4 +-- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/components/InteractiveObjects/CharacterObject.js b/src/components/InteractiveObjects/CharacterObject.js index 6d53cc2..9a8062a 100644 --- a/src/components/InteractiveObjects/CharacterObject.js +++ b/src/components/InteractiveObjects/CharacterObject.js @@ -1,8 +1,9 @@ +import { bottomOrigin } from "@/lib/MeshUtils"; class CharacterObject{ constructor(engine, data){ return new Promise(async(resolve, reject)=>{ this.source = await engine.load(data.$go.asset.name); - this.object = this.source.scene; + this.object = bottomOrigin(this.source.scene); resolve(this); }) } diff --git a/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js b/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js index 6c434e9..96230f9 100644 --- a/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js +++ b/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js @@ -145,7 +145,7 @@ class MazeObject { }); this.mazeObject(def, room); - let floorSize = { width: (bbox.r - bbox.l + 10*scale)/2, height: 0.01, depth: (bbox.f + 10*scale)/2 } + let floorSize = { width: (bbox.r - bbox.l + 10*scale)/2, height: 1, depth: (bbox.f + 10*scale)/2 } const floorGeometry = new PlaneGeometry(floorSize.width*2, floorSize.depth*2); const floor = new Mesh(floorGeometry,new MeshStandardMaterial({ roughness: 0, metalness:1, color: 0x00ffff, side: DoubleSide @@ -155,7 +155,7 @@ class MazeObject { root.add(floor); let pf = engine.physics.add({position: floor.position}, 'fixed', false, undefined, 'cuboid', floorSize) //pf.collider.setRestitution(0); - //pf.collider.setTranslationWrtParent({x:0, y: -100, z:0}) + pf.collider.setTranslationWrtParent({x:0, y: -floorSize.height, z:0}) } } } diff --git a/src/lib/Hero.js b/src/lib/Hero.js index 6f3a698..1066f4c 100644 --- a/src/lib/Hero.js +++ b/src/lib/Hero.js @@ -1,6 +1,6 @@ import { AnimationMixer, Vector3, Clock } from 'three'; import { PointerControls } from './PointerControls'; -import { getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxSize } from './MeshUtils'; +import { getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxSize, centerOrigin } from './MeshUtils'; import { QueryFilterFlags } from '@dimforge/rapier3d'; class Hero{ @@ -21,12 +21,14 @@ class Hero{ fadeDuration = 0.2 runVelocity = 11 walkVelocity = 7 + characterGapOffset = 0.1; + lerp = (x, y, a) => x * (1 - a) + y * a; - constructor(object, data){ - this.object = object; + constructor(io, data){ + this.source = io.source; + this.model = io.object this.data = data; - this.model = object.scene } init(gameEngine){ @@ -36,31 +38,25 @@ class Hero{ gameEngine.mixers.push( this.mixer ); this.animationsMap = {}; - this.object.animations.forEach(a=>{ + this.source.animations.forEach(a=>{ this.animationsMap[a.name] = this.mixer.clipAction(a); }) this.pointerControls = new PointerControls(gameEngine.camera, this.model, gameEngine.renderer.domElement); gameEngine.hero = this; - let bb = getBoundingBox(this.model); + let bb = this.model.userData.bbox; let size = getBoundingBoxSize(bb); - let center = getBoundingBoxCenterPoint(bb, this.model.position) + let center = getBoundingBoxCenterPoint(bb, this.model.userData.object.position) this.po = gameEngine.physics.add(this.model, 'kinematicPositionBased', false, undefined, 'capsule', { radius: size.x/2, halfHeight: size.y/2}) - this.po.collider.setTranslationWrtParent({x: center.x, y: center.y + size.y/2, z: center.z}); + this.po.collider.setTranslationWrtParent({x: center.x, y: center.y + size.y/2 + this.characterGapOffset, z: center.z}); + - this.initCharacterControls(); - - this.clock = new Clock() - this.ready = true; - } - - initCharacterControls(){ this.currentAction = 'idle'; this.animationsMap[this.currentAction].play() - this.characterController = this.gameEngine.physics.world.createCharacterController(0.1); + this.characterController = this.gameEngine.physics.world.createCharacterController(this.characterGapOffset); this.characterController.setUp({x:0, y:1, z:0}); this.po.rigidBody.setTranslation(this.model.position) this.po.characterController = this.characterController; @@ -81,6 +77,9 @@ class Hero{ this.actionStart = 0; this.cameraDelta = 0; this.cameraIdleDelta = 0; + + this.clock = new Clock() + this.ready = true; } lockControls(){ diff --git a/src/lib/MeshUtils.js b/src/lib/MeshUtils.js index 5bc6b74..dbdc85a 100644 --- a/src/lib/MeshUtils.js +++ b/src/lib/MeshUtils.js @@ -72,7 +72,13 @@ function centerOrigin(object){ return group; } +function bottomOrigin(object){ + let group = centerOrigin(object); + group.userData.object.position.y += (group.userData.bbox.max.y - group.userData.bbox.min.y)/2 + return group; +} + export { - assignParams, assignMaterial, autoScale, centerOrigin, wrapInGroup, + assignParams, assignMaterial, autoScale, centerOrigin, wrapInGroup, bottomOrigin, getBoundingBox, getBoundingBoxSize, getBoundingBoxMaxLength, getBoundingBoxCenterPoint } \ No newline at end of file diff --git a/src/mixins/GameEnvironmentMixin.js b/src/mixins/GameEnvironmentMixin.js index acb3296..e978ee7 100644 --- a/src/mixins/GameEnvironmentMixin.js +++ b/src/mixins/GameEnvironmentMixin.js @@ -2,7 +2,7 @@ import { InteractiveObject } from '@/components/InteractiveObjects/InteractiveOb import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer'; import { GameEngine } from '@/lib/GameEngine'; import { Hero } from '@/lib/Hero'; -import { autoScale, getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxSize } from '@/lib/MeshUtils'; +import { autoScale, getBoundingBox, getBoundingBoxSize } from '@/lib/MeshUtils'; import Utils from '@/lib/Utils'; let gameEngine = null; @@ -168,7 +168,7 @@ export default { gameEngine.activeObjects.add(io.object); if (this.env != 'GameDesigner'){ if (i.data.$go?.type == 'player3d'){ - let hero = new Hero(io.source, i.data.$go); + let hero = new Hero(io, i.data.$go); hero.init(gameEngine); }else{ if (io.source?.animations?.length){