MS3D Loading Problem

Started by
13 comments, last by xg0blin 19 years, 7 months ago
This is really confusing me. I've looked at other peoples code (theirs works) and we are doing basically the same thing, and mine works, for the most part anyways. The loader reads the vertices correctly, up until it gets to the 47th vertex, at which point it messes up z, then from there after the whole thing is screwed. Here is the part of my code where everything is messing up:

void MS3DModel::LoadMS3D(string FileName)
{
	ifstream Fin;
	Fin.open(FileName.c_str(), ios::in||ios::binary);
	if(Fin.is_open() && Fout.is_open())
	{
			HeaderMS3D MS3DHeader;

			Fin.read((char *)&MS3DHeader, sizeof(HeaderMS3D));
			Fin.read((char *)&NumVertices, sizeof(ushort));
			Vertices = new VertexMS3D[NumVertices];
	                for(int i = 0; i < NumVertices; i++)
		                Fin.read((char *)&Vertices, sizeof(VertexMS3D));

It reads the header, it reads the numvertices correctly, and then it reads the first 47 vertices correctly (I've used a loader that works and verifed that that is where mine is screwing it up). I don't understand how this can be. If it loads the first set of 15 bytes (the size of VertexMS3D) correctly, why not the rest? What in the hell is going on?
Advertisement
You have to pack the structures into a byte boundary, its a common gotcha, add this to your code before your structure definition:

#ifdef _MSC_VER#	pragma pack( push, packing )#	pragma pack( 1 )#	define PACK_STRUCT#elif defined( __GNUC__ )#	define PACK_STRUCT	__attribute__((packed))#else#	error you must byte-align these structures with the appropriate compiler directives#endif


and then define your structures as (these asume you're using SDL, change UintX variables appropiatelly if you're using DX):
  typedef struct PACK_STRUCT  {    char    id[10];                                     // always "MS3D000000"    int     version;                                    // 4  } ms3d_header_t;  typedef struct PACK_STRUCT  {    Uint8   flags;// SELECTED | SELECTED2 | HIDDEN    float   vertex[3];    char    boneId;                                     // -1 = no bone    Uint8   referenceCount;  } ms3d_vertex_t;  //  // nNumTriangles * sizeof (ms3d_triangle_t)  //  typedef struct PACK_STRUCT  {    Uint16  flags; // SELECTED | SELECTED2 | HIDDEN    Uint16  vertexIndices[3];    float   vertexNormals[3][3];    float   s[3];                  float   t[3];    Uint8   smoothingGroup; // 1 - 32    Uint8   groupIndex;  } ms3d_triangle_t;//// nNumGroups * sizeof (ms3d_group_t)//typedef struct PACK_STRUCT{  Uint8  flags;                        // SELECTED | HIDDEN  char   name[32];  Uint16 numtriangles;  Uint16 *triangleIndices;//[numtriangles];// the groups group the triangles  char   materialIndex;                // -1 = no material} ms3d_group_t;//// nNumMaterials * sizeof (ms3d_material_t)//typedef struct PACK_STRUCT{    char            name[32];                           //    float           ambient[4];                         //    float           diffuse[4];                         //    float           specular[4];                        //    float           emissive[4];                        //    float           shininess;                          // 0.0f - 128.0f    float           transparency;                       // 0.0f - 1.0f    char            mode;                               // 0, 1, 2 is unused now    char            texture[128];                        // texture.bmp    char            alphamap[128];                       // alpha.bmp} ms3d_material_t;//// nNumJoints * sizeof (ms3d_joint_t)////typedef struct PACK_STRUCT{        float           time;                               // time in seconds  float           rotation[3];                        // x, y, z angles} ms3d_keyframe_rot_t;typedef struct PACK_STRUCT{  float           time;                               // time in seconds  float           position[3];                        // local position} ms3d_keyframe_pos_t;typedef struct PACK_STRUCT{  Uint8   flags;// SELECTED | DIRTY  char    name[32];  char    parentName[32];    float   rotation[3];// local reference matrix  float   position[3];  Uint16  numKeyFramesRot;  Uint16  numKeyFramesTrans;  // local animation matrices  ms3d_keyframe_rot_t *keyFramesRot;//[numKeyFramesRot];  // local animation matrices  ms3d_keyframe_pos_t *keyFramesTrans;//[numKeyFramesTrans];} ms3d_joint_t;


That will work for VC++ and GCC
No, I've done that. Like I said, it reads the Header just fine, then the number of vertices, then the first 46.66 vertex structures correctly. Then from that point on it gives me the same number no matter how long it keeps reading.

EDIT: Here, I made an output file, I'll post it here:

MS3DHeader.ID: MS3D000000MS3DHeader.Version: 4NumVertices: 1302Vertices List---------------------------------------------------------------------Vertex      0Flags:      0Vertices:   -34.0001 14.7175 1.52404BoneID:     -1ReferenceID 8Vertex      1Flags:      0Vertices:   -33.6294 14.8621 1.24768BoneID:     -1ReferenceID 4Vertex      2Flags:      0Vertices:   -34.1047 14.7702 1.21844BoneID:     -1ReferenceID 5Vertex      3Flags:      0Vertices:   -32.8446 14.7657 -0.292704BoneID:     -1ReferenceID 7Vertex      4Flags:      0Vertices:   -30.4681 14.3379 -0.358059BoneID:     -1ReferenceID 6Vertex      5Flags:      0Vertices:   -32.7709 14.6641 -0.870893BoneID:     -1ReferenceID 6Vertex      6Flags:      0Vertices:   -33.0026 13.8615 -1.42998BoneID:     -1ReferenceID 9Vertex      7Flags:      0Vertices:   -31.1441 13.6979 -1.30295BoneID:     -1ReferenceID 7Vertex      8Flags:      0Vertices:   -30.9061 12.8341 -1.27772BoneID:     -1ReferenceID 4Vertex      9Flags:      0Vertices:   -31.1572 14.2926 -1.00094BoneID:     -1ReferenceID 2Vertex      10Flags:      0Vertices:   -29.1747 14.3218 -0.884574BoneID:     -1ReferenceID 2Vertex      11Flags:      0Vertices:   -31.5003 13.7036 1.98778BoneID:     -1ReferenceID 4Vertex      12Flags:      0Vertices:   -33.2353 14.5791 1.70136BoneID:     -1ReferenceID 7Vertex      13Flags:      0Vertices:   -32.5797 13.503 1.81474BoneID:     -1ReferenceID 4Vertex      14Flags:      0Vertices:   -29.1555 13.016 -0.834617BoneID:     -1ReferenceID 5Vertex      15Flags:      0Vertices:   -30.1952 12.8007 1.42691BoneID:     -1ReferenceID 6Vertex      16Flags:      0Vertices:   -31.0301 12.826 -0.112222BoneID:     -1ReferenceID 6Vertex      17Flags:      0Vertices:   -33.8708 14.4715 1.70389BoneID:     -1ReferenceID 5Vertex      18Flags:      0Vertices:   -33.6024 14.5344 -1.30255BoneID:     -1ReferenceID 4Vertex      19Flags:      0Vertices:   -33.5597 14.3928 -1.40545BoneID:     -1ReferenceID 4Vertex      20Flags:      0Vertices:   -34.3526 13.2877 -1.30255BoneID:     -1ReferenceID 7Vertex      21Flags:      0Vertices:   -33.6618 12.1172 -1.11471BoneID:     -1ReferenceID 1Vertex      22Flags:      0Vertices:   -33.739 12.1999 -1.1661BoneID:     -1ReferenceID 2Vertex      23Flags:      0Vertices:   -33.6369 12.5736 -1.12485BoneID:     -1ReferenceID 4Vertex      24Flags:      0Vertices:   -30.6325 14.3931 0.670446BoneID:     -1ReferenceID 6Vertex      25Flags:      0Vertices:   -32.9677 14.8038 0.492123BoneID:     -1ReferenceID 7Vertex      26Flags:      0Vertices:   -33.6383 14.9543 0.398585BoneID:     -1ReferenceID 5Vertex      27Flags:      0Vertices:   -33.9265 14.7961 0.736951BoneID:     -1ReferenceID 5Vertex      28Flags:      0Vertices:   -33.851 14.7192 0.895779BoneID:     -1ReferenceID 8Vertex      29Flags:      0Vertices:   -33.5597 14.3928 -1.40545BoneID:     -1ReferenceID 2Vertex      30Flags:      0Vertices:   -32.3767 14.3632 -1.41819BoneID:     -1ReferenceID 3Vertex      31Flags:      0Vertices:   -33.269 14.1266 -1.49379BoneID:     -1ReferenceID 6Vertex      32Flags:      0Vertices:   -34.2928 12.3452 -0.168718BoneID:     -1ReferenceID 6Vertex      33Flags:      0Vertices:   -34.6494 13.474 -0.201892BoneID:     -1ReferenceID 5Vertex      34Flags:      0Vertices:   -34.6844 13.4545 -0.548705BoneID:     -1ReferenceID 6Vertex      35Flags:      0Vertices:   -34.1057 12.6303 2.0338BoneID:     -1ReferenceID 5Vertex      36Flags:      0Vertices:   -33.685 12.4995 1.58147BoneID:     -1ReferenceID 2Vertex      37Flags:      0Vertices:   -34.0046 12.119 1.82141BoneID:     -1ReferenceID 1Vertex      38Flags:      0Vertices:   -34.1702 13.2205 -1.35758BoneID:     -1ReferenceID 4Vertex      39Flags:      0Vertices:   -33.8574 13.18 -1.35281BoneID:     -1ReferenceID 7Vertex      40Flags:      0Vertices:   -30.8835 12.5815 1.87066BoneID:     -1ReferenceID 5Vertex      41Flags:      0Vertices:   -31.5054 12.2179 2.08457BoneID:     -1ReferenceID 5Vertex      42Flags:      0Vertices:   -31.512 12.7207 1.07224BoneID:     -1ReferenceID 3Vertex      43Flags:      0Vertices:   -33.3185 14.1841 1.70707BoneID:     -1ReferenceID 5Vertex      44Flags:      0Vertices:   -33.3245 14.0567 0.828054BoneID:     -1ReferenceID 8Vertex      45Flags:      0Vertices:   -33.7563 12.5177 -1.15696BoneID:     -1ReferenceID 7Vertex      46Flags:      0Vertices:   -33.9564 12.3112 -1.19828BoneID:     -1ReferenceID 3Vertex      47Flags:      0Vertices:   -31.6282 13.1414 -4.30075e+008BoneID:     -51ReferenceID 205Vertex      48Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      49Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      50Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      51Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      52Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      53Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      54Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      55Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      56Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      57Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      58Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      59Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      60Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      61Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      62Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      63Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      64Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      65Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      66Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      67Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      68Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      69Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      70Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      71Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      72Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      73Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      74Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      75Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      76Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      77Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      78Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      79Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      80Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      81Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      82Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      83Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      84Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      85Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      86Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      87Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      88Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      89Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      90Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      91Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      92Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      93Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      94Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      95Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      96Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      97Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      98Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      99Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205Vertex      100Flags:      205Vertices:   -4.31602e+008 -4.31602e+008 -4.31602e+008BoneID:     -51ReferenceID 205...So on and so forth


Here are my structure declarations, maybe I did something wrong? I just can't seem to find anything.
#	pragma pack( push, packing )#	pragma pack( 1 )#define PACK_STRUCTtypedef unsigned char  byte;typedef unsigned short ushort;typedef unsigned long  ulong;struct HeaderMS3D{	char	ID[10]; 	int	Version; } PACK_STRUCT;struct VertexMS3D{	byte	Flags; 	float Vertex[3]; 	char	BoneID; 	byte	ReferenceCount; } PACK_STRUCT;struct TriangleMS3D{	ushort	Flags;  	ushort	VertexIndex[3];	float	Normals[3][3];	float	S[3];	float	T[3];	byte	SmoothingGroup; 	byte	GroupIndex; } PACK_STRUCT;struct GroupMS3D{	byte	Flags; 	char	Name[32];	ushort	NumTriangles;	ushort	*TriangleIndicies;	char	MaterialIndex;} PACK_STRUCT;struct MaterialMS3D{	char  Name[32];	float Ambient[4];	float Diffuse[4];	float Specular[4];	float Emissive[4];	float Shininess; 	float Transparency;	char  Mode; 	char  Texture[128];	char  AlphaMap[128];} PACK_STRUCT;struct RotationMS3D{	float Time;	float Rotation[3];} PACK_STRUCT;struct PositionMS3D{	float Time;	float Position[3];} PACK_STRUCT;struct JointMS3D{    byte         Flags;                                 char         Name[32];                               char         ParentName[32];                         float        Rotation[3];                            float        Position[3];    short        NumKeyFramesRot;                        short        NumKeyFramesTrans;                  		RotationMS3D *KeyFramesRot;          PositionMS3D *KeyFramesTrans; } PACK_STRUCT;#pragma pack( pop, packing )#undef PACK_STRUCT


I can't find anything. This really sucks.

[Edited by - xg0blin on September 3, 2004 8:18:21 PM]
I put an

if(Fin.fail()) return;

inside of my for loop that reads the vertices. It fails at vertex 47. WTF? What would cause it to fail?

I used the terrain generator and made another model. It makes it through all of the vertices, and then the fail bit is set and it exits when reading the triangles. This is really freaking weird.
Sweet jesus, I found it. What's wrong with this line:

Fin.open(FileName.c_str(), ios::in||ios::binary);

Yeah, that was hard to find. I put || instead of |, and it was trying to read anyways. How very odd.
Quote:Original post by xg0blin
Sweet jesus, I found it. What's wrong with this line:

Fin.open(FileName.c_str(), ios::in||ios::binary);

Yeah, that was hard to find. I put || instead of |, and it was trying to read anyways. How very odd.

A non-zero value logical-ORed with anything evaluates to 1, so "ios::in || ios::binary" = 1. I checked ios.h and ios::in = 1, so what your code did was open the file for reading (as it should) but in text mode. Since it is a text file, I can tell you right now that you have not solved the bug.

Look at the file. The 47th vertex is the first one that uses scientific notation.
Quote:Vertices: -31.6282 13.1414 -4.30075e+008

You are not reading such values correctly.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Quote:A non-zero value logical-ORed with anything evaluates to 1, so "ios::in || ios::binary" = 1. I checked ios.h and ios::in = 1, so what your code did was open the file for reading (as it should) but in text mode. Since it is a text file, I can tell you right now that you have not solved the bug.


It fixed the bug. MS3D is a binary format. MS3DAscii is ascii. I knew better than to do that, I just didn't see it and I type || all the time so I didn't think anything about it.

My problem now though it the texture coordinates (if you know something about the way ms3d stores those). The model is loaded correctly, the textures are just all wrong, and I don't know why. In the debugger, they're negative. Weird.

Oh, OK. I thought your vertex list was an excerpt from the model file... nevermind.

As for the texture data, I don't know about MS3D, but I know some model formats list only unique vertex positions. For example, a cube has 8 vertices, right? Actually, no... not necessarily. You might have a corner with the texture coordinate (0,1) for one face, and (1,0) for another face that shares that vertex. So you'd actually create at least two vertices there... if you don't catch that, then the end result would be a model with messed up texture coordinates. So for all I know, that could be what's happening.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Here is the code I have for the drawing (I haven't added materials yet, I want to get textures first, and it's using the wrong textures on the wrong body parts). This code is simple enough to understand. The textures are attached to the wrong groups, and I can't figure out why. The code is pretty easy to follow. It's binding the wrong texture. I checked it in the debugger, and it acts as if it's using the right texture. I dunno. I've written other model loaders, but this is my first crack at MS3D. Thanks for the help anyways, everyone that has helped.

void MS3DModel::DisplayModel()	{		for(int i = 0; i < NumGroups; i++)		{			for(int j = 0; j < Groups.NumTriangles; j++)			{				int Index = Groups.TriangleIndicies[j];				glBindTexture(GL_TEXTURE_2D, Groups.MaterialIndex);				glBegin(GL_TRIANGLES);					glNormal3fv(Triangles[Index].Normals[0]);					glTexCoord2f(Triangles[Index].S[0], Triangles[Index].T[0]);					glVertex3fv(Vertices[Triangles[Index].VertexIndex[0]].Vertex);					glNormal3fv(Triangles[j].Normals[1]);					glTexCoord2f(Triangles[Index].S[1], Triangles[Index].T[1]);					glVertex3fv(Vertices[Triangles[Index].VertexIndex[1]].Vertex);					glNormal3fv(Triangles[Index].Normals[2]);					glTexCoord2f(Triangles[Index].S[2], Triangles[Index].T[2]);					glVertex3fv(Vertices[Triangles[Index].VertexIndex[2]].Vertex);				glEnd();			}		}	}
MaterialIndex is a char, I'm not sure if that'll cause a problem are not when passing it directly to glBindTexture. But your drawing function looks like it has no errors; it's likely the code that sets the textures is wrong. Can you post it?
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.

This topic is closed to new replies.

Advertisement