diff --git a/datacache/mdlcache.cpp b/datacache/mdlcache.cpp index 57ea4006..9ef8c6f3 100644 --- a/datacache/mdlcache.cpp +++ b/datacache/mdlcache.cpp @@ -1680,6 +1680,36 @@ bool CMDLCache::BuildHardwareData( MDLHandle_t handle, studiodata_t *pStudioData Assert( GetVertexData( handle ) ); + if( pStudioHdr->version == 49 ) + { + for( int i = 0; i < pVtxHdr->numBodyParts; i++) + { + OptimizedModel::BodyPartHeader_t *pBodyPartHdr = pVtxHdr->pBodyPart(i); + + for( int j = 0; j < pBodyPartHdr->numModels; j++ ) + { + OptimizedModel::ModelHeader_t *pModelHdr = pBodyPartHdr->pModel(j); + + for( int k = 0; k < pModelHdr->numLODs; k++) + { + OptimizedModel::ModelLODHeader_t *pModelLODHdr = pModelHdr->pLOD(k); + + for( int l = 0; l < pModelLODHdr->numMeshes; l++ ) + { + OptimizedModel::MeshHeader_t *pMeshHdr = pModelLODHdr->pMesh(l); + pMeshHdr->flags |= OptimizedModel::MESH_IS_MDL49; + + for( int m = 0; m < pMeshHdr->numStripGroups; m++ ) + { + OptimizedModel::StripGroupHeader_t *pStripGroupHdr = pMeshHdr->pStripGroup(m); + pStripGroupHdr->flags |= OptimizedModel::STRIPGROUP_IS_MDL49; + } + } + } + } + } + } + BeginLock(); bool bLoaded = g_pStudioRender->LoadModel( pStudioHdr, pVtxHdr, &pStudioData->m_HardwareData ); EndLock(); diff --git a/public/optimize.h b/public/optimize.h index 2dae8174..d7e62606 100644 --- a/public/optimize.h +++ b/public/optimize.h @@ -56,8 +56,6 @@ enum StripHeaderFlags_t { STRIP_IS_TRISTRIP = 0x02 }; -// a strip is a piece of a stripgroup that is divided by bones -// (and potentially tristrips if we remove some degenerates.) struct StripHeader_t { DECLARE_BYTESWAP_DATADESC(); @@ -84,12 +82,42 @@ struct StripHeader_t }; }; +struct StripHeader_v49_t +{ + DECLARE_BYTESWAP_DATADESC(); + // indexOffset offsets into the mesh's index array. + int numIndices; + int indexOffset; + + // vertexOffset offsets into the mesh's vert array. + int numVerts; + int vertOffset; + + // use this to enable/disable skinning. + // May decide (in optimize.cpp) to put all with 1 bone in a different strip + // than those that need skinning. + short numBones; + + unsigned char flags; + + int numBoneStateChanges; + int boneStateChangeOffset; + inline BoneStateChangeHeader_t *pBoneStateChange( int i ) const + { + return (BoneStateChangeHeader_t *)(((byte *)this) + boneStateChangeOffset) + i; + }; + + int numTopologyIndices; + int topologyOffset; +}; + enum StripGroupFlags_t { STRIPGROUP_IS_FLEXED = 0x01, STRIPGROUP_IS_HWSKINNED = 0x02, STRIPGROUP_IS_DELTA_FLEXED = 0x04, STRIPGROUP_SUPPRESS_HW_MORPH = 0x08, // NOTE: This is a temporary flag used at run time. + STRIPGROUP_IS_MDL49 = 0x80 }; // a locking group @@ -117,16 +145,51 @@ struct StripGroupHeader_t int stripOffset; inline StripHeader_t *pStrip( int i ) const { - return (StripHeader_t *)(((byte *)this) + stripOffset) + i; + if( flags & STRIPGROUP_IS_MDL49 ) + return (StripHeader_t *)((StripHeader_v49_t *)(((byte *)this) + stripOffset) + i); + else + return (StripHeader_t *)(((byte *)this) + stripOffset) + i; }; unsigned char flags; }; +struct StripGroupHeader_v49_t +{ + DECLARE_BYTESWAP_DATADESC(); + // These are the arrays of all verts and indices for this mesh. strips index into this. + int numVerts; + int vertOffset; + inline Vertex_t *pVertex( int i ) const + { + return (Vertex_t *)(((byte *)this) + vertOffset) + i; + }; + + int numIndices; + int indexOffset; + inline unsigned short *pIndex( int i ) const + { + return (unsigned short *)(((byte *)this) + indexOffset) + i; + }; + + int numStrips; + int stripOffset; + inline StripHeader_v49_t *pStrip( int i ) const + { + return (StripHeader_v49_t *)(((byte *)this) + stripOffset) + i; + }; + + unsigned char flags; + + int numTopologyIndices; + int topologyOffset; +}; + enum MeshFlags_t { // these are both material properties, and a mesh has a single material. - MESH_IS_TEETH = 0x01, - MESH_IS_EYES = 0x02 + MESH_IS_TEETH = 0x01, + MESH_IS_EYES = 0x02, + MESH_IS_MDL49 = 0x80 }; // a collection of locking groups: @@ -144,8 +207,10 @@ struct MeshHeader_t int stripGroupHeaderOffset; inline StripGroupHeader_t *pStripGroup( int i ) const { - StripGroupHeader_t *pDebug = (StripGroupHeader_t *)(((byte *)this) + stripGroupHeaderOffset) + i; - return pDebug; + if( flags & STRIPGROUP_IS_MDL49 ) + return (StripGroupHeader_t *)((StripGroupHeader_v49_t *)(((byte *)this) + stripGroupHeaderOffset) + i); + else + return (StripGroupHeader_t *)(((byte *)this) + stripGroupHeaderOffset) + i; }; unsigned char flags; }; diff --git a/public/studio.h b/public/studio.h index 19aae8b3..488d3a72 100644 --- a/public/studio.h +++ b/public/studio.h @@ -67,26 +67,26 @@ Studio models are position independent, so the cache manager can move them. ============================================================================== */ -#define STUDIO_VERSION 48 +#define STUDIO_VERSION 49 #ifndef _XBOX #define MAXSTUDIOTRIANGLES 65536 // TODO: tune this #define MAXSTUDIOVERTS 65536 // TODO: tune this #define MAXSTUDIOFLEXVERTS 10000 // max number of verts that can be flexed per mesh. TODO: tune this #else -#define MAXSTUDIOTRIANGLES 25000 -#define MAXSTUDIOVERTS 10000 -#define MAXSTUDIOFLEXVERTS 1000 +#define MAXSTUDIOTRIANGLES 65536 +#define MAXSTUDIOVERTS 32768 +#define MAXSTUDIOFLEXVERTS 5000 #endif #define MAXSTUDIOSKINS 32 // total textures -#define MAXSTUDIOBONES 128 // total bones actually used +#define MAXSTUDIOBONES 256 // total bones actually used #define MAXSTUDIOFLEXDESC 1024 // maximum number of low level flexes (actual morph targets) #define MAXSTUDIOFLEXCTRL 96 // maximum number of flexcontrollers (input sliders) #define MAXSTUDIOPOSEPARAM 24 #define MAXSTUDIOBONECTRLS 5 #define MAXSTUDIOANIMBLOCKS 256 -#define MAXSTUDIOBONEBITS 7 // NOTE: MUST MATCH MAXSTUDIOBONES +#define MAXSTUDIOBONEBITS 8 // NOTE: MUST MATCH MAXSTUDIOBONES // NOTE!!! : Changing this number also changes the vtx file format!!!!! #define MAX_NUM_BONES_PER_VERT 3 @@ -3101,7 +3101,7 @@ inline const mstudioflexcontroller_t *mstudioflexcontrollerui_t::pController( in // If we only support the current version, this function should be empty. inline bool Studio_ConvertStudioHdrToNewVersion( studiohdr_t *pStudioHdr ) { - COMPILE_TIME_ASSERT( STUDIO_VERSION == 48 ); // put this to make sure this code is updated upon changing version. + COMPILE_TIME_ASSERT( STUDIO_VERSION == 49 ); // put this to make sure this code is updated upon changing version. int version = pStudioHdr->version; if ( version == STUDIO_VERSION ) @@ -3143,7 +3143,7 @@ inline bool Studio_ConvertStudioHdrToNewVersion( studiohdr_t *pStudioHdr ) pAnim->zeroframeindex = 0; pAnim->zeroframespan = 0; } - } + } else if (version == 47) { for (int i = 0; i < pStudioHdr->numlocalanim; i++) @@ -3159,7 +3159,9 @@ inline bool Studio_ConvertStudioHdrToNewVersion( studiohdr_t *pStudioHdr ) } // for now, just slam the version number since they're compatible - pStudioHdr->version = STUDIO_VERSION; + + // nillerusr: that's stupid, comment this shit + //pStudioHdr->version = STUDIO_VERSION; return bResult; } diff --git a/studiorender/studiorendercontext.cpp b/studiorender/studiorendercontext.cpp index 78bccf7b..123c8a58 100644 --- a/studiorender/studiorendercontext.cpp +++ b/studiorender/studiorendercontext.cpp @@ -897,9 +897,13 @@ void CStudioRenderContext::R_StudioBuildMeshStrips( studiomeshgroup_t* pMeshGrou // Compute the amount of memory we need to store the strip data int i; int stripDataSize = 0; + + size_t stripHdrSize = (pStripGroup->flags & OptimizedModel::STRIPGROUP_IS_MDL49) + ? sizeof(OptimizedModel::StripHeader_v49_t) : sizeof(OptimizedModel::StripHeader_t); + for( i = 0; i < pStripGroup->numStrips; ++i ) { - stripDataSize += sizeof(OptimizedModel::StripHeader_t); + stripDataSize += stripHdrSize; stripDataSize += pStripGroup->pStrip(i)->numBoneStateChanges * sizeof(OptimizedModel::BoneStateChangeHeader_t); } @@ -907,15 +911,14 @@ void CStudioRenderContext::R_StudioBuildMeshStrips( studiomeshgroup_t* pMeshGrou pMeshGroup->m_pStripData = (OptimizedModel::StripHeader_t*)malloc(stripDataSize); // Copy over the strip info - int boneStateChangeOffset = pStripGroup->numStrips * sizeof(OptimizedModel::StripHeader_t); + int boneStateChangeOffset = pStripGroup->numStrips * stripHdrSize; for( i = 0; i < pStripGroup->numStrips; ++i ) { - memcpy( &pMeshGroup->m_pStripData[i], pStripGroup->pStrip(i), - sizeof( OptimizedModel::StripHeader_t ) ); + memcpy( &pMeshGroup->m_pStripData[i], pStripGroup->pStrip(i), stripHdrSize); // Fixup the bone state change offset, since we have it right after the strip data pMeshGroup->m_pStripData[i].boneStateChangeOffset = boneStateChangeOffset - - i * sizeof(OptimizedModel::StripHeader_t); + i * stripHdrSize; // copy over bone state changes int boneWeightSize = pMeshGroup->m_pStripData[i].numBoneStateChanges *