Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

o3d format

Junior Spellweaver
Joined
Jun 15, 2009
Messages
107
Reaction score
37
So i was staring and trying for a while now and this is what i could come up with. Seems like it parses and loads pretty much all o3d files, but i still don't understand how it's animated.

Credits to Fatduck and Pipelli.

Code:
struct vector
{
    float x,y,z;
};

struct quaternion
{
    float a,b,c,d;
};

struct tAnimationState
{
    quaternion rotateData;       //rotation applied first
    vector translateData;        //translation applied second
};

template<bool hasbones>
struct loddata
{
    int xcount;
    int vtcount;
    int fccount;
    int fcsize;

    vector xdata[ xcount ];

    struct tvertex
    {
        vector pos;       //translate this with translation matrix
        if( hasbones )
        {
            float weight1;
            float weight2;
            short bone1;
            short bone2;
        }
        vector normal;
        float u,v;
    
    }vertexes[ vtcount ];

    struct tface
    {
        short a, b, c;                  //indexes to vertex array
    }faces [ fccount ];

    short unk1[ vtcount ]; 

    int nUnk2;
    int unk2[ nUnk2 ];

    int unk3;
    int matcount;
    
    struct tMaterial
    {
        float lightAmbient[4];          //alpha is 0! has to be set to 1 explicitly
        float lightDiffuse[4];
        float lightSpecular[4];
        int unk5[ 5 ];
        int namelen;
        char textureName [ namelen ];
    };

    tMaterial materials [ max(1, matcount) ];   //at least one

    int matidcount;

    struct tMatid           //accociates materials to the faces
    {
        int startindex;     //index to face array. (it's a raw index, so if you loaded structs, divide by 3!, this indexes the floats)
        int count;          //number of sequential faces to apply the material to (don't divide by 3, if you loaded structs. oh joy, this indexes the faces)
        int matid;          //index to materials
        int unk1 [ 31 ];
    } matids[ matidcount ];
};

//-------------------------------------------------------------------------------------------
// Beginning of file
//-------------------------------------------------------------------------------------------

byte strlen1;
char filename[strlen1];                     //xor 0xCD

int version;                                //0x14, 0x15 or 0x16

unsigned int unk20;        			//checksum maybe?

vector element1Startpoint;
vector element1Endpoint;
if(version == 0x16)
{
    vector element2Startpoint;
    vector element2Endpoint;
}
int unk2_1;
int unk2_2;
char unk2[ 16 ];                        //filename?

float xmin;                             //bounding box
float ymin;
float zmin;
float xmax;
float ymax;
float zmax;
float 0.5;                              //allways 0.5

int nAnimationStates;                   //number of animation states
int nUnk3;
vector data[ nUnk3 ];

//--Not visible lods, defineing the walkable areas-----------------------------------------------

int lod1count;
if(lod1count > 0)
{
    struct tLod1
    {
        float transformationMatrix[ 16 ];    //only used if not null
        loddata<false> data;
    }lod1s[ lod1count ];                           //usually have no texture specified, sometimes texture name is garbage
}                                                    //but even if its valid, it shouldn't be displayed. Its a bounding box thingie, sepcifieing the 
                                                    //areas of the model wich cannot be walked through

int unk6;

//--Bone section-------------------------------------------------------------------------------
int nBones;

struct tbonedata1
{
    float trans1[ 16 ];
    float trans2[ 16 ];
}bonedata1[ nBones ];

struct tbonedata2
{
    int namelen;
    char bonename[ namelen ];           //bone name. usually "Bone1", "Bone2", etc
    float trans1[ 16 ];
    float trans2[ 16 ];
    int some_index;                     //starts with -1, less than nBones
}bonedata2[ nBones ];

if(nBones > 0)  //this is important
{

    int nUnk3;      						//something animation maybe?

    for(int j = 0; j < nUnk3; )
    {
        int unk5;   						//0 or 1 allways
        if( unk5 != 0 )
        {
            tAnimationState globalAnimStates[ nAnimationStates ];

            j += nAnimationStates;  //increase counter here only
        }else
        {
            //this branch (unk5 == 0) does NOT increase the counter
            struct tbonedata16
            {
                float trans[ 16 ];
            }bonedata16;
        }
    }

    int unk6;       //0 or 1 allways
    if(unk6 == 0)
    {
        struct tbonedata17
        {
            float trans[ 16 ];
            int unk7;
        }bonedata17;
    }

}

//--lods section-------------------------------------------------------------------------------

