EzDevInfo.com

gl-matrix

Javascript Matrix and Vector library for High Performance WebGL apps glMatrix

Quaternion rotation by phi and theta instead of xyz in gl-matrix

gl-matrix's quaternion object has 3 functions rotateX, rotateY and rotateZ which rotates quaternion by the specific axis. Now I want to do the same using phi and theta instead of xyz.

How is this possible ? Is it possible to extract some value then pass it to rotateX, rotateY and rotateZ ?


Source: (StackOverflow)

distance/magnitude between quaternions, but ignore roll

I'm searching for a way to determine if a camera (a) is looking at the same direction than a specific object (b).

I'm only working with the rotations because here we don't care about the positions (so we can consider both are located at the origin).

I'm working with quaternions, using gl-matrix.

After many searches and tests, I understood that I can determine the "distance" (magnitude ?) between the two quaternions using a dot product.

var a = quat.create();
quat.rotateY(a, a, Math.PI);

var b = quat.create();
quat.rotateY(b, b, Math.PI);

quat.dot(a, b)

That works well in many cases (it returns a number in range [0..1] : from 1 if both are exactly looking at the same direction to 0 if both are totally opposite).

However, in my case, I don't want to care about the "roll" between the objects. I mean that the camera (a) can be turned upside down, relatively to (b), but still looking at the same point.

For example, if I turn b by 180 degrees around Z, I get a dot product that is around 0, while it's still looking at the same direction.

var a = quat.create();
quat.rotateY(a, a, Math.PI);

var b = quat.create();
quat.rotateY(b, b, Math.PI);
quat.rotateZ(b, b, Math.PI);

quat.dot(a, b);

I tried many things, such as multiplying the inverse of a with b, or [s]lerp, but I still can't get anything that fits my requirements.

Of course, I can't simply separate and work with the absolute Z axis, because everything is all relative here, so the roll could be around any axis.

How can I get that result ?

EDIT : Thanks to LutzL answer, here's how I implemented the solution :

var r = quat.create();
quat.invert(r, a);
quat.multiply(r, r, b);

var distance = r[3]*r[3] - r[0]*r[0] - r[1]*r[1] + r[2]*r[2];

Source: (StackOverflow)

Advertisements

glMatrix quaternion rotation

Can anyone explain to me why this doesn't work as I would expect.

Using a quaternion to rotate a vec3 [5,0,0] 180degree/Math.PI radians around the z axis.

I would think the result would be [-5,0,0]; Rotating [5,5,0] gives [-5,-5,0] as expected.

http://jsfiddle.net/s4sqq5L4/

var q = quat.create();
quat.rotateZ(q, q, Math.PI);
console.log(q);

var v = vec3.fromValues(5, 0, 0);
vec3.transformQuat(v, v, q);
console.log(v);

/*
[0, 0, 1, 6.123234262925839e-17]
[-5, 6.123233998228043e-16, 0]
*/

var q2 = quat.create();
quat.rotateZ(q2, q2, Math.PI);
console.log(q2);

var v2 = vec3.fromValues(5, 5, 0);
vec3.transformQuat(v2, v2, q2);
console.log(v2);

/*
[0, 0, 1, 6.123234262925839e-17]
[-5, -5, 0]
*/

Source: (StackOverflow)

How do I calculate the final bone matrix in skeletal animation?

I'm having trouble finding the final bone matrices for my skeleton.

