-/* -----------------------------------------------------------------------------\r
-\r
-PicoModel Library \r
-\r
-Copyright (c) 2002, Randy Reddig & seaw0lf\r
-All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without modification,\r
-are permitted provided that the following conditions are met:\r
-\r
-Redistributions of source code must retain the above copyright notice, this list\r
-of conditions and the following disclaimer.\r
-\r
-Redistributions in binary form must reproduce the above copyright notice, this\r
-list of conditions and the following disclaimer in the documentation and/or\r
-other materials provided with the distribution.\r
-\r
-Neither the names of the copyright holders nor the names of its contributors may\r
-be used to endorse or promote products derived from this software without\r
-specific prior written permission. \r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\r
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
------------------------------------------------------------------------------ */\r
-\r
-\r
-\r
-/* marker */\r
-#define PM_MDC_C\r
-\r
-\r
-\r
-/* dependencies */\r
-#include "picointernal.h"\r
-\r
-/* mdc model format */\r
-#define MDC_MAGIC "IDPC"\r
-#define MDC_VERSION 2\r
-\r
-/* mdc vertex scale */\r
-#define MDC_SCALE (1.0f / 64.0f)\r
-#define MDC_MAX_OFS 127.0f\r
-#define MDC_DIST_SCALE 0.05f\r
-\r
-/* mdc decoding normal table */\r
-double mdcNormals[ 256 ][ 3 ] =\r
-{\r
- { 1.000000, 0.000000, 0.000000 },\r
- { 0.980785, 0.195090, 0.000000 },\r
- { 0.923880, 0.382683, 0.000000 },\r
- { 0.831470, 0.555570, 0.000000 },\r
- { 0.707107, 0.707107, 0.000000 },\r
- { 0.555570, 0.831470, 0.000000 },\r
- { 0.382683, 0.923880, 0.000000 },\r
- { 0.195090, 0.980785, 0.000000 },\r
- { -0.000000, 1.000000, 0.000000 },\r
- { -0.195090, 0.980785, 0.000000 },\r
- { -0.382683, 0.923880, 0.000000 },\r
- { -0.555570, 0.831470, 0.000000 },\r
- { -0.707107, 0.707107, 0.000000 },\r
- { -0.831470, 0.555570, 0.000000 },\r
- { -0.923880, 0.382683, 0.000000 },\r
- { -0.980785, 0.195090, 0.000000 },\r
- { -1.000000, -0.000000, 0.000000 },\r
- { -0.980785, -0.195090, 0.000000 },\r
- { -0.923880, -0.382683, 0.000000 },\r
- { -0.831470, -0.555570, 0.000000 },\r
- { -0.707107, -0.707107, 0.000000 },\r
- { -0.555570, -0.831469, 0.000000 },\r
- { -0.382684, -0.923880, 0.000000 },\r
- { -0.195090, -0.980785, 0.000000 },\r
- { 0.000000, -1.000000, 0.000000 },\r
- { 0.195090, -0.980785, 0.000000 },\r
- { 0.382684, -0.923879, 0.000000 },\r
- { 0.555570, -0.831470, 0.000000 },\r
- { 0.707107, -0.707107, 0.000000 },\r
- { 0.831470, -0.555570, 0.000000 },\r
- { 0.923880, -0.382683, 0.000000 },\r
- { 0.980785, -0.195090, 0.000000 },\r
- { 0.980785, 0.000000, -0.195090 },\r
- { 0.956195, 0.218245, -0.195090 },\r
- { 0.883657, 0.425547, -0.195090 },\r
- { 0.766809, 0.611510, -0.195090 },\r
- { 0.611510, 0.766809, -0.195090 },\r
- { 0.425547, 0.883657, -0.195090 },\r
- { 0.218245, 0.956195, -0.195090 },\r
- { -0.000000, 0.980785, -0.195090 },\r
- { -0.218245, 0.956195, -0.195090 },\r
- { -0.425547, 0.883657, -0.195090 },\r
- { -0.611510, 0.766809, -0.195090 },\r
- { -0.766809, 0.611510, -0.195090 },\r
- { -0.883657, 0.425547, -0.195090 },\r
- { -0.956195, 0.218245, -0.195090 },\r
- { -0.980785, -0.000000, -0.195090 },\r
- { -0.956195, -0.218245, -0.195090 },\r
- { -0.883657, -0.425547, -0.195090 },\r
- { -0.766809, -0.611510, -0.195090 },\r
- { -0.611510, -0.766809, -0.195090 },\r
- { -0.425547, -0.883657, -0.195090 },\r
- { -0.218245, -0.956195, -0.195090 },\r
- { 0.000000, -0.980785, -0.195090 },\r
- { 0.218245, -0.956195, -0.195090 },\r
- { 0.425547, -0.883657, -0.195090 },\r
- { 0.611510, -0.766809, -0.195090 },\r
- { 0.766809, -0.611510, -0.195090 },\r
- { 0.883657, -0.425547, -0.195090 },\r
- { 0.956195, -0.218245, -0.195090 },\r
- { 0.923880, 0.000000, -0.382683 },\r
- { 0.892399, 0.239118, -0.382683 },\r
- { 0.800103, 0.461940, -0.382683 },\r
- { 0.653281, 0.653281, -0.382683 },\r
- { 0.461940, 0.800103, -0.382683 },\r
- { 0.239118, 0.892399, -0.382683 },\r
- { -0.000000, 0.923880, -0.382683 },\r
- { -0.239118, 0.892399, -0.382683 },\r
- { -0.461940, 0.800103, -0.382683 },\r
- { -0.653281, 0.653281, -0.382683 },\r
- { -0.800103, 0.461940, -0.382683 },\r
- { -0.892399, 0.239118, -0.382683 },\r
- { -0.923880, -0.000000, -0.382683 },\r
- { -0.892399, -0.239118, -0.382683 },\r
- { -0.800103, -0.461940, -0.382683 },\r
- { -0.653282, -0.653281, -0.382683 },\r
- { -0.461940, -0.800103, -0.382683 },\r
- { -0.239118, -0.892399, -0.382683 },\r
- { 0.000000, -0.923880, -0.382683 },\r
- { 0.239118, -0.892399, -0.382683 },\r
- { 0.461940, -0.800103, -0.382683 },\r
- { 0.653281, -0.653282, -0.382683 },\r
- { 0.800103, -0.461940, -0.382683 },\r
- { 0.892399, -0.239117, -0.382683 },\r
- { 0.831470, 0.000000, -0.555570 },\r
- { 0.790775, 0.256938, -0.555570 },\r
- { 0.672673, 0.488726, -0.555570 },\r
- { 0.488726, 0.672673, -0.555570 },\r
- { 0.256938, 0.790775, -0.555570 },\r
- { -0.000000, 0.831470, -0.555570 },\r
- { -0.256938, 0.790775, -0.555570 },\r
- { -0.488726, 0.672673, -0.555570 },\r
- { -0.672673, 0.488726, -0.555570 },\r
- { -0.790775, 0.256938, -0.555570 },\r
- { -0.831470, -0.000000, -0.555570 },\r
- { -0.790775, -0.256938, -0.555570 },\r
- { -0.672673, -0.488726, -0.555570 },\r
- { -0.488725, -0.672673, -0.555570 },\r
- { -0.256938, -0.790775, -0.555570 },\r
- { 0.000000, -0.831470, -0.555570 },\r
- { 0.256938, -0.790775, -0.555570 },\r
- { 0.488725, -0.672673, -0.555570 },\r
- { 0.672673, -0.488726, -0.555570 },\r
- { 0.790775, -0.256938, -0.555570 },\r
- { 0.707107, 0.000000, -0.707107 },\r
- { 0.653281, 0.270598, -0.707107 },\r
- { 0.500000, 0.500000, -0.707107 },\r
- { 0.270598, 0.653281, -0.707107 },\r
- { -0.000000, 0.707107, -0.707107 },\r
- { -0.270598, 0.653282, -0.707107 },\r
- { -0.500000, 0.500000, -0.707107 },\r
- { -0.653281, 0.270598, -0.707107 },\r
- { -0.707107, -0.000000, -0.707107 },\r
- { -0.653281, -0.270598, -0.707107 },\r
- { -0.500000, -0.500000, -0.707107 },\r
- { -0.270598, -0.653281, -0.707107 },\r
- { 0.000000, -0.707107, -0.707107 },\r
- { 0.270598, -0.653281, -0.707107 },\r
- { 0.500000, -0.500000, -0.707107 },\r
- { 0.653282, -0.270598, -0.707107 },\r
- { 0.555570, 0.000000, -0.831470 },\r
- { 0.481138, 0.277785, -0.831470 },\r
- { 0.277785, 0.481138, -0.831470 },\r
- { -0.000000, 0.555570, -0.831470 },\r
- { -0.277785, 0.481138, -0.831470 },\r
- { -0.481138, 0.277785, -0.831470 },\r
- { -0.555570, -0.000000, -0.831470 },\r
- { -0.481138, -0.277785, -0.831470 },\r
- { -0.277785, -0.481138, -0.831470 },\r
- { 0.000000, -0.555570, -0.831470 },\r
- { 0.277785, -0.481138, -0.831470 },\r
- { 0.481138, -0.277785, -0.831470 },\r
- { 0.382683, 0.000000, -0.923880 },\r
- { 0.270598, 0.270598, -0.923880 },\r
- { -0.000000, 0.382683, -0.923880 },\r
- { -0.270598, 0.270598, -0.923880 },\r
- { -0.382683, -0.000000, -0.923880 },\r
- { -0.270598, -0.270598, -0.923880 },\r
- { 0.000000, -0.382683, -0.923880 },\r
- { 0.270598, -0.270598, -0.923880 },\r
- { 0.195090, 0.000000, -0.980785 },\r
- { -0.000000, 0.195090, -0.980785 },\r
- { -0.195090, -0.000000, -0.980785 },\r
- { 0.000000, -0.195090, -0.980785 },\r
- { 0.980785, 0.000000, 0.195090 },\r
- { 0.956195, 0.218245, 0.195090 },\r
- { 0.883657, 0.425547, 0.195090 },\r
- { 0.766809, 0.611510, 0.195090 },\r
- { 0.611510, 0.766809, 0.195090 },\r
- { 0.425547, 0.883657, 0.195090 },\r
- { 0.218245, 0.956195, 0.195090 },\r
- { -0.000000, 0.980785, 0.195090 },\r
- { -0.218245, 0.956195, 0.195090 },\r
- { -0.425547, 0.883657, 0.195090 },\r
- { -0.611510, 0.766809, 0.195090 },\r
- { -0.766809, 0.611510, 0.195090 },\r
- { -0.883657, 0.425547, 0.195090 },\r
- { -0.956195, 0.218245, 0.195090 },\r
- { -0.980785, -0.000000, 0.195090 },\r
- { -0.956195, -0.218245, 0.195090 },\r
- { -0.883657, -0.425547, 0.195090 },\r
- { -0.766809, -0.611510, 0.195090 },\r
- { -0.611510, -0.766809, 0.195090 },\r
- { -0.425547, -0.883657, 0.195090 },\r
- { -0.218245, -0.956195, 0.195090 },\r
- { 0.000000, -0.980785, 0.195090 },\r
- { 0.218245, -0.956195, 0.195090 },\r
- { 0.425547, -0.883657, 0.195090 },\r
- { 0.611510, -0.766809, 0.195090 },\r
- { 0.766809, -0.611510, 0.195090 },\r
- { 0.883657, -0.425547, 0.195090 },\r
- { 0.956195, -0.218245, 0.195090 },\r
- { 0.923880, 0.000000, 0.382683 },\r
- { 0.892399, 0.239118, 0.382683 },\r
- { 0.800103, 0.461940, 0.382683 },\r
- { 0.653281, 0.653281, 0.382683 },\r
- { 0.461940, 0.800103, 0.382683 },\r
- { 0.239118, 0.892399, 0.382683 },\r
- { -0.000000, 0.923880, 0.382683 },\r
- { -0.239118, 0.892399, 0.382683 },\r
- { -0.461940, 0.800103, 0.382683 },\r
- { -0.653281, 0.653281, 0.382683 },\r
- { -0.800103, 0.461940, 0.382683 },\r
- { -0.892399, 0.239118, 0.382683 },\r
- { -0.923880, -0.000000, 0.382683 },\r
- { -0.892399, -0.239118, 0.382683 },\r
- { -0.800103, -0.461940, 0.382683 },\r
- { -0.653282, -0.653281, 0.382683 },\r
- { -0.461940, -0.800103, 0.382683 },\r
- { -0.239118, -0.892399, 0.382683 },\r
- { 0.000000, -0.923880, 0.382683 },\r
- { 0.239118, -0.892399, 0.382683 },\r
- { 0.461940, -0.800103, 0.382683 },\r
- { 0.653281, -0.653282, 0.382683 },\r
- { 0.800103, -0.461940, 0.382683 },\r
- { 0.892399, -0.239117, 0.382683 },\r
- { 0.831470, 0.000000, 0.555570 },\r
- { 0.790775, 0.256938, 0.555570 },\r
- { 0.672673, 0.488726, 0.555570 },\r
- { 0.488726, 0.672673, 0.555570 },\r
- { 0.256938, 0.790775, 0.555570 },\r
- { -0.000000, 0.831470, 0.555570 },\r
- { -0.256938, 0.790775, 0.555570 },\r
- { -0.488726, 0.672673, 0.555570 },\r
- { -0.672673, 0.488726, 0.555570 },\r
- { -0.790775, 0.256938, 0.555570 },\r
- { -0.831470, -0.000000, 0.555570 },\r
- { -0.790775, -0.256938, 0.555570 },\r
- { -0.672673, -0.488726, 0.555570 },\r
- { -0.488725, -0.672673, 0.555570 },\r
- { -0.256938, -0.790775, 0.555570 },\r
- { 0.000000, -0.831470, 0.555570 },\r
- { 0.256938, -0.790775, 0.555570 },\r
- { 0.488725, -0.672673, 0.555570 },\r
- { 0.672673, -0.488726, 0.555570 },\r
- { 0.790775, -0.256938, 0.555570 },\r
- { 0.707107, 0.000000, 0.707107 },\r
- { 0.653281, 0.270598, 0.707107 },\r
- { 0.500000, 0.500000, 0.707107 },\r
- { 0.270598, 0.653281, 0.707107 },\r
- { -0.000000, 0.707107, 0.707107 },\r
- { -0.270598, 0.653282, 0.707107 },\r
- { -0.500000, 0.500000, 0.707107 },\r
- { -0.653281, 0.270598, 0.707107 },\r
- { -0.707107, -0.000000, 0.707107 },\r
- { -0.653281, -0.270598, 0.707107 },\r
- { -0.500000, -0.500000, 0.707107 },\r
- { -0.270598, -0.653281, 0.707107 },\r
- { 0.000000, -0.707107, 0.707107 },\r
- { 0.270598, -0.653281, 0.707107 },\r
- { 0.500000, -0.500000, 0.707107 },\r
- { 0.653282, -0.270598, 0.707107 },\r
- { 0.555570, 0.000000, 0.831470 },\r
- { 0.481138, 0.277785, 0.831470 },\r
- { 0.277785, 0.481138, 0.831470 },\r
- { -0.000000, 0.555570, 0.831470 },\r
- { -0.277785, 0.481138, 0.831470 },\r
- { -0.481138, 0.277785, 0.831470 },\r
- { -0.555570, -0.000000, 0.831470 },\r
- { -0.481138, -0.277785, 0.831470 },\r
- { -0.277785, -0.481138, 0.831470 },\r
- { 0.000000, -0.555570, 0.831470 },\r
- { 0.277785, -0.481138, 0.831470 },\r
- { 0.481138, -0.277785, 0.831470 },\r
- { 0.382683, 0.000000, 0.923880 },\r
- { 0.270598, 0.270598, 0.923880 },\r
- { -0.000000, 0.382683, 0.923880 },\r
- { -0.270598, 0.270598, 0.923880 },\r
- { -0.382683, -0.000000, 0.923880 },\r
- { -0.270598, -0.270598, 0.923880 },\r
- { 0.000000, -0.382683, 0.923880 },\r
- { 0.270598, -0.270598, 0.923880 },\r
- { 0.195090, 0.000000, 0.980785 },\r
- { -0.000000, 0.195090, 0.980785 },\r
- { -0.195090, -0.000000, 0.980785 },\r
- { 0.000000, -0.195090, 0.980785 }\r
-};\r
-\r
-/* mdc model frame information */\r
-typedef struct mdcFrame_s\r
-{\r
- float bounds[ 2 ][ 3 ];\r
- float localOrigin[ 3 ];\r
- float radius;\r
- char creator[ 16 ];\r
-}\r
-mdcFrame_t;\r
-\r
-/* mdc model tag information */\r
-typedef struct mdcTag_s\r
-{\r
- short xyz[3];\r
- short angles[3];\r
-}\r
-mdcTag_t;\r
-\r
-/* mdc surface mdc (one object mesh) */\r
-typedef struct mdcSurface_s\r
-{\r
- char magic[ 4 ];\r
- char name[ 64 ]; /* polyset name */\r
- int flags;\r
- int numCompFrames; /* all surfaces in a model should have the same */\r
- int numBaseFrames; /* ditto */\r
- int numShaders; /* all model surfaces should have the same */\r
- int numVerts;\r
- int numTriangles;\r
- int ofsTriangles;\r
- int ofsShaders; /* offset from start of mdcSurface_t */\r
- int ofsSt; /* texture coords are common for all frames */\r
- int ofsXyzNormals; /* numVerts * numBaseFrames */\r
- int ofsXyzCompressed; /* numVerts * numCompFrames */\r
-\r
- int ofsFrameBaseFrames; /* numFrames */\r
- int ofsFrameCompFrames; /* numFrames */\r
- int ofsEnd; /* next surface follows */\r
-}\r
-mdcSurface_t;\r
-\r
-typedef struct mdcShader_s\r
-{\r
- char name[ 64 ];\r
- int shaderIndex; /* for ingame use */\r
-}\r
-mdcShader_t;\r
-\r
-typedef struct mdcTriangle_s\r
-{\r
- int indexes[ 3 ];\r
-}\r
-mdcTriangle_t;\r
-\r
-typedef struct mdcTexCoord_s\r
-{\r
- float st[ 2 ];\r
-}\r
-mdcTexCoord_t;\r
-\r
-typedef struct mdcVertex_s\r
-{\r
- short xyz[ 3 ];\r
- short normal;\r
-}\r
-mdcVertex_t;\r
-\r
-typedef struct mdcXyzCompressed_s\r
-{\r
- unsigned int ofsVec; /* offset direction from the last base frame */\r
-}\r
-mdcXyzCompressed_t;\r
-\r
-\r
-/* mdc model file mdc structure */\r
-typedef struct mdc_s\r
-{\r
- char magic[ 4 ]; /* MDC_MAGIC */\r
- int version;\r
- char name[ 64 ]; /* model name */\r
- int flags;\r
- int numFrames;\r
- int numTags;\r
- int numSurfaces;\r
- int numSkins; /* number of skins for the mesh */\r
- int ofsFrames; /* offset for first frame */\r
- int ofsTagNames; /* numTags */\r
- int ofsTags; /* numFrames * numTags */\r
- int ofsSurfaces; /* first surface, others follow */\r
- int ofsEnd; /* end of file */\r
-}\r
-mdc_t;\r
-\r
-\r
-\r
-\r
-/*\r
-_mdc_canload()\r
-validates a Return to Castle Wolfenstein model file. btw, i use the\r
-preceding underscore cause it's a static func referenced\r
-by one structure only.\r
-*/\r
-\r
-static int _mdc_canload( PM_PARAMS_CANLOAD )\r
-{\r
- mdc_t *mdc;\r
- \r
-\r
- /* to keep the compiler happy */\r
- *fileName = *fileName;\r
- \r
- /* sanity check */\r
- if( bufSize < ( sizeof( *mdc ) * 2) )\r
- return PICO_PMV_ERROR_SIZE;\r
- \r
- /* set as mdc */\r
- mdc = (mdc_t*) buffer;\r
- \r
- /* check mdc magic */\r
- if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) ) \r
- return PICO_PMV_ERROR_IDENT;\r
- \r
- /* check mdc version */\r
- if( _pico_little_long( mdc->version ) != MDC_VERSION )\r
- return PICO_PMV_ERROR_VERSION;\r
- \r
- /* file seems to be a valid mdc */\r
- return PICO_PMV_OK;\r
-}\r
-\r
-\r
-\r
-/*\r
-_mdc_load()\r
-loads a Return to Castle Wolfenstein mdc model file.\r
-*/\r
-\r
-static picoModel_t *_mdc_load( PM_PARAMS_LOAD )\r
-{\r
- int i, j;\r
- picoByte_t *bb;\r
- mdc_t *mdc;\r
- mdcSurface_t *surface;\r
- mdcShader_t *shader;\r
- mdcTexCoord_t *texCoord;\r
- mdcFrame_t *frame;\r
- mdcTriangle_t *triangle;\r
- mdcVertex_t *vertex;\r
- mdcXyzCompressed_t *vertexComp;\r
- short *mdcShort, *mdcCompVert;\r
- double lat, lng;\r
- \r
- picoModel_t *picoModel;\r
- picoSurface_t *picoSurface;\r
- picoShader_t *picoShader;\r
- picoVec3_t xyz, normal;\r
- picoVec2_t st;\r
- picoColor_t color;\r
- \r
- \r
- /* -------------------------------------------------\r
- mdc loading\r
- ------------------------------------------------- */\r
-\r
-\r
- /* set as mdc */\r
- bb = (picoByte_t*) buffer;\r
- mdc = (mdc_t*) buffer;\r
- \r
- /* check ident and version */\r
- if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) || _pico_little_long( mdc->version ) != MDC_VERSION )\r
- {\r
- /* not an mdc file (todo: set error) */\r
- return NULL;\r
- }\r
- \r
- /* swap mdc */\r
- mdc->version = _pico_little_long( mdc->version );\r
- mdc->numFrames = _pico_little_long( mdc->numFrames );\r
- mdc->numTags = _pico_little_long( mdc->numTags );\r
- mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );\r
- mdc->numSkins = _pico_little_long( mdc->numSkins );\r
- mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );\r
- mdc->ofsTags = _pico_little_long( mdc->ofsTags );\r
- mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );\r
- mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );\r
- mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );\r
- \r
- /* do frame check */\r
- if( mdc->numFrames < 1 )\r
- {\r
- _pico_printf( PICO_ERROR, "MDC with 0 frames" );\r
- return NULL;\r
- }\r
- \r
- if( frameNum < 0 || frameNum >= mdc->numFrames )\r
- {\r
- _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );\r
- return NULL;\r
- }\r
- \r
- /* swap frames */\r
- frame = (mdcFrame_t*) (bb + mdc->ofsFrames );\r
- for( i = 0; i < mdc->numFrames; i++, frame++ )\r
- {\r
- frame->radius = _pico_little_float( frame->radius );\r
- for( j = 0; j < 3; j++ )\r
- {\r
- frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );\r
- frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );\r
- frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );\r
- }\r
- }\r
- \r
- /* swap surfaces */\r
- surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);\r
- for( i = 0; i < mdc->numSurfaces; i++ )\r
- {\r
- /* swap surface mdc */\r
- surface->flags = _pico_little_long( surface->flags );\r
- surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );\r
- surface->numCompFrames = _pico_little_long( surface->numCompFrames );\r
- surface->numShaders = _pico_little_long( surface->numShaders );\r
- surface->numTriangles = _pico_little_long( surface->numTriangles );\r
- surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );\r
- surface->numVerts = _pico_little_long( surface->numVerts );\r
- surface->ofsShaders = _pico_little_long( surface->ofsShaders );\r
- surface->ofsSt = _pico_little_long( surface->ofsSt );\r
- surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );\r
- surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );\r
- surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );\r
- surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );\r
- surface->ofsEnd = _pico_little_long( surface->ofsEnd );\r
- \r
- /* swap triangles */\r
- triangle = (mdcTriangle_t*) ((picoByte_t*) surface + surface->ofsTriangles);\r
- for( j = 0; j < surface->numTriangles; j++, triangle++ )\r
- {\r
- /* sea: swaps fixed */\r
- triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );\r
- triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );\r
- triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );\r
- }\r
- \r
- /* swap st coords */\r
- texCoord = (mdcTexCoord_t*) ((picoByte_t*) surface + surface->ofsSt);\r
- for( j = 0; j < surface->numVerts; j++, texCoord++ )\r
- {\r
- texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );\r
- texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );\r
- }\r
- \r
- /* swap xyz/normals */\r
- vertex = (mdcVertex_t*) ((picoByte_t*) surface + surface->ofsXyzNormals);\r
- for( j = 0; j < (surface->numVerts * surface->numBaseFrames); j++, vertex++)\r
- {\r
- vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );\r
- vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );\r
- vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );\r
- vertex->normal = _pico_little_short( vertex->normal );\r
- }\r
-\r
- /* swap xyz/compressed */\r
- vertexComp = (mdcXyzCompressed_t*) ((picoByte_t*) surface + surface->ofsXyzCompressed);\r
- for( j = 0; j < (surface->numVerts * surface->numCompFrames); j++, vertexComp++)\r
- {\r
- vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );\r
- }\r
-\r
- /* swap base frames */\r
- mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameBaseFrames);\r
- for( j = 0; j < mdc->numFrames; j++, mdcShort++)\r
- {\r
- *mdcShort = _pico_little_short( *mdcShort );\r
- }\r
-\r
- /* swap compressed frames */\r
- mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameCompFrames);\r
- for( j = 0; j < mdc->numFrames; j++, mdcShort++)\r
- {\r
- *mdcShort = _pico_little_short( *mdcShort );\r
- }\r
- \r
- /* get next surface */\r
- surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);\r
- }\r
- \r
- /* -------------------------------------------------\r
- pico model creation\r
- ------------------------------------------------- */\r
- \r
- /* create new pico model */\r
- picoModel = PicoNewModel();\r
- if( picoModel == NULL )\r
- {\r
- _pico_printf( PICO_ERROR, "Unable to allocate a new model" );\r
- return NULL;\r
- }\r
- \r
- /* do model setup */\r
- PicoSetModelFrameNum( picoModel, frameNum );\r
- PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */\r
- PicoSetModelName( picoModel, fileName );\r
- PicoSetModelFileName( picoModel, fileName );\r
- \r
- /* mdc surfaces become picomodel surfaces */\r
- surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);\r
- \r
- /* run through mdc surfaces */\r
- for( i = 0; i < mdc->numSurfaces; i++ )\r
- {\r
- /* allocate new pico surface */\r
- picoSurface = PicoNewSurface( picoModel );\r
- if( picoSurface == NULL )\r
- {\r
- _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );\r
- PicoFreeModel( picoModel ); /* sea */\r
- return NULL;\r
- }\r
- \r
- /* mdc model surfaces are all triangle meshes */\r
- PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );\r
- \r
- /* set surface name */\r
- PicoSetSurfaceName( picoSurface, surface->name );\r
- \r
- /* create new pico shader -sea */\r
- picoShader = PicoNewShader( picoModel );\r
- if( picoShader == NULL )\r
- {\r
- _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );\r
- PicoFreeModel( picoModel );\r
- return NULL;\r
- }\r
- \r
- /* detox and set shader name */\r
- shader = (mdcShader_t*) ((picoByte_t*) surface + surface->ofsShaders);\r
- _pico_setfext( shader->name, "" );\r
- _pico_unixify( shader->name );\r
- PicoSetShaderName( picoShader, shader->name );\r
- \r
- /* associate current surface with newly created shader */\r
- PicoSetSurfaceShader( picoSurface, picoShader );\r
- \r
- /* copy indexes */\r
- triangle = (mdcTriangle_t *) ((picoByte_t*) surface + surface->ofsTriangles);\r
- \r
- for( j = 0; j < surface->numTriangles; j++, triangle++ )\r
- {\r
- PicoSetSurfaceIndex( picoSurface, (j * 3 + 0), (picoIndex_t) triangle->indexes[ 0 ] );\r
- PicoSetSurfaceIndex( picoSurface, (j * 3 + 1), (picoIndex_t) triangle->indexes[ 1 ] );\r
- PicoSetSurfaceIndex( picoSurface, (j * 3 + 2), (picoIndex_t) triangle->indexes[ 2 ] );\r
- }\r
- \r
- /* copy vertexes */\r
- texCoord = (mdcTexCoord_t*) ((picoByte_t *) surface + surface->ofsSt);\r
- mdcShort = (short *) ((picoByte_t *) surface + surface->ofsXyzNormals) + ((int)*((short *) ((picoByte_t *) surface + surface->ofsFrameBaseFrames) + frameNum) * surface->numVerts * 4);\r
- if( surface->numCompFrames > 0 )\r
- {\r
- mdcCompVert = (short *) ((picoByte_t *) surface + surface->ofsFrameCompFrames) + frameNum;\r
- if( *mdcCompVert >= 0 )\r
- vertexComp = (mdcXyzCompressed_t *) ((picoByte_t *) surface + surface->ofsXyzCompressed) + (*mdcCompVert * surface->numVerts);\r
- }\r
- _pico_set_color( color, 255, 255, 255, 255 );\r
- \r
- for( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort+=4 )\r
- {\r
- /* set vertex origin */\r
- xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];\r
- xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];\r
- xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];\r
-\r
- /* add compressed ofsVec */\r
- if( surface->numCompFrames > 0 && *mdcCompVert >= 0 )\r
- { \r
- xyz[ 0 ] += ((float) ((vertexComp->ofsVec) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;\r
- xyz[ 1 ] += ((float) ((vertexComp->ofsVec >> 8) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;\r
- xyz[ 2 ] += ((float) ((vertexComp->ofsVec >> 16) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;\r
- PicoSetSurfaceXYZ( picoSurface, j, xyz );\r
-\r
- normal[ 0 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 0 ];\r
- normal[ 1 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 1 ];\r
- normal[ 2 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 2 ];\r
- PicoSetSurfaceNormal( picoSurface, j, normal );\r
-\r
- vertexComp++;\r
- }\r
- else\r
- { \r
- PicoSetSurfaceXYZ( picoSurface, j, xyz );\r
-\r
- /* decode lat/lng normal to 3 float normal */\r
- lat = (float) ((*(mdcShort + 3) >> 8) & 0xff);\r
- lng = (float) (*(mdcShort + 3) & 0xff);\r
- lat *= PICO_PI / 128;\r
- lng *= PICO_PI / 128;\r
- normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );\r
- normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );\r
- normal[ 2 ] = (picoVec_t) cos( lng );\r
- PicoSetSurfaceNormal( picoSurface, j, normal );\r
- }\r
- \r
- /* set st coords */\r
- st[ 0 ] = texCoord->st[ 0 ];\r
- st[ 1 ] = texCoord->st[ 1 ];\r
- PicoSetSurfaceST( picoSurface, 0, j, st );\r
-\r
- /* set color */\r
- PicoSetSurfaceColor( picoSurface, 0, j, color );\r
- }\r
- \r
- /* get next surface */\r
- surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);\r
- }\r
- \r
- /* return the new pico model */\r
- return picoModel;\r
-}\r
-\r
-\r
-\r
-/* pico file format module definition */\r
-const picoModule_t picoModuleMDC =\r
-{\r
- "1.3", /* module version string */\r
- "RtCW MDC", /* module display name */\r
- "Arnout van Meer", /* author's name */\r
- "2002 Arnout van Meer", /* module copyright */\r
- {\r
- "mdc", NULL, NULL, NULL /* default extensions to use */\r
- },\r
- _mdc_canload, /* validation routine */\r
- _mdc_load, /* load routine */\r
- NULL, /* save validation routine */\r
- NULL /* save routine */\r
-};\r
+/* -----------------------------------------------------------------------------
+
+PicoModel Library
+
+Copyright (c) 2002, Randy Reddig & seaw0lf
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+Neither the names of the copyright holders nor the names of its contributors may
+be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------------- */
+
+
+
+/* marker */
+#define PM_MDC_C
+
+
+
+/* dependencies */
+#include "picointernal.h"
+
+/* mdc model format */
+#define MDC_MAGIC "IDPC"
+#define MDC_VERSION 2
+
+/* mdc vertex scale */
+#define MDC_SCALE (1.0f / 64.0f)
+#define MDC_MAX_OFS 127.0f
+#define MDC_DIST_SCALE 0.05f
+
+/* mdc decoding normal table */
+double mdcNormals[ 256 ][ 3 ] =
+{
+ { 1.000000, 0.000000, 0.000000 },
+ { 0.980785, 0.195090, 0.000000 },
+ { 0.923880, 0.382683, 0.000000 },
+ { 0.831470, 0.555570, 0.000000 },
+ { 0.707107, 0.707107, 0.000000 },
+ { 0.555570, 0.831470, 0.000000 },
+ { 0.382683, 0.923880, 0.000000 },
+ { 0.195090, 0.980785, 0.000000 },
+ { -0.000000, 1.000000, 0.000000 },
+ { -0.195090, 0.980785, 0.000000 },
+ { -0.382683, 0.923880, 0.000000 },
+ { -0.555570, 0.831470, 0.000000 },
+ { -0.707107, 0.707107, 0.000000 },
+ { -0.831470, 0.555570, 0.000000 },
+ { -0.923880, 0.382683, 0.000000 },
+ { -0.980785, 0.195090, 0.000000 },
+ { -1.000000, -0.000000, 0.000000 },
+ { -0.980785, -0.195090, 0.000000 },
+ { -0.923880, -0.382683, 0.000000 },
+ { -0.831470, -0.555570, 0.000000 },
+ { -0.707107, -0.707107, 0.000000 },
+ { -0.555570, -0.831469, 0.000000 },
+ { -0.382684, -0.923880, 0.000000 },
+ { -0.195090, -0.980785, 0.000000 },
+ { 0.000000, -1.000000, 0.000000 },
+ { 0.195090, -0.980785, 0.000000 },
+ { 0.382684, -0.923879, 0.000000 },
+ { 0.555570, -0.831470, 0.000000 },
+ { 0.707107, -0.707107, 0.000000 },
+ { 0.831470, -0.555570, 0.000000 },
+ { 0.923880, -0.382683, 0.000000 },
+ { 0.980785, -0.195090, 0.000000 },
+ { 0.980785, 0.000000, -0.195090 },
+ { 0.956195, 0.218245, -0.195090 },
+ { 0.883657, 0.425547, -0.195090 },
+ { 0.766809, 0.611510, -0.195090 },
+ { 0.611510, 0.766809, -0.195090 },
+ { 0.425547, 0.883657, -0.195090 },
+ { 0.218245, 0.956195, -0.195090 },
+ { -0.000000, 0.980785, -0.195090 },
+ { -0.218245, 0.956195, -0.195090 },
+ { -0.425547, 0.883657, -0.195090 },
+ { -0.611510, 0.766809, -0.195090 },
+ { -0.766809, 0.611510, -0.195090 },
+ { -0.883657, 0.425547, -0.195090 },
+ { -0.956195, 0.218245, -0.195090 },
+ { -0.980785, -0.000000, -0.195090 },
+ { -0.956195, -0.218245, -0.195090 },
+ { -0.883657, -0.425547, -0.195090 },
+ { -0.766809, -0.611510, -0.195090 },
+ { -0.611510, -0.766809, -0.195090 },
+ { -0.425547, -0.883657, -0.195090 },
+ { -0.218245, -0.956195, -0.195090 },
+ { 0.000000, -0.980785, -0.195090 },
+ { 0.218245, -0.956195, -0.195090 },
+ { 0.425547, -0.883657, -0.195090 },
+ { 0.611510, -0.766809, -0.195090 },
+ { 0.766809, -0.611510, -0.195090 },
+ { 0.883657, -0.425547, -0.195090 },
+ { 0.956195, -0.218245, -0.195090 },
+ { 0.923880, 0.000000, -0.382683 },
+ { 0.892399, 0.239118, -0.382683 },
+ { 0.800103, 0.461940, -0.382683 },
+ { 0.653281, 0.653281, -0.382683 },
+ { 0.461940, 0.800103, -0.382683 },
+ { 0.239118, 0.892399, -0.382683 },
+ { -0.000000, 0.923880, -0.382683 },
+ { -0.239118, 0.892399, -0.382683 },
+ { -0.461940, 0.800103, -0.382683 },
+ { -0.653281, 0.653281, -0.382683 },
+ { -0.800103, 0.461940, -0.382683 },
+ { -0.892399, 0.239118, -0.382683 },
+ { -0.923880, -0.000000, -0.382683 },
+ { -0.892399, -0.239118, -0.382683 },
+ { -0.800103, -0.461940, -0.382683 },
+ { -0.653282, -0.653281, -0.382683 },
+ { -0.461940, -0.800103, -0.382683 },
+ { -0.239118, -0.892399, -0.382683 },
+ { 0.000000, -0.923880, -0.382683 },
+ { 0.239118, -0.892399, -0.382683 },
+ { 0.461940, -0.800103, -0.382683 },
+ { 0.653281, -0.653282, -0.382683 },
+ { 0.800103, -0.461940, -0.382683 },
+ { 0.892399, -0.239117, -0.382683 },
+ { 0.831470, 0.000000, -0.555570 },
+ { 0.790775, 0.256938, -0.555570 },
+ { 0.672673, 0.488726, -0.555570 },
+ { 0.488726, 0.672673, -0.555570 },
+ { 0.256938, 0.790775, -0.555570 },
+ { -0.000000, 0.831470, -0.555570 },
+ { -0.256938, 0.790775, -0.555570 },
+ { -0.488726, 0.672673, -0.555570 },
+ { -0.672673, 0.488726, -0.555570 },
+ { -0.790775, 0.256938, -0.555570 },
+ { -0.831470, -0.000000, -0.555570 },
+ { -0.790775, -0.256938, -0.555570 },
+ { -0.672673, -0.488726, -0.555570 },
+ { -0.488725, -0.672673, -0.555570 },
+ { -0.256938, -0.790775, -0.555570 },
+ { 0.000000, -0.831470, -0.555570 },
+ { 0.256938, -0.790775, -0.555570 },
+ { 0.488725, -0.672673, -0.555570 },
+ { 0.672673, -0.488726, -0.555570 },
+ { 0.790775, -0.256938, -0.555570 },
+ { 0.707107, 0.000000, -0.707107 },
+ { 0.653281, 0.270598, -0.707107 },
+ { 0.500000, 0.500000, -0.707107 },
+ { 0.270598, 0.653281, -0.707107 },
+ { -0.000000, 0.707107, -0.707107 },
+ { -0.270598, 0.653282, -0.707107 },
+ { -0.500000, 0.500000, -0.707107 },
+ { -0.653281, 0.270598, -0.707107 },
+ { -0.707107, -0.000000, -0.707107 },
+ { -0.653281, -0.270598, -0.707107 },
+ { -0.500000, -0.500000, -0.707107 },
+ { -0.270598, -0.653281, -0.707107 },
+ { 0.000000, -0.707107, -0.707107 },
+ { 0.270598, -0.653281, -0.707107 },
+ { 0.500000, -0.500000, -0.707107 },
+ { 0.653282, -0.270598, -0.707107 },
+ { 0.555570, 0.000000, -0.831470 },
+ { 0.481138, 0.277785, -0.831470 },
+ { 0.277785, 0.481138, -0.831470 },
+ { -0.000000, 0.555570, -0.831470 },
+ { -0.277785, 0.481138, -0.831470 },
+ { -0.481138, 0.277785, -0.831470 },
+ { -0.555570, -0.000000, -0.831470 },
+ { -0.481138, -0.277785, -0.831470 },
+ { -0.277785, -0.481138, -0.831470 },
+ { 0.000000, -0.555570, -0.831470 },
+ { 0.277785, -0.481138, -0.831470 },
+ { 0.481138, -0.277785, -0.831470 },
+ { 0.382683, 0.000000, -0.923880 },
+ { 0.270598, 0.270598, -0.923880 },
+ { -0.000000, 0.382683, -0.923880 },
+ { -0.270598, 0.270598, -0.923880 },
+ { -0.382683, -0.000000, -0.923880 },
+ { -0.270598, -0.270598, -0.923880 },
+ { 0.000000, -0.382683, -0.923880 },
+ { 0.270598, -0.270598, -0.923880 },
+ { 0.195090, 0.000000, -0.980785 },
+ { -0.000000, 0.195090, -0.980785 },
+ { -0.195090, -0.000000, -0.980785 },
+ { 0.000000, -0.195090, -0.980785 },
+ { 0.980785, 0.000000, 0.195090 },
+ { 0.956195, 0.218245, 0.195090 },
+ { 0.883657, 0.425547, 0.195090 },
+ { 0.766809, 0.611510, 0.195090 },
+ { 0.611510, 0.766809, 0.195090 },
+ { 0.425547, 0.883657, 0.195090 },
+ { 0.218245, 0.956195, 0.195090 },
+ { -0.000000, 0.980785, 0.195090 },
+ { -0.218245, 0.956195, 0.195090 },
+ { -0.425547, 0.883657, 0.195090 },
+ { -0.611510, 0.766809, 0.195090 },
+ { -0.766809, 0.611510, 0.195090 },
+ { -0.883657, 0.425547, 0.195090 },
+ { -0.956195, 0.218245, 0.195090 },
+ { -0.980785, -0.000000, 0.195090 },
+ { -0.956195, -0.218245, 0.195090 },
+ { -0.883657, -0.425547, 0.195090 },
+ { -0.766809, -0.611510, 0.195090 },
+ { -0.611510, -0.766809, 0.195090 },
+ { -0.425547, -0.883657, 0.195090 },
+ { -0.218245, -0.956195, 0.195090 },
+ { 0.000000, -0.980785, 0.195090 },
+ { 0.218245, -0.956195, 0.195090 },
+ { 0.425547, -0.883657, 0.195090 },
+ { 0.611510, -0.766809, 0.195090 },
+ { 0.766809, -0.611510, 0.195090 },
+ { 0.883657, -0.425547, 0.195090 },
+ { 0.956195, -0.218245, 0.195090 },
+ { 0.923880, 0.000000, 0.382683 },
+ { 0.892399, 0.239118, 0.382683 },
+ { 0.800103, 0.461940, 0.382683 },
+ { 0.653281, 0.653281, 0.382683 },
+ { 0.461940, 0.800103, 0.382683 },
+ { 0.239118, 0.892399, 0.382683 },
+ { -0.000000, 0.923880, 0.382683 },
+ { -0.239118, 0.892399, 0.382683 },
+ { -0.461940, 0.800103, 0.382683 },
+ { -0.653281, 0.653281, 0.382683 },
+ { -0.800103, 0.461940, 0.382683 },
+ { -0.892399, 0.239118, 0.382683 },
+ { -0.923880, -0.000000, 0.382683 },
+ { -0.892399, -0.239118, 0.382683 },
+ { -0.800103, -0.461940, 0.382683 },
+ { -0.653282, -0.653281, 0.382683 },
+ { -0.461940, -0.800103, 0.382683 },
+ { -0.239118, -0.892399, 0.382683 },
+ { 0.000000, -0.923880, 0.382683 },
+ { 0.239118, -0.892399, 0.382683 },
+ { 0.461940, -0.800103, 0.382683 },
+ { 0.653281, -0.653282, 0.382683 },
+ { 0.800103, -0.461940, 0.382683 },
+ { 0.892399, -0.239117, 0.382683 },
+ { 0.831470, 0.000000, 0.555570 },
+ { 0.790775, 0.256938, 0.555570 },
+ { 0.672673, 0.488726, 0.555570 },
+ { 0.488726, 0.672673, 0.555570 },
+ { 0.256938, 0.790775, 0.555570 },
+ { -0.000000, 0.831470, 0.555570 },
+ { -0.256938, 0.790775, 0.555570 },
+ { -0.488726, 0.672673, 0.555570 },
+ { -0.672673, 0.488726, 0.555570 },
+ { -0.790775, 0.256938, 0.555570 },
+ { -0.831470, -0.000000, 0.555570 },
+ { -0.790775, -0.256938, 0.555570 },
+ { -0.672673, -0.488726, 0.555570 },
+ { -0.488725, -0.672673, 0.555570 },
+ { -0.256938, -0.790775, 0.555570 },
+ { 0.000000, -0.831470, 0.555570 },
+ { 0.256938, -0.790775, 0.555570 },
+ { 0.488725, -0.672673, 0.555570 },
+ { 0.672673, -0.488726, 0.555570 },
+ { 0.790775, -0.256938, 0.555570 },
+ { 0.707107, 0.000000, 0.707107 },
+ { 0.653281, 0.270598, 0.707107 },
+ { 0.500000, 0.500000, 0.707107 },
+ { 0.270598, 0.653281, 0.707107 },
+ { -0.000000, 0.707107, 0.707107 },
+ { -0.270598, 0.653282, 0.707107 },
+ { -0.500000, 0.500000, 0.707107 },
+ { -0.653281, 0.270598, 0.707107 },
+ { -0.707107, -0.000000, 0.707107 },
+ { -0.653281, -0.270598, 0.707107 },
+ { -0.500000, -0.500000, 0.707107 },
+ { -0.270598, -0.653281, 0.707107 },
+ { 0.000000, -0.707107, 0.707107 },
+ { 0.270598, -0.653281, 0.707107 },
+ { 0.500000, -0.500000, 0.707107 },
+ { 0.653282, -0.270598, 0.707107 },
+ { 0.555570, 0.000000, 0.831470 },
+ { 0.481138, 0.277785, 0.831470 },
+ { 0.277785, 0.481138, 0.831470 },
+ { -0.000000, 0.555570, 0.831470 },
+ { -0.277785, 0.481138, 0.831470 },
+ { -0.481138, 0.277785, 0.831470 },
+ { -0.555570, -0.000000, 0.831470 },
+ { -0.481138, -0.277785, 0.831470 },
+ { -0.277785, -0.481138, 0.831470 },
+ { 0.000000, -0.555570, 0.831470 },
+ { 0.277785, -0.481138, 0.831470 },
+ { 0.481138, -0.277785, 0.831470 },
+ { 0.382683, 0.000000, 0.923880 },
+ { 0.270598, 0.270598, 0.923880 },
+ { -0.000000, 0.382683, 0.923880 },
+ { -0.270598, 0.270598, 0.923880 },
+ { -0.382683, -0.000000, 0.923880 },
+ { -0.270598, -0.270598, 0.923880 },
+ { 0.000000, -0.382683, 0.923880 },
+ { 0.270598, -0.270598, 0.923880 },
+ { 0.195090, 0.000000, 0.980785 },
+ { -0.000000, 0.195090, 0.980785 },
+ { -0.195090, -0.000000, 0.980785 },
+ { 0.000000, -0.195090, 0.980785 }
+};
+
+/* mdc model frame information */
+typedef struct mdcFrame_s
+{
+ float bounds[ 2 ][ 3 ];
+ float localOrigin[ 3 ];
+ float radius;
+ char creator[ 16 ];
+}
+mdcFrame_t;
+
+/* mdc model tag information */
+typedef struct mdcTag_s
+{
+ short xyz[3];
+ short angles[3];
+}
+mdcTag_t;
+
+/* mdc surface mdc (one object mesh) */
+typedef struct mdcSurface_s
+{
+ char magic[ 4 ];
+ char name[ 64 ]; /* polyset name */
+ int flags;
+ int numCompFrames; /* all surfaces in a model should have the same */
+ int numBaseFrames; /* ditto */
+ int numShaders; /* all model surfaces should have the same */
+ int numVerts;
+ int numTriangles;
+ int ofsTriangles;
+ int ofsShaders; /* offset from start of mdcSurface_t */
+ int ofsSt; /* texture coords are common for all frames */
+ int ofsXyzNormals; /* numVerts * numBaseFrames */
+ int ofsXyzCompressed; /* numVerts * numCompFrames */
+
+ int ofsFrameBaseFrames; /* numFrames */
+ int ofsFrameCompFrames; /* numFrames */
+ int ofsEnd; /* next surface follows */
+}
+mdcSurface_t;
+
+typedef struct mdcShader_s
+{
+ char name[ 64 ];
+ int shaderIndex; /* for ingame use */
+}
+mdcShader_t;
+
+typedef struct mdcTriangle_s
+{
+ int indexes[ 3 ];
+}
+mdcTriangle_t;
+
+typedef struct mdcTexCoord_s
+{
+ float st[ 2 ];
+}
+mdcTexCoord_t;
+
+typedef struct mdcVertex_s
+{
+ short xyz[ 3 ];
+ short normal;
+}
+mdcVertex_t;
+
+typedef struct mdcXyzCompressed_s
+{
+ unsigned int ofsVec; /* offset direction from the last base frame */
+}
+mdcXyzCompressed_t;
+
+
+/* mdc model file mdc structure */
+typedef struct mdc_s
+{
+ char magic[ 4 ]; /* MDC_MAGIC */
+ int version;
+ char name[ 64 ]; /* model name */
+ int flags;
+ int numFrames;
+ int numTags;
+ int numSurfaces;
+ int numSkins; /* number of skins for the mesh */
+ int ofsFrames; /* offset for first frame */
+ int ofsTagNames; /* numTags */
+ int ofsTags; /* numFrames * numTags */
+ int ofsSurfaces; /* first surface, others follow */
+ int ofsEnd; /* end of file */
+}
+mdc_t;
+
+
+
+
+/*
+_mdc_canload()
+validates a Return to Castle Wolfenstein model file. btw, i use the
+preceding underscore cause it's a static func referenced
+by one structure only.
+*/
+
+static int _mdc_canload( PM_PARAMS_CANLOAD )
+{
+ mdc_t *mdc;
+
+
+ /* to keep the compiler happy */
+ *fileName = *fileName;
+
+ /* sanity check */
+ if( bufSize < ( sizeof( *mdc ) * 2) )
+ return PICO_PMV_ERROR_SIZE;
+
+ /* set as mdc */
+ mdc = (mdc_t*) buffer;
+
+ /* check mdc magic */
+ if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) )
+ return PICO_PMV_ERROR_IDENT;
+
+ /* check mdc version */
+ if( _pico_little_long( mdc->version ) != MDC_VERSION )
+ return PICO_PMV_ERROR_VERSION;
+
+ /* file seems to be a valid mdc */
+ return PICO_PMV_OK;
+}
+
+
+
+/*
+_mdc_load()
+loads a Return to Castle Wolfenstein mdc model file.
+*/
+
+static picoModel_t *_mdc_load( PM_PARAMS_LOAD )
+{
+ int i, j;
+ picoByte_t *bb;
+ mdc_t *mdc;
+ mdcSurface_t *surface;
+ mdcShader_t *shader;
+ mdcTexCoord_t *texCoord;
+ mdcFrame_t *frame;
+ mdcTriangle_t *triangle;
+ mdcVertex_t *vertex;
+ mdcXyzCompressed_t *vertexComp;
+ short *mdcShort, *mdcCompVert;
+ double lat, lng;
+
+ picoModel_t *picoModel;
+ picoSurface_t *picoSurface;
+ picoShader_t *picoShader;
+ picoVec3_t xyz, normal;
+ picoVec2_t st;
+ picoColor_t color;
+
+
+ /* -------------------------------------------------
+ mdc loading
+ ------------------------------------------------- */
+
+
+ /* set as mdc */
+ bb = (picoByte_t*) buffer;
+ mdc = (mdc_t*) buffer;
+
+ /* check ident and version */
+ if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) || _pico_little_long( mdc->version ) != MDC_VERSION )
+ {
+ /* not an mdc file (todo: set error) */
+ return NULL;
+ }
+
+ /* swap mdc */
+ mdc->version = _pico_little_long( mdc->version );
+ mdc->numFrames = _pico_little_long( mdc->numFrames );
+ mdc->numTags = _pico_little_long( mdc->numTags );
+ mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );
+ mdc->numSkins = _pico_little_long( mdc->numSkins );
+ mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );
+ mdc->ofsTags = _pico_little_long( mdc->ofsTags );
+ mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );
+ mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );
+ mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );
+
+ /* do frame check */
+ if( mdc->numFrames < 1 )
+ {
+ _pico_printf( PICO_ERROR, "MDC with 0 frames" );
+ return NULL;
+ }
+
+ if( frameNum < 0 || frameNum >= mdc->numFrames )
+ {
+ _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
+ return NULL;
+ }
+
+ /* swap frames */
+ frame = (mdcFrame_t*) (bb + mdc->ofsFrames );
+ for( i = 0; i < mdc->numFrames; i++, frame++ )
+ {
+ frame->radius = _pico_little_float( frame->radius );
+ for( j = 0; j < 3; j++ )
+ {
+ frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
+ frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
+ frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
+ }
+ }
+
+ /* swap surfaces */
+ surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
+ for( i = 0; i < mdc->numSurfaces; i++ )
+ {
+ /* swap surface mdc */
+ surface->flags = _pico_little_long( surface->flags );
+ surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
+ surface->numCompFrames = _pico_little_long( surface->numCompFrames );
+ surface->numShaders = _pico_little_long( surface->numShaders );
+ surface->numTriangles = _pico_little_long( surface->numTriangles );
+ surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
+ surface->numVerts = _pico_little_long( surface->numVerts );
+ surface->ofsShaders = _pico_little_long( surface->ofsShaders );
+ surface->ofsSt = _pico_little_long( surface->ofsSt );
+ surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
+ surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
+ surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
+ surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
+ surface->ofsEnd = _pico_little_long( surface->ofsEnd );
+
+ /* swap triangles */
+ triangle = (mdcTriangle_t*) ((picoByte_t*) surface + surface->ofsTriangles);
+ for( j = 0; j < surface->numTriangles; j++, triangle++ )
+ {
+ /* sea: swaps fixed */
+ triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
+ triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
+ triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
+ }
+
+ /* swap st coords */
+ texCoord = (mdcTexCoord_t*) ((picoByte_t*) surface + surface->ofsSt);
+ for( j = 0; j < surface->numVerts; j++, texCoord++ )
+ {
+ texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
+ texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
+ }
+
+ /* swap xyz/normals */
+ vertex = (mdcVertex_t*) ((picoByte_t*) surface + surface->ofsXyzNormals);
+ for( j = 0; j < (surface->numVerts * surface->numBaseFrames); j++, vertex++)
+ {
+ vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
+ vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
+ vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
+ vertex->normal = _pico_little_short( vertex->normal );
+ }
+
+ /* swap xyz/compressed */
+ vertexComp = (mdcXyzCompressed_t*) ((picoByte_t*) surface + surface->ofsXyzCompressed);
+ for( j = 0; j < (surface->numVerts * surface->numCompFrames); j++, vertexComp++)
+ {
+ vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
+ }
+
+ /* swap base frames */
+ mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameBaseFrames);
+ for( j = 0; j < mdc->numFrames; j++, mdcShort++)
+ {
+ *mdcShort = _pico_little_short( *mdcShort );
+ }
+
+ /* swap compressed frames */
+ mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameCompFrames);
+ for( j = 0; j < mdc->numFrames; j++, mdcShort++)
+ {
+ *mdcShort = _pico_little_short( *mdcShort );
+ }
+
+ /* get next surface */
+ surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
+ }
+
+ /* -------------------------------------------------
+ pico model creation
+ ------------------------------------------------- */
+
+ /* create new pico model */
+ picoModel = PicoNewModel();
+ if( picoModel == NULL )
+ {
+ _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
+ return NULL;
+ }
+
+ /* do model setup */
+ PicoSetModelFrameNum( picoModel, frameNum );
+ PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
+ PicoSetModelName( picoModel, fileName );
+ PicoSetModelFileName( picoModel, fileName );
+
+ /* mdc surfaces become picomodel surfaces */
+ surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
+
+ /* run through mdc surfaces */
+ for( i = 0; i < mdc->numSurfaces; i++ )
+ {
+ /* allocate new pico surface */
+ picoSurface = PicoNewSurface( picoModel );
+ if( picoSurface == NULL )
+ {
+ _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
+ PicoFreeModel( picoModel ); /* sea */
+ return NULL;
+ }
+
+ /* mdc model surfaces are all triangle meshes */
+ PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
+
+ /* set surface name */
+ PicoSetSurfaceName( picoSurface, surface->name );
+
+ /* create new pico shader -sea */
+ picoShader = PicoNewShader( picoModel );
+ if( picoShader == NULL )
+ {
+ _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
+ PicoFreeModel( picoModel );
+ return NULL;
+ }
+
+ /* detox and set shader name */
+ shader = (mdcShader_t*) ((picoByte_t*) surface + surface->ofsShaders);
+ _pico_setfext( shader->name, "" );
+ _pico_unixify( shader->name );
+ PicoSetShaderName( picoShader, shader->name );
+
+ /* associate current surface with newly created shader */
+ PicoSetSurfaceShader( picoSurface, picoShader );
+
+ /* copy indexes */
+ triangle = (mdcTriangle_t *) ((picoByte_t*) surface + surface->ofsTriangles);
+
+ for( j = 0; j < surface->numTriangles; j++, triangle++ )
+ {
+ PicoSetSurfaceIndex( picoSurface, (j * 3 + 0), (picoIndex_t) triangle->indexes[ 0 ] );
+ PicoSetSurfaceIndex( picoSurface, (j * 3 + 1), (picoIndex_t) triangle->indexes[ 1 ] );
+ PicoSetSurfaceIndex( picoSurface, (j * 3 + 2), (picoIndex_t) triangle->indexes[ 2 ] );
+ }
+
+ /* copy vertexes */
+ texCoord = (mdcTexCoord_t*) ((picoByte_t *) surface + surface->ofsSt);
+ mdcShort = (short *) ((picoByte_t *) surface + surface->ofsXyzNormals) + ((int)*((short *) ((picoByte_t *) surface + surface->ofsFrameBaseFrames) + frameNum) * surface->numVerts * 4);
+ if( surface->numCompFrames > 0 )
+ {
+ mdcCompVert = (short *) ((picoByte_t *) surface + surface->ofsFrameCompFrames) + frameNum;
+ if( *mdcCompVert >= 0 )
+ vertexComp = (mdcXyzCompressed_t *) ((picoByte_t *) surface + surface->ofsXyzCompressed) + (*mdcCompVert * surface->numVerts);
+ }
+ _pico_set_color( color, 255, 255, 255, 255 );
+
+ for( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort+=4 )
+ {
+ /* set vertex origin */
+ xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
+ xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
+ xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
+
+ /* add compressed ofsVec */
+ if( surface->numCompFrames > 0 && *mdcCompVert >= 0 )
+ {
+ xyz[ 0 ] += ((float) ((vertexComp->ofsVec) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
+ xyz[ 1 ] += ((float) ((vertexComp->ofsVec >> 8) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
+ xyz[ 2 ] += ((float) ((vertexComp->ofsVec >> 16) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
+ PicoSetSurfaceXYZ( picoSurface, j, xyz );
+
+ normal[ 0 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 0 ];
+ normal[ 1 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 1 ];
+ normal[ 2 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 2 ];
+ PicoSetSurfaceNormal( picoSurface, j, normal );
+
+ vertexComp++;
+ }
+ else
+ {
+ PicoSetSurfaceXYZ( picoSurface, j, xyz );
+
+ /* decode lat/lng normal to 3 float normal */
+ lat = (float) ((*(mdcShort + 3) >> 8) & 0xff);
+ lng = (float) (*(mdcShort + 3) & 0xff);
+ lat *= PICO_PI / 128;
+ lng *= PICO_PI / 128;
+ normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
+ normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
+ normal[ 2 ] = (picoVec_t) cos( lng );
+ PicoSetSurfaceNormal( picoSurface, j, normal );
+ }
+
+ /* set st coords */
+ st[ 0 ] = texCoord->st[ 0 ];
+ st[ 1 ] = texCoord->st[ 1 ];
+ PicoSetSurfaceST( picoSurface, 0, j, st );
+
+ /* set color */
+ PicoSetSurfaceColor( picoSurface, 0, j, color );
+ }
+
+ /* get next surface */
+ surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
+ }
+
+ /* return the new pico model */
+ return picoModel;
+}
+
+
+
+/* pico file format module definition */
+const picoModule_t picoModuleMDC =
+{
+ "1.3", /* module version string */
+ "RtCW MDC", /* module display name */
+ "Arnout van Meer", /* author's name */
+ "2002 Arnout van Meer", /* module copyright */
+ {
+ "mdc", NULL, NULL, NULL /* default extensions to use */
+ },
+ _mdc_canload, /* validation routine */
+ _mdc_load, /* load routine */
+ NULL, /* save validation routine */
+ NULL /* save routine */
+};