# How to build mesh position Matrix from COLLADA file?

## Recommended Posts

BlackJoker    1328

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>


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?

##### Share on other sites
hossainiir    1044

Hi,

try this :

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

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

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

This worked for me with XSI exporetd Collada.

Edited by hossainiir

##### Share on other sites
Hodgman    51227
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);


##### Share on other sites
BlackJoker    1328

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

##### Share on other sites
BlackJoker    1328

Hello to all again.

At last I implement taking out all rotations, translation and scaling. and do as said hossainiir, but It doesnt 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 screen3 displays the same scene WITH single matrix

on screen4 - you can see another one problem which I didnt 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;
XMMATRIX scale = XMMatrixScaling(x, y, z);

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

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 scale = XMMatrixScaling(1.0f, 1.0f, -1.0f);
meshInfo->meshPosition = axisZ_UPtoY_UP*meshInfo->meshPosition;
meshInfo->meshPosition = meshInfo->meshPosition*scale;


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?

##### Share on other sites
BlackJoker    1328

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