//struct for visible lods
struct tLod2
{
    int flags;		       //some flags: hasbones = 1, allways_transparent = 0x80000000


    int uknCount3;             //indexes to external bone file?
    int unk7[ uknCount3 ];

    int lodIndex;                  //lodIndex = n for the nth lod

    int lodlink;               //index of lod wich modelview matrix should be loaded before animate/view the current lod (not to confuse with the translation matrix)
    if(lodlink != -1)
    {
        if((lodlink == 0) && ((flags & 1) != 0))    //now im not sure about this
        {
            tAnimationState localAnimationStates1[ nAnimationStates ];
        }
        int m2;
    }

    float translationMatrix[ 16 ];    //only used if not null
    float unk5[ 16 ];                 //bounding box?


    loddata< ((flags & 1) != 0) && (lodlink != 0) > data;	//hasbones = (((flags & 1) != 0) && (lodlink != 0))

    if((nAnimationStates > 0) && ((flags & 1) == 0))
    {
        int t6;
        if(t6 != 0)
        {
            tAnimationStates localAnimationStates2[ BoneDataSize ];
        }
    }
};


int sumlod2count;

for(int i = 0; i < sumlod2count;  )
{
    struct lodGroup                    //each group contains the same model, but different primitive count
    {
        int lodcount;
        tLod2 lod2s[ lodcount ];
    } lg;

    i += lg.lodcount;
}

//-------------------------------------------------------------------------------------------
// End of file
//-------------------------------------------------------------------------------------------

EDIT: update on material field (lightning)
EDIT: update2: figured float7, its an animation state struct. They are explicit, easy to apply. For example:

Code:
glTranslatef(
    tAnimationState.rotatePositionX,
    tAnimationState.rotatePositionY, 
    tAnimationState.rotatePositionZ);
glRotatef(
    acos(tAnimationState.degrees) * 180 / pi, 
    tAnimationState.rotateX, 
    tAnimationState.rotateY, 
    tAnimationState.rotateZ);
glTranslatef(
    -tAnimationState.rotatePositionX,
    -tAnimationState.rotatePositionY, 
    -tAnimationState.rotatePositionZ);

local animations seems to belong to the current lod.
Also, looks like its enough to load only 1 group of the lodGroups, the patchers Degree of object expression seems to choose one from these groups. (Or loads the first group if the rest doesnt exist). The highest res seems to be the first group, and the lowest is the last. (I guess that explains why setting Degree of object expression to low makes the game loading slower -.-)
 
Last edited:
Newbie Spellweaver
Joined
Sep 15, 2008
Messages
56
Reaction score
19
Hi just one addition:
on the top that unkown stuff in your code is used to determine the element glow "anchorpoints". it matters only for weapons.

Code:
--------------
Header section
--------------
byte                nameLength
char[nameLength]    encFilename         //Encrypted with XOR 0xCD
dword               ver                 //always 0x14; 0x15; 0x16 Probably Version/Some function
dword               ??
[color=red]float X 3           XYZ element1 startpoint
float X 3           XYZ element1 endpoint
if version == 22 (0x16)
    float X 3       XYZ element2 startpoint
    float X 3       XYZ element2 endpoint[/color]
dword X 2           ??          //always 0x00
char[16]            Filename (first 16 chars)
float X 6           BoundingBox
float               ??                  //always 0.5
dword               ?Flag01
dword               ?Flag02
struct Flag02Data {
  float X 3         ??
}
dword               MeshTypeFlag
dword               LODFlag
dword               ?Flag03
dword               TotalMeshCount      //All Mesh and LOD
dword               MeshCount

