intermediate
This commit is contained in:
+148
-47
@@ -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);
|
||||
// // Don’t 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 wasn’t 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;
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user