//=========== Copyright © Valve Corporation, All rights reserved. ============// // // Purpose: Mesh class dmx saving functions // //===========================================================================// #include "movieobjects/dmemodel.h" #include "movieobjects/dmemesh.h" #include "movieobjects/dmefaceset.h" #include "movieobjects/dmematerial.h" #include "movieobjects/dmeclip.h" #include "movieobjects/dmechannel.h" #include "movieobjects/dmeattachment.h" #include "movieobjects/dmeanimationlist.h" #include "movieobjects/dmecombinationoperator.h" #include "mdlobjects/dmebbox.h" #include "mdlobjects/dmelod.h" #include "mdlobjects/dmelodlist.h" #include "mdlobjects/dmebodygroup.h" #include "mdlobjects/dmebodygrouplist.h" #include "mdlobjects/dmehitbox.h" #include "mdlobjects/dmehitboxset.h" #include "mdlobjects/dmehitboxsetlist.h" #include "mdlobjects/dmesequence.h" #include "mdlobjects/dmesequencelist.h" #include "mdlobjects/dmecollisionmodel.h" #include "mdlobjects/dmecollisionjoints.h" #include "mdlobjects/dmeincludemodellist.h" #include "mdlobjects/dmedefinebone.h" #include "mdlobjects/dmedefinebonelist.h" #include "mdlobjects/dmematerialgroup.h" #include "mdlobjects/dmematerialgrouplist.h" #include "mdlobjects/dmeeyeball.h" #include "mdlobjects/dmeeyeballglobals.h" #include "mdlobjects/dmeboneweight.h" #include "mdlobjects/dmebonemask.h" #include "mdlobjects/dmebonemasklist.h" #include "mdlobjects/dmeik.h" #include "mdlobjects/dmeanimcmd.h" #include "mdlobjects/dmemotioncontrol.h" #include "mdlobjects/dmeposeparameter.h" #include "mdlobjects/dmeposeparameterlist.h" #include "mdlobjects/dmeanimblocksize.h" #include "meshutils/mesh.h" CDmeVertexDataBase::StandardFields_t g_AttribToField[] = { CDmeVertexData::FIELD_POSITION, //VERTEX_ELEMENT_POSITION = 0, CDmeVertexData::FIELD_POSITION, //VERTEX_ELEMENT_POSITION4D = 1, CDmeVertexData::FIELD_NORMAL, //VERTEX_ELEMENT_NORMAL = 2, CDmeVertexData::FIELD_NORMAL, //VERTEX_ELEMENT_NORMAL4D = 3, CDmeVertexData::FIELD_COLOR, //VERTEX_ELEMENT_COLOR = 4, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_SPECULAR = 5, CDmeVertexData::FIELD_TANGENT, //VERTEX_ELEMENT_TANGENT_S = 6, CDmeVertexData::FIELD_TANGENT, //VERTEX_ELEMENT_TANGENT_T = 7, CDmeVertexData::FIELD_WRINKLE, //VERTEX_ELEMENT_WRINKLE = 8, CDmeVertexData::FIELD_JOINT_INDICES, //VERTEX_ELEMENT_BONEINDICES = 9, CDmeVertexData::FIELD_JOINT_WEIGHTS, //VERTEX_ELEMENT_BONEWEIGHTS1 = 10, CDmeVertexData::FIELD_JOINT_WEIGHTS, //VERTEX_ELEMENT_BONEWEIGHTS2 = 11, CDmeVertexData::FIELD_JOINT_WEIGHTS, //VERTEX_ELEMENT_BONEWEIGHTS3 = 12, CDmeVertexData::FIELD_JOINT_WEIGHTS, //VERTEX_ELEMENT_BONEWEIGHTS4 = 13, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_USERDATA1 = 14, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_USERDATA2 = 15, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_USERDATA3 = 16, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_USERDATA4 = 17, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_0 = 18, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_1 = 19, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_2 = 20, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_3 = 21, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_4 = 22, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_5 = 23, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_6 = 24, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD1D_7 = 25, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_0 = 26, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_1 = 27, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_2 = 28, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_3 = 29, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_4 = 30, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_5 = 31, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_6 = 32, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD2D_7 = 33, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_0 = 34, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_1 = 35, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_2 = 36, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_3 = 37, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_4 = 38, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_5 = 39, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_6 = 40, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD3D_7 = 41, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_0 = 42, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_1 = 43, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_2 = 44, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_3 = 45, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_4 = 46, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_5 = 47, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_6 = 48, CDmeVertexData::FIELD_TEXCOORD, //VERTEX_ELEMENT_TEXCOORD4D_7 = 49, }; DmAttributeType_t g_atForSizeFloats[] = { AT_FLOAT, AT_VECTOR2, AT_VECTOR3, AT_VECTOR4 }; void ConvertMeshToDMX( CDmeMesh *pDmeMeshOut, CMesh *pMeshIn, bool bForce2DTexcoords ) { CDmeVertexData *pVertexData = pDmeMeshOut->FindOrCreateBaseState( "bind" ); pDmeMeshOut->SetCurrentBaseState( "bind" ); //pDmeMeshOut->SetBindBaseState( pVertexData ); pVertexData->AddVertexIndices( pMeshIn->m_nIndexCount ); pVertexData->FlipVCoordinate( false ); // Add the vertices for ( int a=0; am_nAttributeCount; ++a ) { // translate CMesh attributes to dme mesh attributes CMeshVertexAttribute &attrib = pMeshIn->m_pAttributes[ a ]; CDmeVertexDataBase::StandardFields_t field = g_AttribToField[ attrib.m_nType ]; int nSize = GetVertexElementSize( attrib.m_nType, VERTEX_COMPRESSION_NONE ); if ( bForce2DTexcoords && field == CDmeVertexData::FIELD_TEXCOORD ) { nSize = 8; } int nFloats = nSize / sizeof( float ); DmAttributeType_t at = g_atForSizeFloats[ nFloats - 1 ]; // add a vertex field const FieldIndex_t pIndex( pVertexData->CreateField( field ) ); pVertexData->AddVertexData( pIndex, pMeshIn->m_nVertexCount ); float *pFieldData = new float[ pMeshIn->m_nVertexCount * nFloats ]; float *pFieldStart = pFieldData; float *pVertStart = pMeshIn->m_pVerts + attrib.m_nOffsetFloats; for ( int v=0; vm_nVertexCount; ++v ) { Q_memcpy( pFieldStart, pVertStart, nSize ); pFieldStart += nFloats; pVertStart += pMeshIn->m_nVertexStrideFloats; } pVertexData->SetVertexData( pIndex, 0, pMeshIn->m_nVertexCount, at, pFieldData ); delete []pFieldData; pVertexData->SetVertexIndices( pIndex, 0, pMeshIn->m_nIndexCount, (int*)pMeshIn->m_pIndices ); } // Add a material CDmeMaterial *pMaterial = CreateElement< CDmeMaterial >( "material", pDmeMeshOut->GetFileId() ); pMaterial->SetMaterial( pMeshIn->m_materialName ); // Add a face set CDmeFaceSet *pFaceSet = CreateElement< CDmeFaceSet >( "faceSet", pDmeMeshOut->GetFileId() ); int nFaceSetIndices = ( pMeshIn->m_nIndexCount / 3 ) * 4; pFaceSet->AddIndices( nFaceSetIndices ); int nIndexCounter = 0; for ( int i=0; iSetIndex( i, nIndexCounter++ ); pFaceSet->SetIndex( i + 1, nIndexCounter++ ); pFaceSet->SetIndex( i + 2, nIndexCounter++ ); pFaceSet->SetIndex( i + 3, -1 ); } //pFaceSet->SetIndices( 0, faceSetIndices.Count(), faceSetIndices.Base() ); pFaceSet->SetMaterial( pMaterial ); pDmeMeshOut->AddFaceSet( pFaceSet ); } bool SaveMeshesToDMX( CUtlVector &inputMeshes, const char *pDMXFile, bool bForce2DTexcoords ) { CDisableUndoScopeGuard guard; DmFileId_t dmFileId = g_pDataModel->FindOrCreateFileId( pDMXFile ); CDmElement *pRoot = CreateElement< CDmElement >( "root", dmFileId ); CDmeModel *pModel = CreateElement< CDmeModel >( "model", dmFileId ); pRoot->SetValue( "skeleton", pModel ); pRoot->SetValue( "model", pModel ); int nMeshes = inputMeshes.Count(); for ( int m=0; m( "obj", pRoot->GetFileId() ); Assert( pDmeDag ); CDmeMesh *pDmeMesh = CreateElement< CDmeMesh >( "obj", pRoot->GetFileId() ); Assert( pDmeMesh ); pDmeDag->SetShape( pDmeMesh ); pModel->AddJoint( pDmeDag ); pModel->AddChild( pDmeDag ); ConvertMeshToDMX( pDmeMesh, inputMeshes[ m ], bForce2DTexcoords ); } pModel->CaptureJointsToBaseState( "bind" ); const char *pFileFormat = "model"; if ( !g_pDataModel->SaveToFile( pDMXFile, NULL, NULL, pFileFormat, pRoot ) ) { Warning( "SaveMeshesToDMX: SaveToFile \"%s\" failed!\n", pDMXFile ); return false; } return true; }