Please Help! Assimp->Babylon


#1

Hi,

I am trying to convert a .3ds file into babylon. I cannot use any third-party applications and use Babylon exporter. I need to do it programatically. I have implemented the code in C#. It is almost completed. The only part which is not working is: calculating scaling and rotationQuaternion.

I tried in two approaches (one from 3dsMax-to-Babylon-Exporter and other one from Maya-to-Babylon-Exporter) but none of them are working. Have been struggling for a week but no luck. Please help me.

Thanks in advance.

//Approach 1:
private static void PopulateTransformations(BabylonNode babylonNode, Assimp.Node node)
        {
            Matrix4x4 transformMatrix = node.Transform;
            BabylonMatrix tm_babylon = MapMatrix4x4ToBabylonMatrix(transformMatrix);

            var s_babylon = new BabylonVector3();
            var q_babylon = new BabylonQuaternion();
            var t_babylon = new BabylonVector3();

            tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

            if (ExportQuaternionsInsteadOfEulers)//It is true in my case
            {
                // normalize quaternion
                var q = q_babylon;
                float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W);
                babylonNode.rotationQuaternion = new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length };
            }
            else
            {
                babylonNode.rotation = q_babylon.toEulerAngles().ToArray();
            }
            babylonNode.rotation = q_babylon.toEulerAngles().ToArray();
            babylonNode.scaling = new[] { s_babylon.X, s_babylon.Y, s_babylon.Z };
            babylonNode.position = new[] { t_babylon.X, t_babylon.Y, t_babylon.Z };
        }
        public static BabylonMatrix MapMatrix4x4ToBabylonMatrix(Matrix4x4 matrix)
        {
            var babylonMatrix = new BabylonMatrix();
            babylonMatrix.m = new float[]
            {
                matrix.A1,
                matrix.A2,
                matrix.A3,
                matrix.A4,
                matrix.B1,
                matrix.B2,
                matrix.B3,
                matrix.B4,
                matrix.C1,
                matrix.C2,
                matrix.C3,
                matrix.C4,
                matrix.D1,
                matrix.D2,
                matrix.D3,
                matrix.D4
            };

            return babylonMatrix;
        }

Approach 2:


        private static void PopulateTransformations(BabylonNode babylonNode, Assimp.Node node)
        {
            Matrix4x4 transformMatrix = node.Transform;

            Vector3D scaling;
            Quaternion quaternion;
            Vector3D translation;
            transformMatrix.Decompose(out scaling, out quaternion, out translation);
            babylonNode.scaling = new[] { scaling.X, scaling.Y, scaling.Z };
            babylonNode.rotationQuaternion = new[] { quaternion.X, quaternion.Z, quaternion.Y, quaternion.W };

            babylonNode.position = new float[] { node.Transform.A4, transformMatrix.C4, transformMatrix.B4 };
        }

#2

Solved it with Approach 1. but with this Matrix mapping

 public static BabylonMatrix MapMatrix4x4ToBabylonMatrix(Matrix4x4 matrix)
        {
            var babylonMatrix = new BabylonMatrix();
            babylonMatrix.m = new float[] 
            {
                matrix.A1,
                matrix.C1,
                matrix.B1,
                matrix.D1,

                matrix.A3,
                matrix.C3,
                matrix.B3,
                matrix.D3,

                matrix.A2,
                matrix.C2,
                matrix.B2,
                matrix.D2,

                matrix.A4,
                matrix.C4,
                matrix.B4,
                matrix.D4
            };

            return babylonMatrix;
        }

Thank you all


#3

Hi all,
I could successfully write an exporter which exports from Assumption.Scene to BabylonScene. (I am using BabylonExport.Entities library for entities). The advantage is, as Assimp supports conversion of 70+ formats, existing files with those formats can now be exported to Babylon.

Thanks a lot again for your continuous support.

Now, I am stuck with vice-versa approach.

For Assimp to Babylon, I followed Approach 1: that is:

Matrix4x4 transformMatrix = node.Transform;
BabylonMatrix tm_babylon = MapMatrix4x4ToBabylonMatrix(transformMatrix);

var s_babylon = new BabylonVector3();
var q_babylon = new BabylonQuaternion();
var t_babylon = new BabylonVector3();

tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

var q = q_babylon;
float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W);
babylonNode.rotationQuaternion = new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length };
            
babylonNode.rotation = q_babylon.toEulerAngles().ToArray();
babylonNode.scaling = new[] { s_babylon.X, s_babylon.Y, s_babylon.Z };
babylonNode.position = new[] { t_babylon.X, t_babylon.Y, t_babylon.Z };

Now, to convert from Babylon to Assimp, I need to reverse these steps. I am stuck here. I have written a method to construct the matrix back. But after that, there is a problem. In the above code, the q_length is computed from S/R/T values and the S/R/T are updated with the q_length value.

The deadlock situation is: To know the original S/R/T values, we need to know the original q_length used. To know the original q_length, we need to know the original S/R/T values.

Please help me. All the work I have done is going into drain. Please help.

public static Matrix MapBabylonMatrixToMatrix(BabylonVector3 scale, BabylonQuaternion rotation, BabylonVector3 translation)
        {
            BabylonMatrix babylonMatrix = BabylonMatrix.Compose(scale, rotation, translation);
            var m = babylonMatrix.m;
            return new Matrix(

                m[0],
                m[8],
                m[4],
                m[12],

                m[2],
                m[10],
                m[6],
                m[14],

                m[1],
                m[9],
                m[5],
                m[13],

                m[3],
                m[11],
                m[7],
                m[15]
            );
        }

#4

I may not understand correctly but you need a matrix right? so bjs can give you the worldMatrix and you can then give that matrix to assimp? (perhaps you may need to transpose it depending on their convention)