diff --git a/frontend/src/CharacterHandler.ts b/frontend/src/CharacterHandler.ts new file mode 100644 index 00000000..63bce2c5 --- /dev/null +++ b/frontend/src/CharacterHandler.ts @@ -0,0 +1,73 @@ +import {Vector2, Vector3, Vector4} from "math.gl"; +import Renderer from "./lib/Renderer"; +import Camera from "./lib/Camera"; +import AnimationMixer from "./lib/animation/AnimationMixer"; +import Object3D from "./lib/core/Object3D"; + + + +export default class CharacterHandler { + private renderer: Renderer; + private camera: Camera; + private animationMixer: AnimationMixer; + private characterRoot: Object3D; + private floorHit: boolean =false; + private floorPos:Vector3 =new Vector3(0,-1.5,0); + private up:Vector3 =new Vector3(0,1,0); + private floorPlane:Vector3 =new Vector3(0,-1.5,0); + constructor(renderer: Renderer, camera: Camera, characterRoot:Object3D, animationMixer: AnimationMixer) { + this.renderer = renderer; + this.camera = camera; + this.animationMixer = animationMixer; + this.characterRoot =characterRoot; + + this.characterRoot.setPosition(this.floorPos.x,this.floorPos.y,this.floorPos.z) + } + + update(mousePos: Vector2, down: boolean) { + + this.setMouseFloorPos(mousePos.clone()); + + if(this.floorHit){ + this.characterRoot.setPosition(this.floorPos.x,this.floorPos.y,this.floorPos.z) + } + } + + private setMouseFloorPos(mousePos: Vector2) { + mousePos.scale(new Vector2(2 / (this.renderer.width / this.renderer.pixelRatio), 2 / (this.renderer.height / this.renderer.pixelRatio))) + let pos = new Vector4(mousePos.x - 1, (mousePos.y - 1)*-1, 1, 1); + if (this.camera.viewProjectionInv) { + pos.transform(this.camera.viewProjectionInv); + let rayStart = this.camera.cameraWorld.clone() + let rayDir = new Vector3(pos.x-rayStart.x, pos.y-rayStart.y, pos.z-rayStart.z).normalize() + + + let denom = this.up.dot(rayDir); + if (Math.abs(denom) > 0.01) // your favorite epsilon + { + + let t = (this.floorPlane.clone().subtract(rayStart)).dot(this.up) / denom; + if (t < 0) { + this.floorHit =false; + return; + } else { + rayDir.scale(t); + rayStart.add(rayDir); + if ( rayStart.z<-3){ + this.floorHit =false; + return; + } + this.floorHit =true; + this.floorPos = rayStart.clone() + + } + + + } else { + this.floorHit =false; + } + + + } + } +} diff --git a/frontend/src/Main.ts b/frontend/src/Main.ts index cc574c4d..706a5a7d 100644 --- a/frontend/src/Main.ts +++ b/frontend/src/Main.ts @@ -37,6 +37,7 @@ import MainLight from "./MainLight"; import TransformDebugger from "./lib/animation/TransformDebugger"; import AnimationMixer from "./lib/animation/AnimationMixer"; +import CharacterHandler from "./CharacterHandler"; export default class Main { @@ -76,9 +77,9 @@ export default class Main { private centerRightHolder: Object3D; private glFTLoaderChar: GLFTLoader; - private transformDebugger: TransformDebugger; + //private transformDebugger: TransformDebugger; private animationMixer: AnimationMixer; - +private characterHandler:CharacterHandler; constructor(canvas: HTMLCanvasElement) { @@ -156,18 +157,19 @@ export default class Main { } - // this.glFTLoaderChar.root.setPosition(0, -1.5, 0); for (let m of this.glFTLoaderChar.models) { this.gBufferPass.modelRenderer.addModel(m) - // this.glFTLoaderChar.root.addChild(m) } this.animationMixer = new AnimationMixer() this.animationMixer.setAnimations(this.glFTLoaderChar.animations) + + + this.characterHandler =new CharacterHandler(this.renderer,this.camera, this.glFTLoaderChar.root,this.animationMixer) // this.transformDebugger =new TransformDebugger(this.renderer, this.gBufferPass.modelRenderer,this.glFTLoaderChar.root.children[0]); this.shadowPass.setModels(this.gBufferPass.modelRenderer.models); @@ -223,6 +225,10 @@ export default class Main { } private update() { + + + this.characterHandler.update( this.mouseListener.mousePos.clone(),this.mouseListener.isDownThisFrame) + this.animationMixer.update(); this.leftHolder.setPosition(-this.renderer.ratio * 3 / 2, 0, 0) @@ -230,7 +236,7 @@ export default class Main { this.centerRightHolder.setPosition(-this.renderer.ratio * 3 / 4 +2, 0, 0) this.glFTLoader.root.setPosition(0, -1.5, 0) - this.glFTLoaderChar.root.setPosition(1, -1.5, -1); + this.updateCamera(); this.mill.update(); diff --git a/frontend/src/extras/Mill.ts b/frontend/src/extras/Mill.ts index b5ef3e4c..a7cf2c21 100644 --- a/frontend/src/extras/Mill.ts +++ b/frontend/src/extras/Mill.ts @@ -13,7 +13,8 @@ export default class Mill{ this.millBed =mill.children[0]; this.millHead =mill.children[2]; - this.tl = gsap.timeline({repeat: 1000, repeatDelay: 1}); + this.tl = gsap.timeline({repeat: -1, repeatDelay: 1,}); + this.tl.timeScale(3); this.tl.to(this,{"headPos":0.0,ease: "sine.inOut"}) this.tl.to(this,{"bedZ":0.2,duration:4,ease: "sine.inOut"},">") this.tl.to(this,{"headPos":0.1,ease: "sine.inOut"},">") diff --git a/frontend/src/lib/Camera.ts b/frontend/src/lib/Camera.ts index e02945ae..5eb4dd98 100644 --- a/frontend/src/lib/Camera.ts +++ b/frontend/src/lib/Camera.ts @@ -16,8 +16,10 @@ export default class Camera extends UniformGroup { private view: Matrix4 = new Matrix4(); private projection: Matrix4 = new Matrix4(); private viewProjection: Matrix4 = new Matrix4(); - private viewProjectionInv!: Matrix4; + public viewProjectionInv!: Matrix4; + public viewInv!: Matrix4; + public projectionInv!: Matrix4; constructor(renderer: Renderer, label: string) { super(renderer, label, "camera"); @@ -101,6 +103,13 @@ export default class Camera extends UniformGroup { center: this.cameraLookAt, up: this.cameraUp, }); + this.viewInv = this.view.clone(); + this.viewInv.invert(); + + this.projectionInv = this.projection.clone(); + this.projectionInv.invert(); + + this.viewProjection.identity(); this.viewProjection.multiplyRight(this.projection); this.viewProjection.multiplyRight(this.view);