How to build mesh position Matrix from COLLADA file?

Started by
4 comments, last by BlackJoker 11 years ago

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.

Advertisement

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.

???? ?? ??? ????

Persian Gulf

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);

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

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.position = XMFLOAT3(meshesList[index]->meshType.x, meshesList[index]->meshType.z, -meshesList[index]->meshType.y);
vertices.texture = XMFLOAT2(1-meshesList[index]->meshType.tu, 1-meshesList[index]->meshType.tv);
vertices.normal = XMFLOAT3(meshesList[index]->meshType.nx, meshesList[index]->meshType.nz, -meshesList[index]->meshType.ny);
}

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

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.

This topic is closed to new replies.

Advertisement