edit: and for animation i can only give a guess: animation is stored in those .ani files and they are used on the o3d. Which animation will be used seems to be saved in that uknData3 thing. Where they are indexed or whatever i don't know. For my v3 converter i just make the user select a original item to define what animation will used (if he want's animation of vagrant gauntlets he selects those and the converter just copies that uknData3 ;))
Code:
struct LODmesh {
  dword        hasBones         //if this dword is 0x01, model is animated
  dword        uknCount3        //?? Something related to bones
  struct uknData3 (
    dword
  } uknData3[uknCount3]
 
Last edited:
Junior Spellweaver
Joined
Jun 15, 2009
Messages
107
Reaction score
37
I think those fields have to do something with animation. The usual monster models has no bones at all. I think the tLod2 struct's unk8 field has to do something with the bone table... but thats just a guess. Also, when the o3d has no bones at all, or unk8 is greater than the bone count, the lod includes those float7's.
 
Joined
Dec 5, 2008
Messages
608
Reaction score
70
a question pipelli. Actually if we try to take a model from another game then convert it into o3d to try to put it in flyff, player can pass throught those object...

have you find a way to avoid this in your converter v3 ?
 
Newbie Spellweaver
Joined
Sep 15, 2008
Messages
56
Reaction score
19
I think those fields have to do something with animation. The usual monster models has no bones at all. I think the tLod2 struct's unk8 field has to do something with the bone table... but thats just a guess. Also, when the o3d has no bones at all, or unk8 is greater than the bone count, the lod includes those float7's.

Monsters have bones, atleast when i load them in my o3d v3 converter the colors assigned to the vertices seem to make sense.

a question pipelli. Actually if we try to take a model from another game then convert it into o3d to try to put it in flyff, player can pass throught those object...

have you find a way to avoid this in your converter v3 ?

You want to make landscape objects? I didn't really investigate them but they seem to have a bit different format. My converter is not very good i know, but c'mon im not a gamedeveloper. that was the very first time i made something like that. the first time i saw that sheet on xentax Duotone mentioned i was like "WTF?". but after 1 year noone made a tool, so i opened the file with a hex editor and sat hours reading it "along" that sheet. and it made sense and then i wrote that damn converter ;) i have no idea about reversing 3D formats :/
 
Templar FlyFF <3
Joined
Sep 25, 2008
Messages
307
Reaction score
21
Monsters have bones, atleast when i load them in my o3d v3 converter the colors assigned to the vertices seem to make sense.



You want to make landscape objects? I didn't really investigate them but they seem to have a bit different format. My converter is not very good i know, but c'mon im not a gamedeveloper. that was the very first time i made something like that. the first time i saw that sheet on xentax Duotone mentioned i was like "WTF?". but after 1 year noone made a tool, so i opened the file with a hex editor and sat hours reading it "along" that sheet. and it made sense and then i wrote that damn converter ;) i have no idea about reversing 3D formats :/

I lol'd. nice man :)
U should still work on this, find more infos on the webs, maybe consult Deadly. or someone who does know.
 
Junior Spellweaver
Joined
Jun 15, 2009
Messages
107
Reaction score
37
Monsters have bones, atleast when i load them in my o3d v3 converter the colors assigned to the vertices seem to make sense.

Sorry my bad. I meant their in-o3d bone field (starting at int nBones) is empty.
 
Custom Title Activated
Loyal Member
Joined
Sep 9, 2008
Messages
1,949
Reaction score
390
If you want to reverse 3D formats, I suggest learning XNA and look through the .X format. You can also make custom importers and processors. Using the knowledge of .X you can create an importer and start playing with 3D objects using C# or VB.

I was in the process of wring a o3d importer to XNA. Now that the format is basically here, I can finish it so people can use it in their XNA projects and what-not.

Thanks to Duotone, Pipelli, and the rest for their hard work in deciphering the format structure.
 
Junior Spellweaver
Joined
Jun 15, 2009
Messages
107
Reaction score
37
Well, its not done yet.
No clue how to assign bones to a lod from the bone field. I guess it's set at int unk8, also that part is a mess.
Don't know if the m1 and unk8 parts are belong togeather or not (if m1 == 0 than theres animation data comeing. Why there?)
If you look at that field as it begins at unk8 and ends at m1, the problem is that the number of integer between them varies, and not allways ends with a 0xFFFFFFFF. So when does it ends?
Also some lods can be chained togeather, all of the lods may have their own animation, but they shouldn't clear the modelview matrix between them. (I guess thats might be set by a value after int unk8).
The purpose of the struct tbonedata16 in the bone filed is also unknown, there might be more of these fields comeing after eachother sequentially, they may belong to the upcomeing animation data.
And it would be nice to know if unsigned int type1; is a flag or a version. Not mentioning the other unknown areas.
 
Last edited:
Custom Title Activated
Loyal Member
Joined
Sep 9, 2008
Messages
1,949
Reaction score
390
Animating is not really that hard to do. At least I can import it into the XNA framework projects. one step closer to this community realizing a very real world editor.

baby steps people. Baby steps.
 
Junior Spellweaver
Joined
Jun 15, 2009
Messages
107
Reaction score
37
I guess noone will be suprised about the .ani files being pretty much similar to .o3d 's bone section

