Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

How to build mesh position Matrix from COLLADA file?

  • You cannot reply to this topic
5 replies to this topic

#1 BlackJoker   Members   -  Reputation: 211

Like
0Likes
Like

Posted 16 March 2013 - 11:11 AM

Hello,

 

I write a converter from COLLADA to binary now and I faced with the problem:

I want to get mesh matrix from visual scenes to know how to set object in the world, but when I export mesh from 3ds max without triangulating than instead of matrix element I get only this:

<node name="Box001" id="Box001" sid="Box001">
	  <translate sid="translate">11.348564 0.000000 0.590027</translate>
	  <rotate sid="jointOrientX">1 0 0 -90.000000</rotate>
	  <instance_geometry url="#Box001-lib"/><extra><technique profile="FCOLLADA"><visibility>1.000000</visibility></technique></extra></node>

 

or this if I rotate this mesh before export:

 

<node name="Torus001" id="Torus001" sid="Torus001">
	  <translate sid="translate">5.463669 0.000000 -20.828049</translate>
	  <rotate sid="jointOrientX">1 0 0 -90.000000</rotate>
	  <rotate sid="rotateX">1 0 0 90.739616</rotate><instance_geometry url="#Torus001-lib"/><extra><technique profile="FCOLLADA"><visibility>1.000000</visibility></technique></extra></node>

Does some one know how to build from this values matrix 4*4 for DirectX?

And another question I ask, I think, in wrong thread - http://www.gamedev.net/topic/640322-issue-with-fbx-collada-exporter-in-3ds-max/#entry5043330

Who now answer for those questions, please help me with it. 



Sponsor:

#2 hossainiir   Members   -  Reputation: 422

Like
1Likes
Like

Posted 17 March 2013 - 12:48 AM

Hi,

try this : 

 

Matrix Trans = Matrix.Translation(5.463,0,-20);

Matrix RotX = Matrix.RotateX(DegreeToRadian(90.7396));

Matrix RotY = Matrix.RotateY(DegreeToRadian(0));

Matrix RotZ = Matrix.RotateZ(DegreeToRadian(0));

Matrix Scale = Matrix.Scaling(1,1,1);

 

TransformMatrix = Scale * RotX * RotY * RotZ * Trans;

 

This worked for me with XSI exporetd Collada.


Edited by hossainiir, 17 March 2013 - 12:48 AM.

DirectX for persians : http://mdirectx11.blogfa.com/

#3 Hodgman   Moderators   -  Reputation: 13599

Like
1Likes
Like

Posted 17 March 2013 - 01:03 AM

You just need to be able to parse the translate/rotate elements and build from them translation matrices and axis-angle rotation matrices, then multiply them all together in order. My parsing code for collada node transforms looks like:
            Matrix4 matrix = Matrix4.identity.Clone();
            XmlNodeList transforms = node.SelectNodes("c:rotate | c:translate | c:scale | c:skew | c:matrix | c:lookat", nsm);
            foreach (XmlNode transform in transforms)
            {
                string type = transform.Name;
                switch (type)
                {
                    case "rotate":
                        Vector4 rotation = Vector4.Parse(transform.InnerText);
                        matrix.MultiplyRotation(rotation);
                        break;
                    case "translate":
                        Vector4 translation = Vector4.Parse(transform.InnerText);
                        matrix.MultiplyTranslation(translation);
                        break;
                    case "scale":
                        Vector4 scaling = Vector4.Parse(transform.InnerText);
                        matrix.MultiplyScaling(scaling);
                        break;
                    case "matrix":
                        Matrix4 transformMatrix = Matrix4.ParseRowMajor(transform.InnerText);
                        matrix.MultiplyInPlace(transformMatrix);
                        break;
                    default:
                    case "skew":
                    case "lookat":
                        throw new ApplicationException(String.Format("The {0} transform type isn't implemented!", type));
                }
            }
            newNode.local = matrix;
            newNode.global = Matrix4.Multiply(global, newNode.local);


#4 BlackJoker   Members   -  Reputation: 211

