   Problem with transformations?
  Hi there.And my apologies in advance, should this have landed on wrong area.And despite the very DirectX heavy content, the issue does not lie with the particular api.Hi!I am currently working on a modest "2d in 3d" game scheme.Or rather I was, until I hit into some interesting issues...I wrote a simple tool with java to create "paperdoll"-like characters, who consist of a hierarchy ofquads( built from two triangles ).Curiously enough, my Matrix / vector / transformation scheme works flawlessly in my modeling tool. ( Utilizing java.awt and drawLine() mainly ), as the hell itself breaks loose when I began setting up a similar system under DirectX.I initially rolled my own Matrix/Vector classes just for the sake of exercise, but with little results, I switched to D3DX datastructures to eliminate any errors on my own structs.Everything that needs to be done at the moment is to translate and rotate the quads in relation to one another in a software method, and store the results in vertex buffer for later rendering.void Process( D3DXMATRIX &parent)// A recursive method that traverses the whole hierarchy depth first.{D3DXMATRIX trans;// This contains the objects relative transformation from parent.D3DXMATRIX   rot;// This contains the objects relative rotation from parent.D3DXMATRIX combi;D3DXMatrixTranslation( &trans, pos.x, pos.y, pos.z ); // Build the first matrix.D3DXMatrixRotationZ( &rot, relativeRot );// Build the second matrix.D3DXMatrixMultiply( &combi, &trans, &rot );// Multiply transformation by rotation to create combined matrix.D3DXMatrixMultiply( &combi, &combi, &parent );// combine with parents transformation.  Matrix *m = (Matrix*)&combi;// Convert into my own matrix format ( This works ok. As world, view and projection matrices are converted in a similar fashion.dataIn( &vertices[0], *m );if( child )child->Process( combi );if( sibling) sibling->Process( parent );}And this is the function I use to transform the vertices from object to world space.I know that you need 1x4 vertex to multiply with 4x4 matrix, but the thing gets even more insane with the additional fourth row division.( x,y,z / w )Oh, and the reason Im not using the hardware to do the transformations here, is the fact that Im planning on rendering the environment and transforming the "actors" in parallel with two threads, so that "actors" can be rendered away with 1 drawing call / set of quads bound to texture object. So, this bizarre setup is intentional.void dataIn( eVertexPT *vPtr, Matrix &mtx ){for(int i = 0; i < 4; i++) // Quad has 4 vertices.{eVertexPT temp;    // This is a silly placement...  temp.x = vPtr->x;  temp.y = vPtr->y;  temp.z = vPtr->z;    eVertexPT *ptr = &bPtr[ bIndex ];// ptr to the next output vertexptr->x   = ( mtx.m11 * temp.x ) + (mtx.m12 * temp.y) + (mtx.m13 * temp.z) + mtx.m41;  // Transform Xptr->y   = ( mtx.m21 * temp.x ) + (mtx.m22 * temp.y) + (mtx.m23 * temp.z) + mtx.m42;// Transform Yptr->z   = ( mtx.m31 * temp.x ) + (mtx.m32 * temp.y) + (mtx.m33 * temp.z) + mtx.m43;// Transform Zptr->u1  = vPtr->u1;ptr->v1  = vPtr->v1;bIndex++;// Next Ouputvertex....vPtr++;// Next inputVertex...}}Oh, and I do have tried the desperate "permutation game" with the matrix multiplication....And it just feels annoying as all heck to see object A rotation in clockwise fashion, followed by object B rotation in a same way, but having its origin rotating in a counter clockwise way around the first origin.So everything else seems to be going well. View/world/proj matrices and fine, stuff renders well, just the transformation combinations seem to provide wildly different results than in my java applciation. ( Although initially it was a DIRECT port from it! :/)Here is the method from java sidepublic void Process( Matrix pM ){Matrix myTrans = new Matrix();    myTrans.Transformation(relativePos.x, relativePos.y); Matrix myRot   = new Matrix();    myRot.RotationZ( relativeRot );  Matrix myMatrix = Matrix.MatrixMultiply( myTrans , myRot );   Matrix cMatrix   = Matrix.MatrixMultiply( myMatrix, pM    );   r.Draw( cMatrix.Transform(v[0]),   // Just encapsulation for   cMatrix.Transform(v[1]),   // DrawLine 0,1  1,2, 2,3, 3,0.   cMatrix.Transform(v[2]),    cMatrix.Transform(v[3]));if( child != null )child.Process( cMatrix );if( sibling != null)sibling.Process( pM );}And the Matrix class from java sidepackage datastruct;import datastruct.Vertex;    public class Matrix {public float m11, m12, m13, m14;public float m21, m22, m23, m24;public float m31, m32, m33, m34;public float m41, m42, m43, m44;public Matrix(){m11 = 1;m22 = 1;m33 = 1;m44 = 1;}public void Transformation( float x, float y){m41 = x;m42 = y;}public void RotationZ( float r){m11 = (float)Math.cos( r );m12 = (float)Math.sin( r );    m21 = -(float)Math.sin( r );m22 = (float)Math.cos( r );}public void Scale( float s ){m11 *= s;m22 *= s;m33 *= s;}public Vertex Transform( Vertex v ) {Vertex nV = new Vertex(0,0,0);float nX = v.x*m11 + v.y*m21 + v.z*m31 + 1*m41;float nY = v.x*m12 + v.y*m22 + v.z*m32 + 1*m42;float nZ = v.x*m13 + v.y*m23 + v.z*m33 + 1*m43;nV.x = nX;nV.y = nY;nV.z = nZ;return nV;}public static Matrix MatrixMultiply( Matrix a, Matrix b ){Matrix result = new Matrix();result.m11 = a.m11*b.m11 + a.m12*b.m21 + a.m13*b.m31 + a.m14*b.m41;result.m12 = a.m11*b.m12 + a.m12*b.m22 + a.m13*b.m32 + a.m14*b.m42;result.m13 = a.m11*b.m13 + a.m12*b.m23 + a.m13*b.m33 + a.m14*b.m43;result.m14 = a.m11*b.m14 + a.m12*b.m24 + a.m13*b.m34 + a.m14*b.m44;result.m21 = a.m21*b.m11 + a.m22*b.m21 + a.m23*b.m31 + a.m24*b.m41;result.m22 = a.m21*b.m12 + a.m22*b.m22 + a.m23*b.m32 + a.m24*b.m42;result.m23 = a.m21*b.m13 + a.m22*b.m23 + a.m23*b.m33 + a.m24*b.m43;result.m24 = a.m21*b.m14 + a.m22*b.m24 + a.m23*b.m34 + a.m24*b.m44;result.m31 = a.m31*b.m11 + a.m32*b.m21 + a.m33*b.m31 + a.m34*b.m41;result.m32 = a.m31*b.m12 + a.m32*b.m22 + a.m33*b.m32 + a.m34*b.m42;result.m33 = a.m31*b.m13 + a.m32*b.m23 + a.m33*b.m33 + a.m34*b.m43;result.m34 = a.m31*b.m14 + a.m32*b.m24 + a.m33*b.m34 + a.m34*b.m44;result.m41 = a.m41*b.m11 + a.m42*b.m21 + a.m43*b.m31 + a.m44*b.m41;result.m42 = a.m41*b.m12 + a.m42*b.m22 + a.m43*b.m32 + a.m44*b.m42;result.m43 = a.m41*b.m13 + a.m42*b.m23 + a.m43*b.m33 + a.m44*b.m43;result.m44 = a.m41*b.m14 + a.m42*b.m24 + a.m43*b.m34 + a.m44*b.m44;return result;}}The java tool is essentially a 2D representation, but as far as I figured, tailing along 0 for Z-component cannot hurt.If anyone can spot a clear issue here, I would be grateful.And as image tells more than 2^32 words, here a screenie from the java-tool to illustrate what Im going for.http://img291.imageshack.us/img291/9927/keyframe.jpg[Edited by - rmed002 on May 19, 2010 4:16:43 PM]
  Okay now...I replaced this...eVertexPT temp;  temp.x = vPtr->x;  temp.y = vPtr->y;  temp.z = vPtr->z;eVertexPT *ptr   = &bPtr[ bIndex ];ptr->x   = ( mtx.m11 * temp.x ) + (mtx.m12 * temp.y) + (mtx.m13 * temp.z) + mtx.m41;  ptr->y   = ( mtx.m21 * temp.x ) + (mtx.m22 * temp.y) + (mtx.m23 * temp.z) + mtx.m42;ptr->z   = ( mtx.m31 * temp.x ) + (mtx.m32 * temp.y) + (mtx.m33 * temp.z) + mtx.m43;ptr->u1  = vPtr->u1;ptr->v1  = vPtr->v1;by thiseVertexPT *ptr = &bPtr[ bIndex ];  mtx.Transform_Vertex( temp );ptr->x   = temp.x;ptr->y   = temp.y;ptr->z   = temp.z;ptr->u1  = vPtr->u1;ptr->v1  = vPtr->v1;where the function contains this:float nX = v.x*m11 + v.y*m21 + v.z*m31 + 1*m41;float nY = v.x*m12 + v.y*m22 + v.z*m32 + 1*m42;float nZ = v.x*m13 + v.y*m23 + v.z*m33 + 1*m43;float w  = v.x*m14 + v.y*m24 + v.z*m34 + 1*m44;v.x = nX / w;v.y = nY / w;v.z = nZ / w;Which is the way its supposed to be anyway...But what is different this time?As far as I know, I have tried this change in the method several times...Oh well, I shall test whether the thing is actually correct.Hopefully this would be the last we hear of it. :/Yep.Problems have vanished as soon as they appeared.Thank-you for the potential interest. :P[Edited by - rmed002 on May 19, 2010 6:09:40 PM]