Nikola Lukic
Nikola Lukic

Reputation: 4246

Converting Cannojs 3D world vectors to model-view matrix

I use glmatrix 3.4.0 . With position i dont have any problem.

Event glmatrix last version have some support for QUAT i cant make correct way of converting from QUAT to AxisAngle or rotate mat4 ...

I know that glmatrix use radians and i have no problem to get any data from CANNONJS Quaternion. I also try every possible type of ratator convertion (quat to mat , axis angle to mat etc...).

Very strange effect : if i push cube with player physics body then rotation got fixed not in the moment but got fixed... also if i pushed more and more they stay fixed.

Any suggestion.

  mat4.identity(object.mvMatrix);
  this.mvPushMatrix(object.mvMatrix, this.mvMatrixStack);

  mat4.translate(object.mvMatrix, object.mvMatrix, object.position.worldLocation);

 
  // I use local.physics.currentBody.quaternion.toAxisAngle()[0] AXIS
  // local.physics.currentBody.quaternion.toAxisAngle()[1] ANGLE

   // case CLASSIC  - This is classic glmatrix rotate call.
   // This must work - Works but not perfect
   // Critical angle values are 90deg manifest 96deg
   // Also ~180deg
   // and  ~270deg
   var t = vec3.fromValues(object.rotation.axis.x,object.rotation.axis.z, object.rotation.axis.y);
    mat4.rotate(object.mvMatrix, object.mvMatrix, (object.rotation.angle), t);

    // case BAD: NOT WORKING 
    var QP =object.physics.currentBody.quaternion;
    var QUAT = quat.fromValues(QP.x, QP.y, QP.z, QP.w)
    mat4.fromQuat(object.mvMatrix, QUAT)


Next step i use override native CANNONJS func:

// test override 
CANNON.Quaternion.prototype.toAxisAngle = function(targetAxis){
  targetAxis = targetAxis || new CANNON.Vec3();
  if (this.w > 1) this.normalize(); 
  // if w>1 acos and sqrt will produce errors, this cant happen if quaternion is normalised

  var angle = 2 * Math.acos(this.w);
  var s = Math.sqrt(1-this.w*this.w); // assuming quaternion normalised then w is less than 1, so term always positive.
  if (s < 0.001) {
      // test to avoid divide by zero, s is always positive due to sqrt
      // if s close to zero then direction of axis not important
      // if it is important that axis is normalised then replace with x=1; y=z=0;
      // console.log('override works ....')
     
      // variant I
      // HOW TO KNOW THIS -> ??
      // This one for example fix my case of angle 90deg
      // but then 180deg have ~small defect ~30deg mistake
      targetAxis.x = 0;
      targetAxis.y = 0;
      targetAxis.z = 1;
   
      // This one fix 180 deg but ~90deg got mistake ....
      // variant II
      targetAxis.x = 1;
      targetAxis.y = 0;
      targetAxis.z = 0;
      // ... 

      // targetAxis.x = this.x;
      // targetAxis.y = this.y;
      // targetAxis.z = this.z;
  } else {
      targetAxis.x = this.x / s; // normalise axis
      targetAxis.y = this.y / s;
      targetAxis.z = this.z / s;
  }
  return [targetAxis,angle];
};

Project source

LIVE: SELECT FPSSHOOTER EXAMPLE ON LEFT BAR

Upvotes: 1

Views: 210

Answers (0)

Related Questions