www.xbdev.net xbdev - software development
Tuesday October 22, 2019
home | about | contact | Donations

     
 

3D File Formats

The bits and bytes...

 

MS3D MilkShape Format - Grabbing all the information
Author bkenwright@xbdev.net

Well we have the structures, and the first part of the data seems correct, next I think we should read it all in and dump it all out to a txt file, as if we ever need to look at the raw data inside the file, we can just use this dump program ;)  Its educational and also useful.

 

If you look at the code, it all seems pretty straight forward till you get to the groups!  Because one of the member variables of that structure, has its size determined by the number of triangles, well then we have to do a little bodgy bit of code where we count the size of the structure and add on how many extra bytes are needed for the data.

 

 

Source Code - Download

/**********************************************************************************/
/*                                                                                */
/*  File:    main.cpp                                                             */
/*  Author:  bkenwright@xbdev.net                                                 */
/*  Web:     www.xbdev.net                                                        */
/*  Date:    28-08-2006                                                           */
/*                                                                                */
/**********************************************************************************/
/*
	Introduction to the milkshape ms3d file format
*/
/**********************************************************************************/

#include <stdio.h>	// fopen(..), sprintf(..)
#include <stdarg.h> 	// va_start, va_end

#include "ms3d.h"   // The definition of the layout of the ms3d file format, and
                    // some structures to show how its layed out!

//Saving debug information to a log file
void dprintf(const char *fmt, ...) 
{
	va_list parms;
	char buf[256];

	// Try to print in the allocated space.
	va_start(parms, fmt);
	vsprintf (buf, fmt, parms);
	va_end(parms);

	// Write the information out to a txt file
	FILE *fp = fopen("output.txt", "a+");
	fprintf(fp, "%s", buf);
	fclose(fp);
}// End dprintf(..)



/**********************************************************************************/
/*                                                                                */
/*  main() - Program Entry Point!   Where it all starts...                        */
/*                                                                                */
/**********************************************************************************/