I know my bind pose matrices work, and I know my transform matrices work, but I figured multiplying them (which I'm calling the composite matrix) then multiplying them by its parents composite matrix (then by its parents parent, etc.) would get me the correct matrix.

Its worth noting I'm using gl-matrix.js as my vector / matrix math library, its matrix math works in reverse, getting a world matrix requires, PositionMatrix * RotationMatrix * ScaleMatrix, instead of the other way around. so I may be getting the orders mixed up,

I've tried changing the multiplication orders of the bind pose matrices and the bone transform matrices, as well as the order of final matrix and parent matrices, but I'm just mind boggled now.

Anyway to wrap this question up in a bow, Given a mesh where every vertex is pre-transformed to its relative bone(s) space, each bones bind pose matrix and each bones per frame transform matrix how would I find the final bone matrix?

EDIT:

still having issues but it may help to say where I am at the moment, the following psuedo code gets the model perfectly into its bind pose

finalBones = []
foreach bone in bones
    mat = bone.poseMatrix
    parent = bone
    while (parent.parent != null)
        parent = parent.parent
        mat *= parent.poseMatrix
    finalBones.push(mat)

the above snippest is exactly whats going on without needing to explain the matrix functions (its javascript so its done via functions like mat4.copy and mat4.mul)

I figured if I did something like

finalBones = []
foreach bone in bones
    mat = bone.poseMatrix
    mat *= bone.transformMatrix
    parent = bone
    while (parent.parent != null)
        parent = parent.parent
        mat *= parent.poseMatrix
        mat *= parent.transformMatrix
    finalBones.push(mat)

I would get the final matrix (and I have tried using the transformMatrices before the poseMatrices) but all I get is a model with a broken spine and inside out legs

EDIT 2:

so on further inspection, the bone transform matrices on an idle frame have the middle 2 rows inverted? odd, but I'm looking into what happens if I swap them back now


Source: (StackOverflow)

Normals rotates wrong way when object is rotated

I am rendering a simple torus in WebGL. Rotating the vertices works fine but I have a problem with the normals. When rotated around a single axis, they keep the correct direction but when the rotation around a second axis increases, the normals start rotating the wrong way up until one of the rotations are 180°, then the normals are rotating in the complete opposite of what they should. I assume the problem lies with the quaternion used for rotation, but I have not been able to determine what is wrong.

Here is a (slightly modified, but it still shows the problem) jsfiddle of my project: https://jsfiddle.net/dt509x8h/1/
In the html-part of the fiddle there is a div containing all the data from the obj-file I am reading to generate the torus (although a lower resolution one).

vertex shader:

attribute vec4 aVertexPosition;
attribute vec3 aNormalDirection;

uniform mat4 uMVPMatrix;
uniform mat3 uNMatrix;

varying vec3 nrm;

void main(void) {
    gl_Position = uMVPMatrix * aVertexPosition;
    nrm = aNormalDirection * uNMatrix;
}

fragment shader:

varying vec3 nrm;

void main(void) {
    gl_FragColor = vec4(nrm, 1.0);
}

Updating the matrices (run when there has been input):

mat4.perspective(pMatrix, Math.PI*0.25, width/height, clipNear, clipFar); //This is actually not run on input, it is just here to show the creation of the perspective matrix
mat4.fromRotationTranslation(mvMatrix, rotation, position);
mat3.normalFromMat4(nMatrix, mvMatrix);

mat4.multiply(mvpMatrix, pMatrix, mvMatrix);

var uMVPMatrix = gl.getUniformLocation(shaderProgram, "uMVPMatrix");
var uNMatrix = gl.getUniformLocation(shaderProgram, "uNMatrix");
gl.uniformMatrix4fv(uMVPMatrix, false, mvpMatrix);
gl.uniformMatrix3fv(uNMatrix, false, nMatrix);

Creating the rotation quaternion (called when mouse has moved):

var d = vec3.fromValues(lastmousex-mousex, mousey-lastmousey, 0.0);
var l = vec3.length(d);
vec3.normalize(d,d);
var axis = vec3.cross(vec3.create(), d, [0,0,1]);
vec3.normalize(axis, axis);

var q = quat.setAxisAngle(quat.create(), a, l*scale);
quat.multiply(rotation, q, rotation);

Rotating the torus only around the Y-axis, the normals point in the right directions:
Rotating the torus only around the Y-axis
Rotating the torus around two axes. The normals are pointing all over the place:
Rotating around two axes

I am using glMatrix v2.3.2 for all matrix and quaternion operations.

Update: It seems that rotating only around the Z axis (by setting the input axis for quat.setAxisAngle explicitly to [0,0,1], or by using quat.rotateZ) also causes the normals to rotate in the opposite direction.
Zeroing the z-component of the axis does not help.

Update2: Rotating by quat.rotateX(q, q, l*scale); quat.rotateY(q, q, l*scale); quat.multiply(rotation, q, rotation); Seems correct, but as soon as rotation around Z is introduced the z normals starts to move around.
Using the difference in x or y mouse-values instead of l causes all normals to move, and so does using largely different scale-values for x and y.

Update3: changing the order of multiplication in the shader to uNMatrix * aNormalDirection causes the normals to always rotate the wrong way.


Source: (StackOverflow)