Like
0Likes
Like

Posted 17 March 2013 - 04:23 AM

Thanks, I wiil try this after fix another issue in my engine which influence on the position of objects in the scene.



#5 BlackJoker   Members   -  Reputation: 211

Like
0Likes
Like

Posted 31 March 2013 - 05:19 AM

Hello to all again.

At last I implement taking out all rotations, translation and scaling. and do as said hossainiir, but It doesn`t work correctly.

 

If I use single matrix - scene load correctly, but if not - meshes displays not on their places as they was in 3d max originally.

 

On screen I use can see original 3s max scene in front.

 

on screen2 - scene after loading without single matrix

 

on screen3 displays the same scene WITH single matrix

 

on screen4 - you can see another one problem which I didn`t mention yet. When I begin rotation of mesh it loose its scaling and became exactly the same as it was before I use scaling in 3ds max and in addition it becomes very small. I actually export with millimeters, but I think that small size is not the real problem . Real problem is that mesh loose its form.

 

So, I have 2 problems.

 

Here is some code to show how I use matrices.

float x = 0;
float y = 0;
float z = 0;
file.read((char*)&x,sizeof(float));
file.read((char*)&y,sizeof(float));
file.read((char*)&z,sizeof(float));
XMMATRIX scale = XMMatrixScaling(x, y, z);

file.read((char*)&x,sizeof(float));
file.read((char*)&y,sizeof(float));
file.read((char*)&z,sizeof(float));

XMMATRIX rotationX = XMMatrixRotationX(x);
XMMATRIX rotationY = XMMatrixRotationY(y);
XMMATRIX rotationZ = XMMatrixRotationZ(z);

file.read((char*)&x,sizeof(float));
file.read((char*)&y,sizeof(float));
file.read((char*)&z,sizeof(float));

XMMATRIX translation = XMMatrixTranslation(x, y, z);
					
meshInfo->meshPosition = scale * rotationX * rotationY * rotationZ * translation;

After that I made the following to translate Y_UP 3s max right hand coordinate system to Y_UP left hand coordinate system in DirectX

 

XMFLOAT4X4 cm;
	cm._11 = 1;
	cm._12 = 0;
	cm._13 = 0;
	cm._14 = 0;
	cm._21 = 0;
	cm._22 = 0;
	cm._23 = 1;
	cm._24 = 0;
	cm._31 = 0;
	cm._32 = 1;
	cm._33 = 0;
	cm._34 = 0;
	cm._41 = 0;
	cm._42 = 0;
	cm._43 = 0;
	cm._44 = 1;
	XMMATRIX axisZ_UPtoY_UP = XMLoadFloat4x4(&cm);


XMMATRIX scale = XMMatrixScaling(1.0f, 1.0f, -1.0f);
meshInfo->meshPosition = axisZ_UPtoY_UP*meshInfo->meshPosition;
meshInfo->meshPosition = meshInfo->meshPosition*scale;

and then I load geometry

 

for (int i = 0; i<meshesList[index]->vertexCount; i++)
{
vertices[i].position = XMFLOAT3(meshesList[index]->meshType[i].x, meshesList[index]->meshType[i].z, -meshesList[index]->meshType[i].y);
vertices[i].texture = XMFLOAT2(1-meshesList[index]->meshType[i].tu, 1-meshesList[index]->meshType[i].tv);
vertices[i].normal = XMFLOAT3(meshesList[index]->meshType[i].nx, meshesList[index]->meshType[i].nz, -meshesList[index]->meshType[i].ny);
}

Thats all. Could anyone tell me what I am doing wrong here?

 

Attached Thumbnails

  • screen.png
  • screen2.png
  • screen3.png
  • screen4.png


#6 BlackJoker   Members   -  Reputation: 211

Like
0Likes
Like

Posted 03 April 2013 - 10:48 AM

Update: I fix issue with positioning. I just forgot to convert values to radians, but issue with scaling is still present.

Update 2: issue 2 was also fixed.


Edited by BlackJoker, 04 April 2013 - 11:56 AM.






PARTNERS