void main()
{
	dprintf("Welcome to the ms3d tutorial...\n\n");


	// Lets open the test ms3d file we are using, called box.ms3d
	FILE * fp = fopen("box.ms3d", "rb");

	// Temp buffer to store our data in, as we read it in
	char buf[256];


	// Lets read in the head information
	ms3d_header_t head;

	int r =			// The total number of items readed is returned.
	fread (	&head,		// void * buffer,
		sizeof(head),	// size
		1,		// count,
		fp );		// FILE * stream
	

	// Tricky bug!...check that our data isn't being padded!!
	dprintf("Check - sizeof(ms3d_header_t) == %d\n\n", sizeof(ms3d_header_t));

	//------------------------------------------------------------------------------
	// Log them to our debug txt file
	dprintf("ID: %c%c%c%c\n", 
			head.id[0], // 'M'
			head.id[1], // 'S'
			head.id[2], // '3'
			head.id[3]);// 'D'

	dprintf("Version: 0x%1X\n", head.version);

	//------------------------------------------------------------------------------

	// Read in the number of verts
	unsigned short nNumVertices;			
	fread (	&nNumVertices,			
			sizeof(unsigned short),	
			1,				
			fp );

	// Lets print out the number of vertices in this demo.
	dprintf("Num Vertices: %d\n", nNumVertices);

	//------------------------------------------------------------------------------

	// Read in the vertice data
	ms3d_vertex_t * verts = new ms3d_vertex_t[nNumVertices];

	fread (	verts,			
			sizeof (ms3d_vertex_t),	
			nNumVertices,				
			fp );

	// Just to check the data seems okay, we'll dump the x,y and z values to our
	// debug file
	for (int i=0; i<nNumVertices; i++)
	{
		dprintf("\t x:%.1f, y:%.1f, z:%.1f\n", 
			verts[i].vertex[0],	// x
			verts[i].vertex[1],	// y
			verts[i].vertex[2] ); 	// z
		
	}//End for(..)

	delete[] verts;
	//------------------------------------------------------------------------------

	// Read in the number of triangles
	unsigned short nNumTriangles;			
	fread (	&nNumTriangles,			
			sizeof(unsigned short),	
			1,				
			fp );

	// Lets print out the number of vertices in this demo.
	dprintf("\nNum Triangles: %d\n", nNumTriangles);

	//------------------------------------------------------------------------------

	// Read in all the triangle data
	ms3d_triangle_t * tris = new ms3d_triangle_t[nNumTriangles];

	fread (	tris,			
			sizeof (ms3d_triangle_t),	
			nNumTriangles,				
			fp );

	for (int i=0; i<nNumTriangles; i++)
	{
		// Get each vertex index that make up each face
		int a = tris[i].vertexIndices[0];
		int b = tris[i].vertexIndices[1];
		int c = tris[i].vertexIndices[2];

		// Write each face index to our debug file
		dprintf("\t a:%d, b:%d, c:%d\n", a, b, c);
	}

	delete[] tris;
	//------------------------------------------------------------------------------

	// Lets readin in the number of groups if there are any

	unsigned short nNumGroups;			
	fread (	&nNumGroups,			
			sizeof(unsigned short),	
			1,				
			fp );

	dprintf("\n\nNum Groups: %d\n", nNumGroups);
	
	//------------------------------------------------------------------------------

	// Of course now that we know how many groups there, are, we read them all in

	int groupDataSize = SIZE_MS3D_GROUP_DATA  +  nNumTriangles * sizeof(unsigned short);

	char * groupData = new char [groupDataSize * nNumGroups];

	ms3d_group_t * groups = (ms3d_group_t*)groupData;

	fread (	groups,			
			groupDataSize,	
			nNumGroups,				
			fp );

	for (int i=0; i<nNumGroups; i++)
	{
		// Write out some group info
		dprintf("\t Group Name: %s\n", groups[i].name);
		// Write each face index to our debug file
		dprintf("\t materialIndex: %d\n", groups[i].materialIndex);
	}

	delete[] groupData;

	//------------------------------------------------------------------------------

	// Lets readin in the number of materials if there are any

	unsigned short nNumMaterials;			
	fread (	&nNumMaterials,			
			sizeof(unsigned short),	
			1,				
			fp );

	dprintf("\n\nNum Materials: %d\n", nNumMaterials);

	//------------------------------------------------------------------------------

	// If we have any materials!!...
	if (nNumMaterials)
	{
		ms3d_material_t * mats = new ms3d_material_t[nNumMaterials];

		fread (	mats,			
				sizeof (ms3d_material_t),	
				nNumMaterials,				
				fp );

		for (int i=0; i<nNumMaterials; i++)
		{
			// Write out some group info

			// Write each face index to our debug file
			dprintf("\t diffuse r:%d, g:%d, b:%d, a:%d\n", 
					mats[i].diffuse[0],	// red
					mats[i].diffuse[1],	// green
					mats[i].diffuse[2],	// blue
					mats[i].diffuse[3]);	// alpha
		}
		delete[] mats;

	}// End if(..)


	dprintf("\n");

	//------------------------------------------------------------------------------

	// Close our File!
	fclose(fp);

	// Exit
	dprintf("Goodbye\n");
}

 

And if you run the above code, then it will generate an output debug file for you called output.txt, as in all the other demos, and below is the exciting contents of that file.  Which as you'll probably agree seem like reasonabe values for the 3d cube model that I've been using for testing.

 

Output.txt - Debug File Output
Welcome to the ms3d tutorial...

Check - sizeof(ms3d_header_t) == 14

ID: MS3D
Version: 0x4
Num Vertices: 8
x:-5.3, y:4.0, z:6.3
x:-5.3, y:-4.5, z:6.3
x:5.3, y:4.0, z:6.3
x:5.3, y:-4.5, z:6.3
x:5.3, y:4.0, z:-4.3
x:5.3, y:-4.5, z:-4.3
x:-5.3, y:4.0, z:-4.3
x:-5.3, y:-4.5, z:-4.3

Num Triangles: 12
a:0, b:1, c:2
a:1, b:3, c:2
a:2, b:3, c:4
a:3, b:5, c:4
a:4, b:5, c:6
a:5, b:7, c:6
a:6, b:7, c:0
a:7, b:1, c:0
a:6, b:0, c:4
a:0, b:2, c:4
a:1, b:7, c:3
a:7, b:5, c:3


Num Groups: 1
Group Name: Box01
materialIndex: 2


Num Materials: 0

Goodbye

 

 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.