X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=plugins%2Fmd3model%2Fmd3.cpp;h=e3db3ae7575ee58b96ec555a170b03fe60cc6143;hp=42fa37b63d49ceb3e092635d101e4c7ae4938a34;hb=e4287c28bb2dafedc81c66e63951d947cfbeb225;hpb=12b372f89ce109a4db9d510884fbe7d05af79870 diff --git a/plugins/md3model/md3.cpp b/plugins/md3model/md3.cpp index 42fa37b6..e3db3ae7 100644 --- a/plugins/md3model/md3.cpp +++ b/plugins/md3model/md3.cpp @@ -1,23 +1,23 @@ /* -Copyright (C) 2001-2006, William Joseph. -All Rights Reserved. + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "md3.h" @@ -32,69 +32,66 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "md3normals.h" // the maximum size of game reletive pathnames -#define MAX_QPATH 64 +#define MAX_QPATH 64 /* -======================================================================== + ======================================================================== -.MD3 triangle model file format + .MD3 triangle model file format -======================================================================== -*/ + ======================================================================== + */ const unsigned char MD3_IDENT[4] = { 'I', 'D', 'P', '3', }; -#define MD3_VERSION 15 +#define MD3_VERSION 15 // limits -#define MD3_MAX_LODS 4 -#define MD3_MAX_TRIANGLES 8192 // per surface -#define MD3_MAX_VERTS 4096 // per surface -#define MD3_MAX_SHADERS 256 // per surface -#define MD3_MAX_FRAMES 1024 // per model -#define MD3_MAX_SURFACES 32 // per model -#define MD3_MAX_TAGS 16 // per frame +#define MD3_MAX_LODS 4 +#define MD3_MAX_TRIANGLES 8192 // per surface +#define MD3_MAX_VERTS 4096 // per surface +#define MD3_MAX_SHADERS 256 // per surface +#define MD3_MAX_FRAMES 1024 // per model +#define MD3_MAX_SURFACES 32 // per model +#define MD3_MAX_TAGS 16 // per frame // vertex scales -#define MD3_XYZ_SCALE (1.f / 64) +#define MD3_XYZ_SCALE ( 1.f / 64 ) typedef float float3[3]; -void istream_read_float3(PointerInputStream& inputStream, float3 f) -{ - f[0] = istream_read_float32_le(inputStream); - f[1] = istream_read_float32_le(inputStream); - f[2] = istream_read_float32_le(inputStream); +void istream_read_float3( PointerInputStream& inputStream, float3 f ){ + f[0] = istream_read_float32_le( inputStream ); + f[1] = istream_read_float32_le( inputStream ); + f[2] = istream_read_float32_le( inputStream ); } typedef struct md3Frame_s { - float3 bounds[2]; - float3 localOrigin; - float radius; - char name[16]; + float3 bounds[2]; + float3 localOrigin; + float radius; + char name[16]; } md3Frame_t; -void istream_read_md3Frame(PointerInputStream& inputStream, md3Frame_t& frame) -{ - istream_read_float3(inputStream, frame.bounds[0]); - istream_read_float3(inputStream, frame.bounds[1]); - istream_read_float3(inputStream, frame.localOrigin); - frame.radius = istream_read_float32_le(inputStream); - inputStream.read(reinterpret_cast(frame.name), 16); +void istream_read_md3Frame( PointerInputStream& inputStream, md3Frame_t& frame ){ + istream_read_float3( inputStream, frame.bounds[0] ); + istream_read_float3( inputStream, frame.bounds[1] ); + istream_read_float3( inputStream, frame.localOrigin ); + frame.radius = istream_read_float32_le( inputStream ); + inputStream.read( reinterpret_cast( frame.name ), 16 ); } typedef struct md3Tag_s { - char name[MAX_QPATH]; // tag name - float3 origin; - float3 axis[3]; + char name[MAX_QPATH]; // tag name + float3 origin; + float3 axis[3]; } md3Tag_t; -void istream_read_md3Shader(PointerInputStream& inputStream, md3Tag_t& tag) -{ - inputStream.read(reinterpret_cast(tag.name), MAX_QPATH); - istream_read_float3(inputStream, tag.origin); - istream_read_float3(inputStream, tag.axis[0]); - istream_read_float3(inputStream, tag.axis[1]); - istream_read_float3(inputStream, tag.axis[2]); +void istream_read_md3Shader( PointerInputStream& inputStream, md3Tag_t& tag ){ + inputStream.read( reinterpret_cast( tag.name ), MAX_QPATH ); + istream_read_float3( inputStream, tag.origin ); + istream_read_float3( inputStream, tag.axis[0] ); + istream_read_float3( inputStream, tag.axis[1] ); + istream_read_float3( inputStream, tag.axis[2] ); } /* @@ -108,233 +105,219 @@ void istream_read_md3Shader(PointerInputStream& inputStream, md3Tag_t& tag) ** XyzNormals sizeof( md3XyzNormal_t ) * numVerts * numFrames */ typedef struct { - char ident[4]; // + char ident[4]; // - char name[MAX_QPATH]; // polyset name + char name[MAX_QPATH]; // polyset name - int flags; - int numFrames; // all surfaces in a model should have the same + int flags; + int numFrames; // all surfaces in a model should have the same - int numShaders; // all surfaces in a model should have the same - int numVerts; + int numShaders; // all surfaces in a model should have the same + int numVerts; - int numTriangles; - int ofsTriangles; + int numTriangles; + int ofsTriangles; - int ofsShaders; // offset from start of md3Surface_t - int ofsSt; // texture coords are common for all frames - int ofsXyzNormals; // numVerts * numFrames + int ofsShaders; // offset from start of md3Surface_t + int ofsSt; // texture coords are common for all frames + int ofsXyzNormals; // numVerts * numFrames - int ofsEnd; // next surface follows + int ofsEnd; // next surface follows } md3Surface_t; -void istream_read_md3Surface(PointerInputStream& inputStream, md3Surface_t& surface) -{ - inputStream.read(reinterpret_cast(surface.ident), 4); - inputStream.read(reinterpret_cast(surface.name), MAX_QPATH); - surface.flags = istream_read_int32_le(inputStream); - surface.numFrames = istream_read_int32_le(inputStream); - surface.numShaders = istream_read_int32_le(inputStream); - surface.numVerts = istream_read_int32_le(inputStream); - surface.numTriangles = istream_read_int32_le(inputStream); - surface.ofsTriangles = istream_read_int32_le(inputStream); - surface.ofsShaders = istream_read_int32_le(inputStream); - surface.ofsSt = istream_read_int32_le(inputStream); - surface.ofsXyzNormals = istream_read_int32_le(inputStream); - surface.ofsEnd = istream_read_int32_le(inputStream); +void istream_read_md3Surface( PointerInputStream& inputStream, md3Surface_t& surface ){ + inputStream.read( reinterpret_cast( surface.ident ), 4 ); + inputStream.read( reinterpret_cast( surface.name ), MAX_QPATH ); + surface.flags = istream_read_int32_le( inputStream ); + surface.numFrames = istream_read_int32_le( inputStream ); + surface.numShaders = istream_read_int32_le( inputStream ); + surface.numVerts = istream_read_int32_le( inputStream ); + surface.numTriangles = istream_read_int32_le( inputStream ); + surface.ofsTriangles = istream_read_int32_le( inputStream ); + surface.ofsShaders = istream_read_int32_le( inputStream ); + surface.ofsSt = istream_read_int32_le( inputStream ); + surface.ofsXyzNormals = istream_read_int32_le( inputStream ); + surface.ofsEnd = istream_read_int32_le( inputStream ); } typedef struct { - char name[MAX_QPATH]; - int shaderIndex; // for in-game use + char name[MAX_QPATH]; + int shaderIndex; // for in-game use } md3Shader_t; -void istream_read_md3Shader(PointerInputStream& inputStream, md3Shader_t& shader) -{ - inputStream.read(reinterpret_cast(shader.name), MAX_QPATH); - shader.shaderIndex = istream_read_int32_le(inputStream); +void istream_read_md3Shader( PointerInputStream& inputStream, md3Shader_t& shader ){ + inputStream.read( reinterpret_cast( shader.name ), MAX_QPATH ); + shader.shaderIndex = istream_read_int32_le( inputStream ); } typedef struct { - int indexes[3]; + int indexes[3]; } md3Triangle_t; -void istream_read_md3Triangle(PointerInputStream& inputStream, md3Triangle_t& triangle) -{ - triangle.indexes[0] = istream_read_int32_le(inputStream); - triangle.indexes[1] = istream_read_int32_le(inputStream); - triangle.indexes[2] = istream_read_int32_le(inputStream); +void istream_read_md3Triangle( PointerInputStream& inputStream, md3Triangle_t& triangle ){ + triangle.indexes[0] = istream_read_int32_le( inputStream ); + triangle.indexes[1] = istream_read_int32_le( inputStream ); + triangle.indexes[2] = istream_read_int32_le( inputStream ); } typedef struct { - float st[2]; + float st[2]; } md3St_t; -void istream_read_md3St(PointerInputStream& inputStream, md3St_t& st) -{ - st.st[0] = istream_read_float32_le(inputStream); - st.st[1] = istream_read_float32_le(inputStream); +void istream_read_md3St( PointerInputStream& inputStream, md3St_t& st ){ + st.st[0] = istream_read_float32_le( inputStream ); + st.st[1] = istream_read_float32_le( inputStream ); } typedef struct { - short xyz[3]; - short normal; + short xyz[3]; + short normal; } md3XyzNormal_t; -void istream_read_md3XyzNormal(PointerInputStream& inputStream, md3XyzNormal_t& xyz) -{ - xyz.xyz[0] = istream_read_int16_le(inputStream); - xyz.xyz[1] = istream_read_int16_le(inputStream); - xyz.xyz[2] = istream_read_int16_le(inputStream); - xyz.normal = istream_read_int16_le(inputStream); +void istream_read_md3XyzNormal( PointerInputStream& inputStream, md3XyzNormal_t& xyz ){ + xyz.xyz[0] = istream_read_int16_le( inputStream ); + xyz.xyz[1] = istream_read_int16_le( inputStream ); + xyz.xyz[2] = istream_read_int16_le( inputStream ); + xyz.normal = istream_read_int16_le( inputStream ); } typedef struct { - char ident[4]; - int version; + char ident[4]; + int version; - char name[MAX_QPATH]; // model name + char name[MAX_QPATH]; // model name - int flags; + int flags; - int numFrames; - int numTags; - int numSurfaces; + int numFrames; + int numTags; + int numSurfaces; - int numSkins; + int numSkins; - int ofsFrames; // offset for first frame - int ofsTags; // numFrames * numTags - int ofsSurfaces; // first surface, others follow + int ofsFrames; // offset for first frame + int ofsTags; // numFrames * numTags + int ofsSurfaces; // first surface, others follow - int ofsEnd; // end of file + int ofsEnd; // end of file } md3Header_t; -void istream_read_md3Header(PointerInputStream& inputStream, md3Header_t& header) -{ - inputStream.read(reinterpret_cast(header.ident), 4); - header.version = istream_read_int32_le(inputStream); - inputStream.read(reinterpret_cast(header.name), MAX_QPATH); - header.flags = istream_read_int32_le(inputStream); - header.numFrames = istream_read_int32_le(inputStream); - header.numTags = istream_read_int32_le(inputStream); - header.numSurfaces = istream_read_int32_le(inputStream); - header.numSkins = istream_read_int32_le(inputStream); - header.ofsFrames = istream_read_int32_le(inputStream); - header.ofsTags = istream_read_int32_le(inputStream); - header.ofsSurfaces = istream_read_int32_le(inputStream); - header.ofsEnd = istream_read_int32_le(inputStream); +void istream_read_md3Header( PointerInputStream& inputStream, md3Header_t& header ){ + inputStream.read( reinterpret_cast( header.ident ), 4 ); + header.version = istream_read_int32_le( inputStream ); + inputStream.read( reinterpret_cast( header.name ), MAX_QPATH ); + header.flags = istream_read_int32_le( inputStream ); + header.numFrames = istream_read_int32_le( inputStream ); + header.numTags = istream_read_int32_le( inputStream ); + header.numSurfaces = istream_read_int32_le( inputStream ); + header.numSkins = istream_read_int32_le( inputStream ); + header.ofsFrames = istream_read_int32_le( inputStream ); + header.ofsTags = istream_read_int32_le( inputStream ); + header.ofsSurfaces = istream_read_int32_le( inputStream ); + header.ofsEnd = istream_read_int32_le( inputStream ); } -int MD3Surface_read(Surface& surface, unsigned char* buffer) -{ +int MD3Surface_read( Surface& surface, unsigned char* buffer ){ md3Surface_t md3Surface; - { - PointerInputStream inputStream(buffer); - istream_read_md3Surface(inputStream, md3Surface); - } - - { - surface.vertices().reserve(md3Surface.numVerts); - - PointerInputStream xyzNormalStream(buffer + md3Surface.ofsXyzNormals); - PointerInputStream stStream(buffer + md3Surface.ofsSt); - - // read verts into vertex array - xyz, st, normal - for(int i = 0; i < md3Surface.numVerts; i++) - { - md3XyzNormal_t md3Xyz; - istream_read_md3XyzNormal(xyzNormalStream, md3Xyz); - - md3St_t md3St; - istream_read_md3St(stStream, md3St); - - surface.vertices().push_back( - ArbitraryMeshVertex( - Vertex3f( md3Xyz.xyz[0] * MD3_XYZ_SCALE, md3Xyz.xyz[1] * MD3_XYZ_SCALE, md3Xyz.xyz[2] * MD3_XYZ_SCALE), - DecodeNormal(reinterpret_cast(&md3Xyz.normal)), - TexCoord2f(md3St.st[0], md3St.st[1]) - ) - ); - } - } - - { - surface.indices().reserve(md3Surface.numTriangles * 3); - - PointerInputStream inputStream(buffer + md3Surface.ofsTriangles); - for(int i = 0; i < md3Surface.numTriangles; i++) - { - md3Triangle_t md3Triangle; - istream_read_md3Triangle(inputStream, md3Triangle); - surface.indices().insert(md3Triangle.indexes[0]); - surface.indices().insert(md3Triangle.indexes[1]); - surface.indices().insert(md3Triangle.indexes[2]); - } - } - - { - md3Shader_t md3Shader; - { - PointerInputStream inputStream(buffer + md3Surface.ofsShaders); - istream_read_md3Shader(inputStream, md3Shader); - } - surface.setShader(md3Shader.name); - } - + { + PointerInputStream inputStream( buffer ); + istream_read_md3Surface( inputStream, md3Surface ); + } + + { + surface.vertices().reserve( md3Surface.numVerts ); + + PointerInputStream xyzNormalStream( buffer + md3Surface.ofsXyzNormals ); + PointerInputStream stStream( buffer + md3Surface.ofsSt ); + + // read verts into vertex array - xyz, st, normal + for ( int i = 0; i < md3Surface.numVerts; i++ ) + { + md3XyzNormal_t md3Xyz; + istream_read_md3XyzNormal( xyzNormalStream, md3Xyz ); + + md3St_t md3St; + istream_read_md3St( stStream, md3St ); + + surface.vertices().push_back( + ArbitraryMeshVertex( + Vertex3f( md3Xyz.xyz[0] * MD3_XYZ_SCALE, md3Xyz.xyz[1] * MD3_XYZ_SCALE, md3Xyz.xyz[2] * MD3_XYZ_SCALE ), + DecodeNormal( reinterpret_cast( &md3Xyz.normal ) ), + TexCoord2f( md3St.st[0], md3St.st[1] ) + ) + ); + } + } + + { + surface.indices().reserve( md3Surface.numTriangles * 3 ); + + PointerInputStream inputStream( buffer + md3Surface.ofsTriangles ); + for ( int i = 0; i < md3Surface.numTriangles; i++ ) + { + md3Triangle_t md3Triangle; + istream_read_md3Triangle( inputStream, md3Triangle ); + surface.indices().insert( md3Triangle.indexes[0] ); + surface.indices().insert( md3Triangle.indexes[1] ); + surface.indices().insert( md3Triangle.indexes[2] ); + } + } + + { + md3Shader_t md3Shader; + { + PointerInputStream inputStream( buffer + md3Surface.ofsShaders ); + istream_read_md3Shader( inputStream, md3Shader ); + } + surface.setShader( md3Shader.name ); + } + surface.updateAABB(); - return md3Surface.ofsEnd; + return md3Surface.ofsEnd; } -void MD3Model_read(Model& model, unsigned char* buffer) -{ - md3Header_t md3Header; - { - PointerInputStream inputStream(buffer); - istream_read_md3Header(inputStream, md3Header); - } +void MD3Model_read( Model& model, unsigned char* buffer ){ + md3Header_t md3Header; + { + PointerInputStream inputStream( buffer ); + istream_read_md3Header( inputStream, md3Header ); + } - unsigned char* surfacePosition = buffer + md3Header.ofsSurfaces; + unsigned char* surfacePosition = buffer + md3Header.ofsSurfaces; - for(int i = 0; i != md3Header.numSurfaces; ++i) + for ( int i = 0; i != md3Header.numSurfaces; ++i ) { - surfacePosition += MD3Surface_read(model.newSurface(), surfacePosition); - } + surfacePosition += MD3Surface_read( model.newSurface(), surfacePosition ); + } - model.updateAABB(); + model.updateAABB(); } -scene::Node& MD3Model_new(unsigned char* buffer) -{ - ModelNode* modelNode = new ModelNode(); - MD3Model_read(modelNode->model(), buffer); - return modelNode->node(); +scene::Node& MD3Model_new( unsigned char* buffer ){ + ModelNode* modelNode = new ModelNode(); + MD3Model_read( modelNode->model(), buffer ); + return modelNode->node(); } -scene::Node& MD3Model_default() -{ - ModelNode* modelNode = new ModelNode(); - Model_constructNull(modelNode->model()); - return modelNode->node(); +scene::Node& MD3Model_default(){ + ModelNode* modelNode = new ModelNode(); + Model_constructNull( modelNode->model() ); + return modelNode->node(); } -scene::Node& MD3Model_fromBuffer(unsigned char* buffer) -{ - if (!ident_equal(buffer, MD3_IDENT)) - { - globalErrorStream() << "MD3 read error: incorrect ident\n"; - return MD3Model_default(); - } - else - { - return MD3Model_new(buffer); - } +scene::Node& MD3Model_fromBuffer( unsigned char* buffer ){ + if ( !ident_equal( buffer, MD3_IDENT ) ) { + globalErrorStream() << "MD3 read error: incorrect ident\n"; + return MD3Model_default(); + } + else + { + return MD3Model_new( buffer ); + } } -scene::Node& loadMD3Model(ArchiveFile& file) -{ - ScopedArchiveBuffer buffer(file); - return MD3Model_fromBuffer(buffer.buffer); +scene::Node& loadMD3Model( ArchiveFile& file ){ + ScopedArchiveBuffer buffer( file ); + return MD3Model_fromBuffer( buffer.buffer ); } -