Some copy pastes:
Code:
struct tAnimationState
{
    float rotateX;
    float rotateY;
    float rotateZ;
    float degrees;
    float rotatePositionX;     //center point of rotation
    float rotatePositionY;
    float rotatePositionZ;
};

//-------------------------------------------------------------------------------------------
// Beginning of file
//-------------------------------------------------------------------------------------------

int unk2;
int unk1;
float unk3;         //allways 0.5

int unk4[ 8 ];
int nBones;

int nAnimationStates;
int unk11; 

struct tbonedata2
{
    int namelen;
    char bonename[ namelen ];           //bone name. usually "Bone1", "Bone2", etc
    float trans1[ 16 ];
    float trans2[ 16 ];
    int some_index;                     //starts with -1, less than nBones
}bonedata2[ nBones ];

int nUnk3;

for(int j = 0; j < nUnk3; )
{
    int unk5;   			//0 or 1 allways
    if( unk5 != 0 )
    {
        tAnimationState globalAnimStates[ nAnimationStates ];
        j += nAnimationStates;  //increase counter here only
    }else
    {
        //this branch (unk5 == 0) does NOT increase the counter
        struct tbonedata16
        {
            float trans[ 16 ];
        }bonedata16;
    }
}

int unk6;       //0 or 1 allways (well, not for ani. its sometimes 2)
if(unk6 == 0)
{
    struct tbonedata17
    {
        float trans[ 16 ];
        int unk7;
    }bonedata17;
}

//rest is unknown, mostly 0's

Also, anyone any idea why are the bone indexes always dividable by 3?
Another thing is interesting that if you count all the 0 (tbonedata16) and 1 (tAnimationState) fields in the last part of the bone section (includeing the last tbonedata17 field), the result will equals to int nBones.
That makes there are 3 arrays for bones in o3d files.

Also, in o3d files, int t7 in struct tLod2 specifies a lod in the current lod group, the current lod inherits the indexed lod's modelview matrix.
(easiest way to implement is to save modelview matrix for each lod after its animated, than load when a lod refers to it) (of course its slow that way :p)
 
Last edited:
Newbie Spellweaver
Joined
Sep 15, 2008
Messages
56
Reaction score
19
Well i guess i can't help anymore since i really have no idea about that topic ;) all those people probably think i am a wizard because i made a faulty converter (which not works for every file, only uses LOD1, uses OBJ and badass code :D, but someone had to make one xD).

