Vector operation issue

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;
  }

reproducing that in any way (preferably on the playground) will be a wonderful way of getting to the bottom of this.

Looking at the code, I can only tell you that multiplyInPlace is a function, so I am not sure what you are trying to achieve with this:

frameDecceleration.scaleInPlace(deltaTime).multiplyInPlace;

And that it is possible that the player’s rotationQuaternion is null (which might explain the NaN). It really depends on when it is being generated.

For a deeper dive - show us the code running. Thanks!

As @RaananW said, it could be that you are calculating the value of null or undefined, or specifically multiplying a string value. Please check.
you also need to check for verify that the Eulerian and Quaternionic conversions are correct and that there are no misses in the call.

1 Like