intermediate

This commit is contained in:
2025-10-17 11:55:39 +03:00
parent 49e0486277
commit 0018d513eb
8 changed files with 195 additions and 158 deletions
+148 -47
View File
@@ -17,27 +17,43 @@ export class CharacterControls {
walkVelocity = 3
lerp = (x, y, a) => x * (1 - a) + y * a;
constructor(model, mixer, animationsMap, orbitControl, camera, currentAction, ray, rigidBody, pointerControls) {
constructor(model, mixer, animationsMap, engine, currentAction, po, pointerControls) {
this.model = model
this.mixer = mixer
this.animationsMap = animationsMap
this.currentAction = currentAction
this.animationsMap[currentAction].play()
this.ray = ray
this.rigidBody = rigidBody
this.characterController = engine.phy.world.createCharacterController(0.1);
this.characterController.setUp({x:0, y:1, z:0});
po.rigidBody.setTranslation(this.model.position)
// this.characterController.enableSnapToGround(0.5);
// // Dont allow climbing slopes larger than 45 degrees.
// this.characterController.setMaxSlopeClimbAngle(45 * Math.PI / 180);
// // Automatically slide down on slopes smaller than 30 degrees.
// this.characterController.setMinSlopeSlideAngle(30 * Math.PI / 180);
// this.characterController.enableAutostep(0.5, 0.2, true);
// this.characterController.setApplyImpulsesToDynamicBodies(true);
// this.characterController.setCharacterMass(50);
this.po = po;
this.pointerControls = pointerControls
this.orbitControl = orbitControl
this.camera = camera
this.orbitControl = engine.orbitControls
this.camera = engine.camera
this.updateCameraTarget(new THREE.Vector3(0,1,5))
this._v = new THREE.Vector3();
this.velocity = new THREE.Vector3();
this.forceDirection = new THREE.Vector3();
this.forceAcceleration = 1 / 32;
this.forceSpeedMax = 0.075;
}
switchRunToggle() {
this.toggleRun = !this.toggleRun
}
update(world, delta, pointerControls) {
update0(world, delta, pointerControls) {
const directionPressed = pointerControls.moving()
var play = '';
@@ -86,51 +102,74 @@ export class CharacterControls {
velocity = this.currentAction == 'run' ? this.runVelocity : this.walkVelocity
}
const translation = this.rigidBody.translation();
if (translation.y < -1) {
// don't fall below ground
this.rigidBody.setNextKinematicTranslation( {
x: 0,
y: 10,
z: 0
});
} else {
const cameraPositionOffset = this.camera.position.sub(this.model.position);
// update model and camera
this.model.position.x = translation.x
this.model.position.y = translation.y
this.model.position.z = translation.z
this.updateCameraTarget(cameraPositionOffset)
this.walkDirection.y += this.lerp(this.storedFall, -9.81 * delta, 0.10)
this.storedFall = this.walkDirection.y
this.ray.origin.x = translation.x
this.ray.origin.y = translation.y
this.ray.origin.z = translation.z
let hit = world.castRay(this.ray, 0.5, false, 0xfffffffff);
if (hit) {
const point = this.ray.pointAt(hit.timeOfImpact);
let diff = translation.y - ( point.y + CONTROLLER_BODY_RADIUS);
if (diff < 0.0) {
this.storedFall = 0
this.walkDirection.y = this.lerp(0, -diff, 0.5)
}
}
this.walkDirection.x = this.walkDirection.x * velocity * delta
this.walkDirection.z = this.walkDirection.z * velocity * delta
this.walkDirection.x = this.walkDirection.x * velocity * delta + this.model.position.x
this.walkDirection.z = this.walkDirection.z * velocity * delta + this.model.position.z
this.rigidBody.setNextKinematicTranslation( {
x: translation.x + this.walkDirection.x,
y: translation.y + this.walkDirection.y,
z: translation.z + this.walkDirection.z
});
}
//const translation = this.rigidBody.translation();
//const translation = characterController.computedMovement();
this.characterController.computeColliderMovement(
this.po.collider, // The collider we would like to move.
this.walkDirection, // The movement we would like to apply if there wasnt any obstacle.
);
// for (let i = 0; i < this.characterController.numComputedCollisions(); i++) {
// let collision = this.characterController.computedCollision(i);
// console.log('c', collision)
// // Do something with that collision information.
// }
let correctedMovement = this.characterController.computedMovement();
this.po.rigidBody.setNextKinematicTranslation(correctedMovement);
//this.po.rigidBody.setNextKinematicRotation(this.rotateQuarternion);
// if (translation.y < -1) {
// // don't fall below ground
// this.rigidBody.setNextKinematicTranslation( {
// x: 0,
// y: 10,
// z: 0
// });
// } else {
const cameraPositionOffset = this.camera.position.sub(this.model.position);
this.model.position.copy(correctedMovement)
// // update model and camera
// this.model.position.x = translation.x
// this.model.position.y = translation.y
// this.model.position.z = translation.z
this.updateCameraTarget(cameraPositionOffset, correctedMovement)
// this.walkDirection.y += this.lerp(this.storedFall, -9.81 * delta, 0.10)
// this.storedFall = this.walkDirection.y
// this.ray.origin.x = translation.x
// this.ray.origin.y = translation.y
// this.ray.origin.z = translation.z
// let hit = world.castRay(this.ray, 0.5, false, 0xfffffffff);
// if (hit) {
// const point = this.ray.pointAt(hit.timeOfImpact);
// let diff = translation.y - ( point.y + CONTROLLER_BODY_RADIUS);
// if (diff < 0.0) {
// this.storedFall = 0
// this.walkDirection.y = this.lerp(0, -diff, 0.5)
// }
// }
// this.walkDirection.x = this.walkDirection.x * velocity * delta
// this.walkDirection.z = this.walkDirection.z * velocity * delta
// this.rigidBody.setNextKinematicTranslation( {
// x: translation.x + this.walkDirection.x,
// y: translation.y + this.walkDirection.y,
// z: translation.z + this.walkDirection.z
// });
// }
}
updateCameraTarget(offset) {
updateCameraTarget(offset, cm) {
// move camera
const rigidTranslation = this.rigidBody.translation();
const rigidTranslation = cm || this.po.rigidBody.translation();
this.camera.position.x = rigidTranslation.x + offset.x
this.camera.position.y = rigidTranslation.y + offset.y
this.camera.position.z = rigidTranslation.z + offset.z
@@ -168,4 +207,66 @@ export class CharacterControls {
return directionOffset
}
update (world, delta, pointerControls){
// Calculate input buffer
// if (this.jumpBuffer > 0) {
// this.jumpBuffer -= loop.delta; // ms
// // Automatically jump if buffer is set
// if (this.allowJump === true) {
// this.jumpBuffer = 0;
// this.jump();
// }
// }
// Add fake friction and fake gravity
this.velocity.x *= 0.75;
this.velocity.z *= 0.75;
this.velocity.y -= 0.005;
// Update force direction from user input
let xDirection = 0;
let zDirection = 0;
if (pointerControls.moveForward) zDirection = -1;
if (pointerControls.moveBackward) zDirection = 1;
if (pointerControls.moveRight) xDirection = 1;
if (pointerControls.moveLeft) xDirection = -1;
// Set the new force direction
this.forceDirection.copy({ x: xDirection, y: 0, z: zDirection }); // Ex: -1.0 to 1.0
// Decrease acceleration if the velocity speed equals the force speed
this._v.copy(this.velocity);
const speed = this._v.dot(this.forceDirection);
const speedNext = speed + this.forceAcceleration;
const speedClamped = Math.max(speed, Math.min(speedNext, this.forceSpeedMax));
const acceleration = speedClamped - speed; // Ex: 0.5 (or 0 at max speed)
// Add force to velocity using new acceleration
this.velocity.x += this.forceDirection.x * acceleration;
this.velocity.y += this.forceDirection.y * acceleration;
this.velocity.z += this.forceDirection.z * acceleration;
// Set the next kinematic translation
if (this.po.rigidBody.numColliders() > 0) {
this.characterController.computeColliderMovement(this.po.collider, this.velocity);
this._v.copy(this.po.rigidBody.translation());
this._v.add(this.characterController.computedMovement());
this.po.rigidBody.setNextKinematicTranslation(this._v);
}
// Calculate 3D object rotation from character translation
this._v.copy(this.po.rigidBody.nextTranslation());
if (this._v.distanceTo(this.po.rigidBody.translation()) > 0.01) {
this.model.lookAt(this._v.x, this.model.position.y, this._v.z);
this.po.rigidBody.setNextKinematicRotation(this.model.quaternion);
}
// Set vertical velocity to zero if grounded
// if (this.characterController.computedGrounded()) {
// this.allowJump = true;
// this.entity.velocity.y = 0;
// }
}
}