Sunday May 19, 2024
 home | contact | Support | 3D File Formats The bits and bytes...

Prt-2- .x File Format

Well its one thing to create a simple mesh....its just an array of x, y and z coordinates....

Bones!  Now thats an advanced topic we'd like to know more about....so hold on to your hat where going in...

Bones....bones....bones....its not as tough as it sounds....you have a body...which has an arm connected to it...you move the body, and the arm moves with it....just keep that simple image in your head :)  Bones in the .x file format use the 'Frame' template

Now you'll need a lot of coffee and patience to grasp frame's...and bones... as its a tricky one

Lets have a look at the formal definition:

Frame Aframe {        // The frame name is chosen for convenience.
FrameTransformMatrix {
...transform data...
}
[ Meshes ] and/or [ More frames]
}

Dear god...its looks horrible....if like me your looking at that definition above crying...don't worry....stay carm...its not that bad....it will all become clear in time :)

What we'll do is create 2 mesh's....two cubes and call them cubeA and cubeB....and we'll make cubeA the body and cubeB a sort of arm..if you can picture that...

[NOTE]

We can embed our mesh's...our cubes in this case inside the 'Frame' or bones if you want to call it them....or you can use references...where you declare your Mesh earlier...then inside the Frame just use a reference like {CubeA} and it refers to cubeA

Frame CubeFrame {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}
{CubeA}        // You could have the mesh inline, but this

}

Now if you look above, you'll see that the FrameTranformMatrix is a identity matrix...has 1's going across it...from  top left to bottom right.....anything applied to an identity matrix stays the same....so if we multipy all of our Mesh CubeA values by an identity matrix it does nothing...but on the other hand, we could put another matrix in there and have it scale or move our CubeA...so keep that in mind.

[NOTE]

Now I've discovered that a number of .x file loaders and viewers have a problem using the reference method...and always export inline...  So if possible always use the inline method....so if possible put your Mesh's inline

For those who are keen on exploring and learning the various 3D file formats, and excellent applications is 3D Exploration, which can be downloaded as shareware, and allows you to view nearly all 3D file formats....a definite must on your journey of adventure.

Nested Frames....this is where we use our Frame's as bones...and actually achieve something new and exciting

Frame CubeFrameA {

FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}

Frame CubeFrameB{

FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}

{CubeB}

}

{CubeA}

}

Now if we move CubeA, CubeB should follow...but if we only move CubeB then CubeA won't follow.......notice that CubeFrameB is inside CubeFrameA...this means its a child...

Its also tricky to picture in your head ...especially when your new to matrix's and things...but the Matrix used on A has to be used on B as well...think of it as a waterfall effect....the water trickles down the stream...never goes up the stream ;)

I'll show you the whole thing...the whole piece of code....lets call it bonecube.x

 xof 0303txt 0032   Header {  1;  0;  1; }   // use comments to seperate out the parts-------------   Mesh CubeA { 8;                                // 8 vertices 1.000000;1.000000;-1.000000;,     // vertex 0 -1.000000;1.000000;-1.000000;,    // vertex 1 -1.000000;1.000000;1.000000;,     // etc... 1.000000;1.000000;1.000000;, 1.000000;-1.000000;-1.000000;, -1.000000;-1.000000;-1.000000;, -1.000000;-1.000000;1.000000;, 1.000000;-1.000000;1.000000;;   12;                      // 12 faces 3;0,1,2;,                // face 0 has 3 vertices 3;0,2,3;,                // etc... 3;0,4,5;, 3;0,5,1;, 3;1,5,6;, 3;1,6,2;, 3;2,6,7;, 3;2,7,3;, 3;3,7,4;, 3;3,4,0;, 3;4,7,6;, 3;4,6,5;;                }   //-----------------------------------------------------   Mesh CubeB { 8;                                // 8 vertices 1.000000;1.000000;-1.000000;,     // vertex 0 -1.000000;1.000000;-1.000000;,    // vertex 1 -1.000000;1.000000;1.000000;,     // etc... 1.000000;1.000000;1.000000;, 1.000000;-1.000000;-1.000000;, -1.000000;-1.000000;-1.000000;, -1.000000;-1.000000;1.000000;, 1.000000;-1.000000;1.000000;;   12;                      // 12 faces 3;0,1,2;,                // face 0 has 3 vertices 3;0,2,3;,                // etc... 3;0,4,5;, 3;0,5,1;, 3;1,5,6;, 3;1,6,2;, 3;2,6,7;, 3;2,7,3;, 3;3,7,4;, 3;3,4,0;, 3;4,7,6;, 3;4,6,5;; }   //Bone structure stuff is here------------------------   Frame CubeFrameA { FrameTransformMatrix { 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;; }     Frame CubeFrameB{     FrameTransformMatrix {     1.000000, 0.000000, 0.000000, 0.000000,     0.000000, 1.000000, 0.000000, 0.000000,     0.000000, 0.000000, 1.000000, 0.000000,     0.000000, 0.000000, 0.000000, 1.000000;;     }     {CubeB}     } {CubeA} }

Or if you use inline....so you put the mesh's inside the frame....it would look like this:

 xof 0303txt 0032   Header {  1;  0;  1; }     Frame CubeFrameA { FrameTransformMatrix { 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;; }     Frame CubeFrameB{     FrameTransformMatrix {     1.000000, 0.000000, 0.000000, 0.000000,     0.000000, 1.000000, 0.000000, 0.000000,     0.000000, 0.000000, 1.000000, 0.000000,     0.000000, 0.000000, 0.000000, 1.000000;;     }     Mesh CubeB {     8;                                // 8 vertices     1.000000;1.000000;-1.000000;,     // vertex 0     -1.000000;1.000000;-1.000000;,    // vertex 1     -1.000000;1.000000;1.000000;,     // etc...      1.000000;1.000000;1.000000;,      1.000000;-1.000000;-1.000000;,     -1.000000;-1.000000;-1.000000;,     -1.000000;-1.000000;1.000000;,     1.000000;-1.000000;1.000000;;       12;                      // 12 faces     3;0,1,2;,                // face 0 has 3 vertices     3;0,2,3;,                // etc...     3;0,4,5;,     3;0,5,1;,     3;1,5,6;,     3;1,6,2;,     3;2,6,7;,     3;2,7,3;,     3;3,7,4;,     3;3,4,0;,     3;4,7,6;,     3;4,6,5;;     }     }   Mesh CubeA { 8;                                // 8 vertices 1.000000;1.000000;-1.000000;,     // vertex 0 -1.000000;1.000000;-1.000000;,    // vertex 1 -1.000000;1.000000;1.000000;,     // etc... 1.000000;1.000000;1.000000;, 1.000000;-1.000000;-1.000000;, -1.000000;-1.000000;-1.000000;, -1.000000;-1.000000;1.000000;, 1.000000;-1.000000;1.000000;;   12;                      // 12 faces 3;0,1,2;,                // face 0 has 3 vertices 3;0,2,3;,                // etc... 3;0,4,5;, 3;0,5,1;, 3;1,5,6;, 3;1,6,2;, 3;2,6,7;, 3;2,7,3;, 3;3,7,4;, 3;3,4,0;, 3;4,7,6;, 3;4,6,5;;                } }

Well it may seem like a lot of work at first...but its truly not until you start applying it to some small time projects that you'll drewl with amazment..... for example you could have two parts .....lets say a tank...body and a gun...and you could rotate the tank and the gun would rotate as well...but then you could rotate the gun on its own......