Since you didn't have that element stuff in your code (you had it as unk data) i assume you didn't look at page 2 in the xentax topic (or not recently). i added that info there. also fatduck posted an update for the file header (i dont know cpp so i can't really understand that struct stuff code of you if you have it already in there or not :/)

with the 0xFFFFFFF thing you mean the nTerminator? i had problems with this too if i remember correctly until fatduck posted that update..

this sheet should contain all info from the xentax thread (new header and that element stuff)


Code:
--------------
Header section
--------------
byte                nameLength
char[nameLength]    encFilename         //Encrypted with XOR 0xCD
dword               ver                 //always 0x14; 0x15; 0x16 Probably Version/Some function
dword               ??
float X 3           XYZ element1 startpoint
float X 3           XYZ element1 endpoint
if version == 22
    float X 3       XYZ element2 startpoint
    float X 3       XYZ element2 endpoint
dword X 2           ??          //always 0x00
char[16]            Filename (first 16 chars)
float X 6           BoundingBox
float               ??                  //always 0.5
dword               ?Flag01
dword               ?Flag02
struct Flag02Data {
  float X 3         ??
}
dword               MeshTypeFlag
dword               LODFlag
dword               ?Flag03
dword               TotalMeshCount      //All Mesh and LOD
dword               MeshCount
	

------------
Mesh Section
------------
struct LODmesh {
  dword        hasBones         //if this dword is 0x01, model is animated
  dword        uknCount3        //?? Something related to bones
  struct uknData3 (
    dword
  } uknData3[uknCount3]
  dword        ??	
  dword        nTermimator      //0xFFFFFFFF
  float X 16   Matrix4X4        //transformation
  float X 6    BBox             //?? Bounding Box
  byte X 40                     //always 00
  dword        XCount           //?? Vert Shader
  dword        VtCount          //verts count
  dword        FcCount          //face count
  dword        FcSize           //Face indices size
  struct XData {
    float X 3
  } XData[XCount]
  struct VertPool {
    float X 3      posXYZ
    if (hasBones) {
       float          weight1
       float          weight2
       word           Bone1
       word           Bone2
    }
    float X 3      NormalXYZ
    float X 2      UV
  } VertPool[VtCount]
  struct Face {
    word           idx1
    word           idx2
    word           idx3
  } Face[FcCount]
  struct XIndex {
    word           idx
  } XIndex[VtCount]
  dword          XXCount        //same as XCount - no?
  struct XXData {
    dword
  } XXData[XXCount]
  ----------------
  material section
  ----------------
  dword
  dword          MatCount       //?? *material count(even MatCount = 0, still have material)
  struct Material {
    float x 4   colorRGBA
    float x 4    colorRGBA
    float x 4    colorRGBA
    float x 4    colorRGBA
    dword                       //always 00
    dword        TexLeg
    char[TexLeg] szTexture
    byte			// always 0x00
  } Material[MatCount]
  dword        matIDCount     //face material count
  struct FaceMatID {
    dword                       //always 0
    dword        MFcCount       //face for this MatID has to be the same as FaceCount
    dword        MatID
    dword                       //always 4
    byte X 120                  //all 00
  } FaceMatID[matIDCount]
} LODmesh[lodCount]
 
Junior Spellweaver
Joined
Jun 15, 2009
Messages
107
Reaction score
37
Thanks again, i haven't seen those yet.
As for the nTerminator, its not allways there, and thats for sure. If it was allways there it would make things alot easier >.<
 
Joined
Dec 5, 2008
Messages
608
Reaction score
70
hi, there is something strange in last fatduck version given by pipelli...

--------------
Header section
--------------
byte nameLength
char[nameLength] encFilename //Encrypted with XOR 0xCD
dword ver //always 0x14; 0x15; 0x16 Probably Version/Some function
dword ??
float X 3 XYZ element1 startpoint
float X 3 XYZ element1 endpoint
if version == 22
float X 3 XYZ element2 startpoint
float X 3 XYZ element2 endpoint
dword X 2 ?? //always 0x00
char[16] Filename (first 16 chars)
float X 6 BoundingBox
float ?? //always 0.5
dword ?Flag01
dword ?Flag02
struct Flag02Data {
float X 3 ??
}
dword MeshTypeFlag
dword LODFlag
dword ?Flag03
dword TotalMeshCount //All Mesh and LOD
dword MeshCount



------------
Mesh Section
------------
struct LODmesh {
dword hasBones //if this dword is 0x01, model is animated
dword uknCount3 //?? Something related to bones
struct uknData3 (
dword
} uknData3[uknCount3]
dword ??
dword nTermimator //0xFFFFFFFF
float X 16 Matrix4X4 //transformation
float X 6 BBox //?? Bounding Box
byte X 40 //always 00
dword XCount //?? Vert Shader
dword VtCount //verts count
dword FcCount //face count
dword FcSize //Face indices size
struct XData {
float X 3
} XData[XCount]
struct VertPool {
float X 3 posXYZ
if (hasBones) {
float weight1
float weight2
word Bone1
word Bone2
}
float X 3 NormalXYZ
float X 2 UV
} VertPool[VtCount]
struct Face {
word idx1
word idx2
word idx3
} Face[FcCount]
struct XIndex {
word idx
} XIndex[VtCount]
dword XXCount //same as XCount - no?
struct XXData {
dword
} XXData[XXCount]
----------------
material section
----------------
dword
dword MatCount //?? *material count(even MatCount = 0, still have material)
struct Material {
float x 4 colorRGBA
float x 4 colorRGBA
float x 4 colorRGBA
float x 4 colorRGBA
dword //always 00
dword TexLeg
char[TexLeg] szTexture
byte // always 0x00
} Material[MatCount]
dword matIDCount //face material count
struct FaceMatID {
dword //always 0
dword MFcCount //face for this MatID has to be the same as FaceCount
dword MatID
dword //always 4
byte X 120 //all 00
} FaceMatID[matIDCount]
} LODmesh[lodCount]

lodCount at the end is never read...
and dword TotalMeshCount //All Mesh and LOD
dword MeshCount
are never used so does this mean that lodcount correspond to TotalMeshCount ??
 
Junior Spellweaver
Joined
Jun 15, 2009
Messages
107
Reaction score
37
If i'm right they assumed there is only one lod field, i could be wrong tho.

Edit:

So we were looking things through with Divine and managed to simplify the struct tLod2. It turned out that that type1 and type2 fields doesn't even exist in the beginning of the file. Thanks for Divine for pointing that out.

Also, the field used to be called m1 is lodlink index for sure. (Index of the lod wich modelview matrix should be loaded at the beginning of the curren't lod's animation) (Indexed lod may be animated as well.)
 
Last edited:
Joined
Dec 5, 2008
Messages
608
Reaction score
70
about this in loddata :

float unk5[ 16 ]; //bounding box?


i find that this is :
float bbox[6]; //modifyed bounding box (is it correct value after matrix translation ?
int isanimated; //0 all the time but 1 on objet or mover that have an animation on 10 files i was correct in my studdy but strangely BigMuscle have 0...
int unk5[9]; //seem to be always 0

about matrix i have a question :

if i use those 4 matrix : 1 0 0 0 / 0 1 0 0 / 0 0 1 0/ 0 0 0 1
am i right if i say that don't change anything ? so if i take a model from another game and don't have the matrix in .obj file i could use those value for matrix ?

and about animation (for those who know how it work) :

am i right if i suppose that .chr file define "parts" of a mover and .ani define movment for thoses part corresponding to the animation we have in the file name ? (idle,atk etc.)


at the top :
unsigned int unk20; //checksum maybe?

i think it's a float not an int...
 
Last edited:
Joined
Dec 5, 2008
Messages
608
Reaction score
70
Hi duotone, some news...

in MATID section in the unk[31] table, the second value (often 255) correspond to transparency :

here what i have with 100 value :

Duotone - o3d format - RaGEZONE Forums


(here i haven't apply this value on the center mesh, only on the 2 mesh surrounding it :p

i tryed to change the others value but i don't see any difference in Beast, perhaps i will have to try in game and see...

Oh and btw i think that the "unk3" value in each mesh (just before materials) correspond to this :
// Addition Texture
#define ATEX_NONE 0 //- Ne pas utiliser plus de cartes
#define ATEX_00 0 // Texture mis 00 fois (par défaut)
#define ATEX_USE 1 //- Activer des cartes supplémentaires
#define ATEX_01 1 // Texture Set 01 fois
#define ATEX_02 2 // Texture Set 02 fois
#define ATEX_03 3 // 텍스쳐세트 03번
#define ATEX_04 4 // 텍스쳐세트 04번
#define ATEX_05 5 // 텍스쳐세트 05번
#define ATEX_06 6 // 텍스쳐세트 06번
#define ATEX_07 7 // 텍스쳐세트 07번
in define.h

in all o3d i always saw value from 1 to 7 (7for azria trees) i don't know what it's supposed to do but well i think it's that...
 
Last edited:
Newbie Spellweaver
Joined
Jun 2, 2010
Messages
5
Reaction score
0
Sorry for reviving this topic since its been asleep for half a year, and I would like to quickly say this is my first post on Ragezone.

To the point.

I've been trying to wrap my head around this format and even made a program using C# to help visualize this data. I've noticed something interesting.

I've been trying to edit character models, mostly the body parts which correspond to different outfits. I noticed that when using the converters to convert from obj then back to o3d, the hasbones flag is set to 0, which means the weights and bones from the original o3d file is dropped.

Code:
struct VertPool {
float X 3 posXYZ
if (hasBones) {
[B]float weight1
float weight2
word Bone1
word Bone2[/B]
}
float X 3 NormalXYZ
float X 2 UV
} VertPool[VtCount]

Playing around with this, it seems that these bones are needed with the Xdata, the XXdata, uKndata3 and Xindex data if animation is wanted.

Ive tried inserting this data into my new o3d from the source o3d, and that caused some interesting and disturbing deformations of the model in game.

Also I noticed that when the Meshflag is set, there appears to be a bunch of extra data in the header which Ive not been able to make sense of.

I'm not claiming I know much about 3d file formats or 3d modeling, I'd just like a push in the right direction.

I would attach or link my o3d editor, but not being familiar with the forums and no one knowing me, Ill wait to hear back to this post.
 
Last edited:
Joined
Dec 5, 2008
Messages
608
Reaction score
70
Xdata is the real vertice list, vertice list here are just a buffer list to send to the GPU and just after you have a list of index buffer to optimise GPU 's work (see : )
the actual tools you could find on internet are incomplete and don't work in all case like you could see...

To have a better tool of course you need to make your own.

weight are effectively needed for bone movement so yeah it' linked to uKndata3 with correspond to bone data :p
 
Ace of Hearts
Joined
Jul 28, 2009
Messages
739
Reaction score
104
it's fine seeing as the format is still incomplete and your posting usefull information
 
Back
Top