The below function is for the purpose of updating player’s position
UpdatePosition(deltaTime: number) {
if (!this._player) {
return;
}
const velocity = this._velocity;
const frameDecceleration = new Vector3(
//multiply decceleration ratio by velocity component in each axes
velocity.x * this._decceleration.x,
velocity.y * this._decceleration.y,
velocity.z * this._decceleration.z
);
console.log(frameDecceleration.z * deltaTime);
console.log(this._velocity);
frameDecceleration.scaleInPlace(deltaTime).multiplyInPlace;
frameDecceleration.z =
Math.sign(frameDecceleration.z) *
Math.min(Math.abs(frameDecceleration.z), Math.abs(velocity.z));
velocity.addInPlace(frameDecceleration);
const player = this._player.Mesh;
const quat = new Quaternion();
const axis = new Vector3();
const acc = this._acceleration.clone();
const rot = player.rotationQuaternion.clone();
//product deltaTime to move character according to device frame rate
if (this._inputSystem.inputs.w) {
let dynamicAcc = acc.z;
velocity.z += dynamicAcc * deltaTime;
}
if (this._inputSystem.inputs.s) {
velocity.z -= acc.z * deltaTime;
}
if (this._inputSystem.inputs.a) {
axis.set(0, 1, 0); // rotation based on Y-axis(normalized vector)
Quaternion.RotationAxis(
axis,
4.0 * Math.PI * deltaTime * this._acceleration.y
);
rot.multiplyInPlace(quat);
}
if (this._inputSystem.inputs.d) {
axis.set(0, 1, 0);
Quaternion.RotationAxis(
axis,
4.0 * -Math.PI * deltaTime * this._acceleration.y
);
rot.multiplyInPlace(quat);
}
player.rotationQuaternion = rot;
const forward = new Vector3(0, 0, 1);
forward.applyRotationQuaternionInPlace(player.rotationQuaternion);
forward.normalize();
const sideways = new Vector3(1, 0, 0);
sideways.applyRotationQuaternionInPlace(player.rotationQuaternion);
sideways.normalize();
sideways.scaleInPlace(velocity.x * deltaTime);
forward.scaleInPlace(velocity.z * deltaTime);
player.position.add(forward);
player.position.add(sideways);
}
I’m experiencing non-deterministic situation right now.
When i logged a lot in the update function, Sometimes there is no problem in vector calculations.
But mostly, this.velocity and other vectors have ‘NaN’ elements in every loop.
This logic worked in Three.js , but the problem occured during migrating the code into babylon.js
Here are three.js code
public Update(deltaTime: number) {
if (!this.parent) {
return;
}
const velocity = this.velocity;
const frameDecceleration = new Vector3(
//multiply decceleration ratio by velocity component in each axes
velocity.x * this.decceleration.x,
velocity.y * this.decceleration.y,
velocity.z * this.decceleration.z
);
frameDecceleration.multiplyScalar(deltaTime);
frameDecceleration.z =
Math.sign(frameDecceleration.z) *
Math.min(Math.abs(frameDecceleration.z), Math.abs(velocity.z));
velocity.add(frameDecceleration);
const player = this.parent.Mesh;
const quat = new Quaternion();
const axis = new Vector3();
const acc = this.acceleration.clone();
const rot = player.quaternion.clone();
//product deltaTime to move character according to device frame rate
if (this.input.keys.Forward) {
let dynamicAcc = acc.z;
if (this.input.keys.Shift) {
dynamicAcc = acc.z * 2;
}
velocity.z += dynamicAcc * deltaTime;
this.isPosUpdated = true;
}
if (this.input.keys.Backward) {
velocity.z -= acc.z * deltaTime;
this.isPosUpdated = true;
}
if (this.input.keys.Left) {
axis.set(0, 1, 0); // rotation based on Y-axis(normalized vector)
quat.setFromAxisAngle(
axis,
4.0 * Math.PI * deltaTime * this.acceleration.y
);
rot.multiply(quat);
this.isRotUpdated = true;
}
if (this.input.keys.Right) {
axis.set(0, 1, 0);
quat.setFromAxisAngle(
axis,
4.0 * -Math.PI * deltaTime * this.acceleration.y
);
rot.multiply(quat);
this.isRotUpdated = true;
}
player.quaternion.copy(rot);
const prevPosition = new Vector3();
prevPosition.copy(player.position);
const forward = new Vector3(0, 0, 1); // unit vector on axis-z
forward.applyQuaternion(player.quaternion);
forward.normalize();
const sideways = new Vector3(1, 0, 0);
sideways.applyQuaternion(player.quaternion);
sideways.normalize();
sideways.multiplyScalar(velocity.x * deltaTime);
forward.multiplyScalar(velocity.z * deltaTime);
player.position.add(forward);
player.position.add(sideways);
prevPosition.copy(player.position);
/**
* Update animation mixer
*/
if (this.parent.AnimMixer) {
this.parent.AnimMixer.update(deltaTime);
}
// Check whether character transform is updated
if (this.isPosUpdated || this.isRotUpdated) {
console.log("send request");
//if transform changed
this.channel.emit("transform update", {
id: this.userId,
pos: [prevPosition.x, prevPosition.y, prevPosition.z],
quat: [
player.quaternion.x,
player.quaternion.y,
player.quaternion.z,
player.quaternion.w,
],
state: this.stateMachine.currentState?.Name,
input: this.input.keys,
});
}
//intialize again
this.isPosUpdated = false;
this.isRotUpdated = false;
}