   Parallel Transport Frame
  This is related to my "Bezier Curve Evaluation" Thread I posted a while ago, now I have more understanding ive decided to come back to it.I initially have a bezier curve that I need an object to follow and need to know which way is up, forward, side etc, i used the frenet frame but I had torsion effects so I had to move to the Parallel Transport Frame instead.Now the code below follows the curve corectly but the rotation isnt correct. Maybe its the way Im storing the previous frame or the order im doing things in.Heres what I havevoid draw(void){// NOTE: the tangent is calculated before this function is called and works fine// Calculate the axis angle rotation matrixVector rotation = crossProduct(oldTangent, newTangent);float angleOfRotation = atan2(rotation.magnitude(), dotProduct(oldTangent, newTangent));// Create the rotation matrix, puts matrix in rotationMatrix[]createRotationMatrix(angleOfRotation, rotation.x, rotation.y, rotation.z);// Multiply old frame by the new frame, puts the result in newMatrix[]multiplyMatrix(previousMatrix, rotationMatrix);// Update position of the new framenewMatrix[12] = newPosition.x;newMatrix[13] = newPosition.y;newMatrix[14] = newPosition.z;// Now Draw itglPushMatrix();  // Translate  glMultMatrixf(newMatrix);  // Draw the object  drawObject();glPopMatrix();// Store previous values for next passpreviousMatrix = newMatrix;oldTangent = newTangent;}Can anyone see what Im doing wrong?If there is any bits of code that needs further explanation ill post it here.Thx   
  Still having problems with this huh? Well, since I got you into the whole 'parallel transport frame' mess, I should try to help you fix it :-) The basic idea looks correct; maybe you could post createRotationMatrix() and multiplyMatrix() so I can take a look at them.   ;  I'm not sure how your data is stored, so this is just a shot in the dark...It looks like you're creating a rotation matrix from euler angles, then multiplying that matrix by the previous frame's matrix.  This is fine, but since the previous frame contained the previous rotations as well, you are accumulating rotations.Since you're overwriting the translation component directly every frame anyway, I'm not sure why you even have a need to multiply with the previous frame's matrix at all.Edit: Idled on a reply for too long, I guess... listen to jyk.  :);Quote:Original post by bpointIt looks like you're creating a rotation matrix from euler angles, then multiplying that matrix by the previous frame's matrix.  This is fine, but since the previous frame contained the previous rotations as well, you are accumulating rotations.It's an axis-angle rotation, not Euler angles (it kind of looks like the latter due to the 'x, y, z' arguments though).Quote:Since you're overwriting the translation component directly every frame anyway, I'm not sure why you even have a need to multiply with the previous frame's matrix at all.The PTF uses incremental rotations, so the multiplication is in fact correct.It looks like he's got the concept right, but as they say, the devil is in the details :)   ;  Ok heres my functions, again they are taken from a book and working examples so they should work fine.void createRotationMatrix(float angle, float x, float y, float z){float sinSave, cosSave, oneMinusCos;float xx, yy, zz, xy, yz, zx, xs, ys, zs;// If NULL vector passed in, this will blow up...if(x == 0.0f && y == 0.0f && z == 0.0f)return;sinSave = (float)sin(angle);cosSave = (float)cos(angle);oneMinusCos = 1.0f - cosSave;xx = x * x;yy = y * y;zz = z * z;xy = x * y;yz = y * z;zx = z * x;xs = x * sinSave;ys = y * sinSave;zs = z * sinSave;this->rotationMatrix[0] = (oneMinusCos * xx) + cosSave;this->rotationMatrix[4] = (oneMinusCos * xy) - zs;this->rotationMatrix[8] = (oneMinusCos * zx) + ys;this->rotationMatrix[12] = 0.0f;this->rotationMatrix[1] = (oneMinusCos * xy) + zs;this->rotationMatrix[5] = (oneMinusCos * yy) + cosSave;this->rotationMatrix[9] = (oneMinusCos * yz) - xs;this->rotationMatrix[13] = 0.0f;this->rotationMatrix[2] = (oneMinusCos * zx) - ys;this->rotationMatrix[6] = (oneMinusCos * yz) + xs;this->rotationMatrix[10] = (oneMinusCos * zz) + cosSave;this->rotationMatrix[14] = 0.0f;this->rotationMatrix[3] = 0.0f;this->rotationMatrix[7] = 0.0f;this->rotationMatrix[11] = 0.0f;this->rotationMatrix[15] = 1.0f;}void multiplyMatrix(Matrix m1, Matrix m2){newMatrix[0]= m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];newMatrix[4]= m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];newMatrix[8]= m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];newMatrix[12]    = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];newMatrix[1]= m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];newMatrix[5]= m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];newMatrix[9]= m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];newMatrix[13]    = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];newMatrix[2]= m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];newMatrix[6]= m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];newMatrix[10]    = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];newMatrix[14]    = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];newMatrix[3]= m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];newMatrix[7]= m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];newMatrix[11]    = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];newMatrix[15]    = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];} [Edited by - dawberj3 on April 20, 2006 12:19:30 PM];  I would next try changing:multiplyMatrix(previousMatrix, rotationMatrix);To:multiplyMatrix(rotationMatrix, previousMatrix);It would also be a good idea to orthogonalize the rotation matrix at the end of each update (if your object is orienting more or less correctly but is slowly becoming stretched or distorted, this is probably the problem).   ;  ive tried that and the same happens. :(The rotations are no where near close, they are either too small to notice or just wrong, (rotations are happening but in the wrong direction and very small)This is annoying coz im following evryones instructions but they just dont work!!! grrrWhat else could make it fail?Thx   ;  Oop, one more thing: you're not normalizing the axis of rotation. You need to do it after you compute the angle, but before you construct the rotation matrix.   ;  WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!That seemed to do the trick! Just a few little details that need tidying up to make it perfect.but before I get too excited it has produced a problem that is probably easily fixable, when the object is moving around the curve, then I move the camera, the object vanishes! Any ideas?Also can you explain how to orthonormalise the frame? I cant find anything that is useful on the net.Thx Alot   