An exception occurred when getting the rotation property of an object

An exception occurred when getting the rotation property of an object.

I’m using Ammo.js as the physics engine and creating a vehicle,. I’m trying to get the body rotation attributes around the y-axis and output them in the console.

I found that the output value is between-PI/2~PI/2, and the value of the rotation property decreases when the PI/2 is reached, and the value of the rotation property increases when the-PI/2 is reached.

To test, I created another mesh, and assigned a value to it using the rotation of vehicle’s body. The exception is shown in the following video:

Video_20201210115858.wmv (1.7 MB)

I’m not sure why this happened. I hope someone can help me.

Thanks!

I could not view your video on my phone, so I converted it.

1 Like

Can you share some of your code? I think I once had the same issue, but can’t reproduce it anymore :confused:

Here is my code:

let tmpTrans = new Ammo.btTransform();

let ms = carBody.getMotionState();
ms.getWorldTransform(tmpTrans);

let p = tmpTrans.getOrigin();
let q = tmpTrans.getRotation();

carMesh.position.set(p.x(), p.y(), p.z());
carMesh.quaternion.set(q.x(), q.y(), q.z(), q.w());

Then I created another mesh, and assigned a value to it using the rotation of vehicle’s body:

newMesh.rotation.y = carMesh.rotation.y;

And then there was the situation in the video.

I keep forgetting how it worked with .rotation - but it’s possible that when you cross 0 / Math.PI, rotation.y resets to once again fit that interval, and rotation.x / rotation.z change signs.

In general, use quaternions over rotations.

newMesh.quaternion.copy(carMesh.quaternion);
newMesh.quaternion.x = newMesh.quaternion.z = 0; // If you care only about y-axis

I don’t understand what you mean by this

cross 0 / Math.PI,

but I have tried the second method of using quaternions, and the result is still the same as in the video.

I assume you are using raycastVehicle?

You can do this:

animate() {  
  let quat = raycastVehicle.getRigidBody().getWorldTransform().getRotation()
  let rad = this.quaternionToRadian(quat)

  newMesh.rotation.y  = rad.y
}

quaternionToRadian(ammoQuat) {
  let x, y, z

  let q1 = new THREE.Quaternion(ammoQuat.x(), ammoQuat.y(), ammoQuat.z(), ammoQuat.w())
  if (q1.w > 1) q1 = q1.normalize()

  const angle = 2 * Math.acos(q1.w)
  const s = Math.sqrt(1 - q1.w * q1.w)

  if (s < 0.001) {
    x = q1.x
    y = q1.y
    z = q1.z
  } else {
    x = q1.x / s
    y = q1.y / s
    z = q1.z / s
  }
  return { x: x * angle, y: y * angle, z: z * angle }
}