This commit is contained in:
2025-11-24 08:27:04 +02:00
parent c67ffd774b
commit 3678ad0cfb
5 changed files with 28 additions and 22 deletions
@@ -1,8 +1,9 @@
import { bottomOrigin } from "@/lib/MeshUtils";
class CharacterObject{ class CharacterObject{
constructor(engine, data){ constructor(engine, data){
return new Promise(async(resolve, reject)=>{ return new Promise(async(resolve, reject)=>{
this.source = await engine.load(data.$go.asset.name); this.source = await engine.load(data.$go.asset.name);
this.object = this.source.scene; this.object = bottomOrigin(this.source.scene);
resolve(this); resolve(this);
}) })
} }
@@ -145,7 +145,7 @@ class MazeObject {
}); });
this.mazeObject(def, room); 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 floorGeometry = new PlaneGeometry(floorSize.width*2, floorSize.depth*2);
const floor = new Mesh(floorGeometry,new MeshStandardMaterial({ const floor = new Mesh(floorGeometry,new MeshStandardMaterial({
roughness: 0, metalness:1, color: 0x00ffff, side: DoubleSide roughness: 0, metalness:1, color: 0x00ffff, side: DoubleSide
@@ -155,7 +155,7 @@ class MazeObject {
root.add(floor); root.add(floor);
let pf = engine.physics.add({position: floor.position}, 'fixed', false, undefined, 'cuboid', floorSize) let pf = engine.physics.add({position: floor.position}, 'fixed', false, undefined, 'cuboid', floorSize)
//pf.collider.setRestitution(0); //pf.collider.setRestitution(0);
//pf.collider.setTranslationWrtParent({x:0, y: -100, z:0}) pf.collider.setTranslationWrtParent({x:0, y: -floorSize.height, z:0})
} }
} }
} }
+14 -15
View File
@@ -1,6 +1,6 @@
import { AnimationMixer, Vector3, Clock } from 'three'; import { AnimationMixer, Vector3, Clock } from 'three';
import { PointerControls } from './PointerControls'; import { PointerControls } from './PointerControls';
import { getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxSize } from './MeshUtils'; import { getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxSize, centerOrigin } from './MeshUtils';
import { QueryFilterFlags } from '@dimforge/rapier3d'; import { QueryFilterFlags } from '@dimforge/rapier3d';
class Hero{ class Hero{
@@ -21,12 +21,14 @@ class Hero{
fadeDuration = 0.2 fadeDuration = 0.2
runVelocity = 11 runVelocity = 11
walkVelocity = 7 walkVelocity = 7
characterGapOffset = 0.1;
lerp = (x, y, a) => x * (1 - a) + y * a; lerp = (x, y, a) => x * (1 - a) + y * a;
constructor(object, data){ constructor(io, data){
this.object = object; this.source = io.source;
this.model = io.object
this.data = data; this.data = data;
this.model = object.scene
} }
init(gameEngine){ init(gameEngine){
@@ -36,31 +38,25 @@ class Hero{
gameEngine.mixers.push( this.mixer ); gameEngine.mixers.push( this.mixer );
this.animationsMap = {}; this.animationsMap = {};
this.object.animations.forEach(a=>{ this.source.animations.forEach(a=>{
this.animationsMap[a.name] = this.mixer.clipAction(a); this.animationsMap[a.name] = this.mixer.clipAction(a);
}) })
this.pointerControls = new PointerControls(gameEngine.camera, this.model, gameEngine.renderer.domElement); this.pointerControls = new PointerControls(gameEngine.camera, this.model, gameEngine.renderer.domElement);
gameEngine.hero = this; gameEngine.hero = this;
let bb = getBoundingBox(this.model); let bb = this.model.userData.bbox;
let size = getBoundingBoxSize(bb); 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 = 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.currentAction = 'idle';
this.animationsMap[this.currentAction].play() 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.characterController.setUp({x:0, y:1, z:0});
this.po.rigidBody.setTranslation(this.model.position) this.po.rigidBody.setTranslation(this.model.position)
this.po.characterController = this.characterController; this.po.characterController = this.characterController;
@@ -81,6 +77,9 @@ class Hero{
this.actionStart = 0; this.actionStart = 0;
this.cameraDelta = 0; this.cameraDelta = 0;
this.cameraIdleDelta = 0; this.cameraIdleDelta = 0;
this.clock = new Clock()
this.ready = true;
} }
lockControls(){ lockControls(){
+7 -1
View File
@@ -72,7 +72,13 @@ function centerOrigin(object){
return group; 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 { export {
assignParams, assignMaterial, autoScale, centerOrigin, wrapInGroup, assignParams, assignMaterial, autoScale, centerOrigin, wrapInGroup, bottomOrigin,
getBoundingBox, getBoundingBoxSize, getBoundingBoxMaxLength, getBoundingBoxCenterPoint getBoundingBox, getBoundingBoxSize, getBoundingBoxMaxLength, getBoundingBoxCenterPoint
} }
+2 -2
View File
@@ -2,7 +2,7 @@ import { InteractiveObject } from '@/components/InteractiveObjects/InteractiveOb
import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer'; import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer';
import { GameEngine } from '@/lib/GameEngine'; import { GameEngine } from '@/lib/GameEngine';
import { Hero } from '@/lib/Hero'; 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'; import Utils from '@/lib/Utils';
let gameEngine = null; let gameEngine = null;
@@ -168,7 +168,7 @@ export default {
gameEngine.activeObjects.add(io.object); gameEngine.activeObjects.add(io.object);
if (this.env != 'GameDesigner'){ if (this.env != 'GameDesigner'){
if (i.data.$go?.type == 'player3d'){ 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); hero.init(gameEngine);
}else{ }else{
if (io.source?.animations?.length){ if (io.source?.animations?.length){