00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "wmesh.h"
00025
00026
00027
00028
00029 #ifdef _MSC_VER
00030 #pragma pack( push, packing )
00031 #pragma pack( 1 )
00032 #define PACK_STRUCT
00033 #ifndef PATH_MAX
00034 #define PATH_MAX _MAX_PATH
00035 #endif
00036 #elif defined( __GNUC__ )
00037 #define PACK_STRUCT __attribute__((packed))
00038 #include <limits.h>
00039 #else
00040 #error you must byte-align these structures with the appropriate compiler directives
00041 #endif
00042
00043 namespace farsa {
00044
00045 typedef unsigned char byte;
00046 typedef unsigned short word;
00047
00048 struct MS3DHeader {
00049 char m_ID[10];
00050 int m_version;
00051 } PACK_STRUCT;
00052
00053 struct MS3DVertex {
00054 byte m_flags;
00055 float m_vertex[3];
00056 char m_boneID;
00057 byte m_refCount;
00058 } PACK_STRUCT;
00059
00060 struct MS3DTriangle {
00061 word m_flags;
00062 word m_vertexIndices[3];
00063 float m_vertexNormals[3][3];
00064 float m_s[3], m_t[3];
00065 byte m_smoothingGroup;
00066 byte m_groupIndex;
00067 } PACK_STRUCT;
00068
00069 struct MS3DMaterial {
00070 static unsigned int Texture[15];
00071 char m_name[32];
00072 float m_ambient[4];
00073 float m_diffuse[4];
00074 float m_specular[4];
00075 float m_emissive[4];
00076 float m_shininess;
00077 float m_transparency;
00078 byte m_mode;
00079 char m_texture[128];
00080 char m_alphamap[128];
00081 } PACK_STRUCT;
00082
00083 #ifdef _MSC_VER
00084 #pragma pack( pop, packing )
00085 #endif
00086 #undef PACK_STRUCT
00087
00088
00089
00090 }
00091
00092 #include "string.h"
00093 #include <QString>
00094 #include <QFile>
00095 #include <QImage>
00096
00097 namespace farsa {
00098
00099 WMesh::WMesh( World* world, QString name, const wMatrix& tm)
00100 : WObject( world, name, tm, false ) {
00101 m_numMeshes = 0;
00102 m_pMeshes = NULL;
00103 m_numMaterials = 0;
00104 m_pMaterials = NULL;
00105 m_numTriangles = 0;
00106 m_pTriangles = NULL;
00107 m_numVertices = 0;
00108 m_pVertices = NULL;
00109 attacho = NULL;
00110 world->pushObject( this );
00111 }
00112
00113 WMesh::~WMesh() {
00114 int i;
00115 for ( i = 0; i < m_numMeshes; i++ ) {
00116 delete[] m_pMeshes[i].m_pTriangleIndices;
00117 }
00118 m_numMeshes = 0;
00119 if ( m_pMeshes != NULL ) {
00120 delete[] m_pMeshes;
00121 m_pMeshes = NULL;
00122 }
00123 m_numMaterials = 0;
00124 if ( m_pMaterials != NULL ) {
00125 delete[] m_pMaterials;
00126 m_pMaterials = NULL;
00127 }
00128 m_numTriangles = 0;
00129 if ( m_pTriangles != NULL ) {
00130 delete[] m_pTriangles;
00131 m_pTriangles = NULL;
00132 }
00133 m_numVertices = 0;
00134 if ( m_pVertices != NULL ) {
00135 delete[] m_pVertices;
00136 m_pVertices = NULL;
00137 }
00138 }
00139
00140 void WMesh::attachTo( WObject* obj ) {
00141 this->attacho = obj;
00142 }
00143
00144 bool WMesh::loadMS3DModel( QString filename ) {
00145 QFile inputFile( filename );
00146 if ( !inputFile.open( QIODevice::ReadOnly ) ) {
00147 return false;
00148 }
00149 QByteArray bBuffer = inputFile.readAll();
00150 const char *pPtr = bBuffer.data();
00151 MS3DHeader *pHeader = ( MS3DHeader* )pPtr;
00152 pPtr += sizeof( MS3DHeader );
00153 if ( strncmp( pHeader->m_ID, "MS3D000000", 10 ) != 0 ) {
00154
00155 return false;
00156 }
00157 if ( pHeader->m_version < 3 ) {
00158
00159 return false;
00160 }
00161 int nVertices = *( word* )pPtr;
00162 m_numVertices = nVertices;
00163 m_pVertices = new Vertex[nVertices];
00164 pPtr += sizeof( word );
00165 int i;
00166 for ( i = 0; i < nVertices; i++ ) {
00167 MS3DVertex *pVertex = ( MS3DVertex* )pPtr;
00168 m_pVertices[i].m_boneID = pVertex->m_boneID;
00169 memcpy( m_pVertices[i].m_location, pVertex->m_vertex, sizeof( float )*3 );
00170 pPtr += sizeof( MS3DVertex );
00171 }
00172 int nTriangles = *( word* )pPtr;
00173 m_numTriangles = nTriangles;
00174 m_pTriangles = new Triangle[nTriangles];
00175 pPtr += sizeof( word );
00176 for ( i = 0; i < nTriangles; i++ ) {
00177 MS3DTriangle *pTriangle = ( MS3DTriangle* )pPtr;
00178 int vertexIndices[3] = { pTriangle->m_vertexIndices[0], pTriangle->m_vertexIndices[1], pTriangle->m_vertexIndices[2] };
00179 float t[3] = { 1.0f-pTriangle->m_t[0], 1.0f-pTriangle->m_t[1], 1.0f-pTriangle->m_t[2] };
00180 memcpy( m_pTriangles[i].m_vertexNormals, pTriangle->m_vertexNormals, sizeof( float )*3*3 );
00181 memcpy( m_pTriangles[i].m_s, pTriangle->m_s, sizeof( float )*3 );
00182 memcpy( m_pTriangles[i].m_t, t, sizeof( float )*3 );
00183 memcpy( m_pTriangles[i].m_vertexIndices, vertexIndices, sizeof( int )*3 );
00184 pPtr += sizeof( MS3DTriangle );
00185 }
00186 int nGroups = *( word* )pPtr;
00187 m_numMeshes = nGroups;
00188 m_pMeshes = new Mesh[nGroups];
00189 pPtr += sizeof( word );
00190 for ( i = 0; i < nGroups; i++ ) {
00191 pPtr += sizeof( byte );
00192 pPtr += 32;
00193 word nTriangles = *( word* )pPtr;
00194 pPtr += sizeof( word );
00195 int *pTriangleIndices = new int[nTriangles];
00196 for ( int j = 0; j < nTriangles; j++ ) {
00197 pTriangleIndices[j] = *( word* )pPtr;
00198 pPtr += sizeof( word );
00199 }
00200 char materialIndex = *( char* )pPtr;
00201 pPtr += sizeof( char );
00202 m_pMeshes[i].m_materialIndex = materialIndex;
00203 m_pMeshes[i].m_numTriangles = nTriangles;
00204 m_pMeshes[i].m_pTriangleIndices = pTriangleIndices;
00205 }
00206 int nMaterials = *( word* )pPtr;
00207 m_numMaterials = nMaterials;
00208 m_pMaterials = new Material[nMaterials];
00209 pPtr += sizeof( word );
00210 for ( i = 0; i < nMaterials; i++ ) {
00211 MS3DMaterial *pMaterial = ( MS3DMaterial* )pPtr;
00212 memcpy( m_pMaterials[i].m_ambient, pMaterial->m_ambient, sizeof( float )*4 );
00213 memcpy( m_pMaterials[i].m_diffuse, pMaterial->m_diffuse, sizeof( float )*4 );
00214 memcpy( m_pMaterials[i].m_specular, pMaterial->m_specular, sizeof( float )*4 );
00215 memcpy( m_pMaterials[i].m_emissive, pMaterial->m_emissive, sizeof( float )*4 );
00216 m_pMaterials[i].m_shininess = pMaterial->m_shininess;
00217 m_pMaterials[i].m_pTextureFilename = QString( pMaterial->m_texture );
00218 pPtr += sizeof( MS3DMaterial );
00219 }
00220 return true;
00221 }
00222
00223 }