uid issue
This commit is contained in:
2140
dmeutils/dmanimutils.cpp
Normal file
2140
dmeutils/dmanimutils.cpp
Normal file
File diff suppressed because it is too large
Load Diff
33
dmeutils/dmeutils.vpc
Normal file
33
dmeutils/dmeutils.vpc
Normal file
@ -0,0 +1,33 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// DMEUTILS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR ".."
|
||||
$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;DMEUTILS_LIB"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "dmeutils"
|
||||
{
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\dmeutils\dmmeshutils.h"
|
||||
$File "$SRCDIR\public\dmeutils\dmanimutils.h"
|
||||
}
|
||||
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "dmmeshutils.cpp"
|
||||
$File "dmanimutils.cpp"
|
||||
$File "loadfromdmx.cpp"
|
||||
$File "savetodmx.cpp"
|
||||
}
|
||||
}
|
3933
dmeutils/dmmeshutils.cpp
Normal file
3933
dmeutils/dmmeshutils.cpp
Normal file
File diff suppressed because it is too large
Load Diff
487
dmeutils/loadfromdmx.cpp
Normal file
487
dmeutils/loadfromdmx.cpp
Normal file
@ -0,0 +1,487 @@
|
||||
//=========== Copyright <20> Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Mesh class dmx loading 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 "dmeutils/dmmeshutils.h"
|
||||
#include "meshutils/mesh.h"
|
||||
|
||||
|
||||
#define MAX_BIND_POSE_BONES 256
|
||||
struct LoadMeshInfo_t
|
||||
{
|
||||
CDmeModel *m_pModel;
|
||||
float m_flScale;
|
||||
int *m_pBoneRemap;
|
||||
matrix3x4_t m_pBindPose[MAX_BIND_POSE_BONES];
|
||||
};
|
||||
|
||||
class CDMXLoader
|
||||
{
|
||||
public:
|
||||
bool LoadVertices( CDmeDag *pDmeDag, CDmeVertexData *pBindState, const matrix3x4_t& mat, float flScale, int nBoneAssign, int *pBoneRemap, int nStartingUniqueCount );
|
||||
bool LoadMesh( CDmeDag *pDmeDag, CDmeMesh *pMesh, CDmeVertexData *pBindState, const matrix3x4_t& mat, float flScale,
|
||||
int nBoneAssign, int *pBoneRemap );
|
||||
bool LoadMesh( CDmeMesh *pMesh, CDmeDag *pDag, const matrix3x4_t &dagToBindPose = g_MatrixIdentity, float flScale = 1.0f, int nBoneAssign = -1, int *pBoneRemap = NULL, const CUtlVector< CUtlString > *pDeltaNames = NULL );
|
||||
bool LoadMeshes( const LoadMeshInfo_t &info, CDmeDag *pDag, const matrix3x4_t &parentToBindPose, int nBoneAssign );
|
||||
bool LoadMeshes( CDmeModel *pModel, float flScale, int *pBoneRemap = NULL );
|
||||
bool LoadMaterialGroups( CDmeMaterialGroupList *pMaterialGroupList );
|
||||
bool LoadDMX( const char *pDMXFile );
|
||||
CUtlVector<CMesh*> &GetOutputMeshes() { return m_outputMeshes; }
|
||||
CUtlVector< CDmeDag* > &GetOutputDmeDags() { return m_OutputDmeDags; }
|
||||
|
||||
private:
|
||||
CUtlVector<CMesh*> m_outputMeshes;
|
||||
CUtlVector< CDmeDag* > m_OutputDmeDags; // DAG per mesh, when not collapsing meshes
|
||||
};
|
||||
|
||||
void GenerateAttributesFromVertexData( CMeshVertexAttribute *pAttributes, int &nAttributes, int &nVertexStrideFloats, CDmeVertexData *pBindState )
|
||||
{
|
||||
const CUtlVector<Vector> &positions = pBindState->GetPositionData( );
|
||||
const CUtlVector<Vector> &normals = pBindState->GetNormalData( );
|
||||
const CUtlVector<Vector2D> &texcoords = pBindState->GetTextureCoordData( );
|
||||
const CUtlVector<Vector4D> &tangents = pBindState->GetTangentData( );
|
||||
const CUtlVector<Color> &colors = pBindState->GetColorData();
|
||||
|
||||
int nLocalAttributes = 0;
|
||||
nVertexStrideFloats = 0;
|
||||
if ( positions.Count() )
|
||||
{
|
||||
pAttributes[ nLocalAttributes ].m_nOffsetFloats = nVertexStrideFloats;
|
||||
pAttributes[ nLocalAttributes ].m_nType = VERTEX_ELEMENT_POSITION;
|
||||
nLocalAttributes ++;
|
||||
nVertexStrideFloats += 3;
|
||||
|
||||
if ( nLocalAttributes > nAttributes )
|
||||
goto endGetAttributes;
|
||||
}
|
||||
if ( normals.Count() )
|
||||
{
|
||||
pAttributes[ nLocalAttributes ].m_nOffsetFloats = nVertexStrideFloats;
|
||||
pAttributes[ nLocalAttributes ].m_nType = VERTEX_ELEMENT_NORMAL;
|
||||
nLocalAttributes ++;
|
||||
nVertexStrideFloats += 3;
|
||||
|
||||
if ( nLocalAttributes > nAttributes )
|
||||
goto endGetAttributes;
|
||||
}
|
||||
if ( texcoords.Count() )
|
||||
{
|
||||
pAttributes[ nLocalAttributes ].m_nOffsetFloats = nVertexStrideFloats;
|
||||
pAttributes[ nLocalAttributes ].m_nType = VERTEX_ELEMENT_TEXCOORD2D_0;
|
||||
nLocalAttributes ++;
|
||||
nVertexStrideFloats += 2;
|
||||
|
||||
if ( nLocalAttributes > nAttributes )
|
||||
goto endGetAttributes;
|
||||
}
|
||||
if ( tangents.Count() )
|
||||
{
|
||||
pAttributes[ nLocalAttributes ].m_nOffsetFloats = nVertexStrideFloats;
|
||||
pAttributes[ nLocalAttributes ].m_nType = VERTEX_ELEMENT_TANGENT_WITH_FLIP;
|
||||
nLocalAttributes ++;
|
||||
nVertexStrideFloats += 4;
|
||||
|
||||
if ( nLocalAttributes > nAttributes )
|
||||
goto endGetAttributes;
|
||||
}
|
||||
if ( colors.Count() )
|
||||
{
|
||||
pAttributes[ nLocalAttributes ].m_nOffsetFloats = nVertexStrideFloats;
|
||||
pAttributes[ nLocalAttributes ].m_nType = VERTEX_ELEMENT_COLOR;
|
||||
nLocalAttributes ++;
|
||||
nVertexStrideFloats += 1;
|
||||
|
||||
if ( nLocalAttributes > nAttributes )
|
||||
goto endGetAttributes;
|
||||
}
|
||||
|
||||
endGetAttributes:
|
||||
nAttributes = nLocalAttributes;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Convert a single CDmeMesh to a CMesh
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ConvertMeshFromDMX( CMesh *pMeshOut, CDmeMesh *pDmeMesh )
|
||||
{
|
||||
if ( !pMeshOut || !pDmeMesh )
|
||||
return false;
|
||||
|
||||
CDmeVertexData *pDmeBindBaseState = pDmeMesh->GetBindBaseState();
|
||||
if ( !pDmeBindBaseState )
|
||||
return false;
|
||||
|
||||
CDmeDag *pDmeDag = pDmeMesh->GetParent();
|
||||
if ( !pDmeDag )
|
||||
return false;
|
||||
|
||||
matrix3x4_t mShapeToWorld;
|
||||
pDmeDag->GetShapeToWorldTransform( mShapeToWorld );
|
||||
|
||||
CDMXLoader dmxLoader;
|
||||
if ( dmxLoader.LoadMesh( pDmeDag, pDmeMesh, pDmeBindBaseState, mShapeToWorld, 1.0f, 0, NULL ) )
|
||||
{
|
||||
CUtlVector< CMesh * > &outputMeshes = dmxLoader.GetOutputMeshes();
|
||||
if ( outputMeshes.Count() <= 0 )
|
||||
return false;
|
||||
|
||||
DuplicateMesh( pMeshOut, *outputMeshes[0] );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads the mesh data from the DMX data
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDMXLoader::LoadMesh( CDmeDag *pDmeDag, CDmeMesh *pMesh, CDmeVertexData *pBindState, const matrix3x4_t& mat, float flScale,
|
||||
int nBoneAssign, int *pBoneRemap )
|
||||
{
|
||||
matrix3x4_t normalMat;
|
||||
MatrixInverseTranspose( mat, normalMat );
|
||||
|
||||
const CUtlVector<Vector> &positions = pBindState->GetPositionData( );
|
||||
const CUtlVector<Vector> &normals = pBindState->GetNormalData( );
|
||||
const CUtlVector<Vector2D> &texcoords = pBindState->GetTextureCoordData( );
|
||||
const CUtlVector<Vector4D> &tangents = pBindState->GetTangentData( );
|
||||
const CUtlVector<Color> &colors = pBindState->GetColorData();
|
||||
|
||||
bool bHasPosition = ( positions.Count() > 0 );
|
||||
bool bHasNormal = ( normals.Count() > 0 );
|
||||
bool bHasTexcoord = ( texcoords.Count() > 0 );
|
||||
bool bHasTangent = ( tangents.Count() > 0 );
|
||||
bool bHasColor = ( colors.Count() > 0 );
|
||||
bool bFlipVCoordinate = pBindState->IsVCoordinateFlipped();
|
||||
|
||||
int nAttributes = 32;
|
||||
int nVertexStrideFloats = 0;
|
||||
CMeshVertexAttribute attributes[ 32 ];
|
||||
GenerateAttributesFromVertexData( attributes, nAttributes, nVertexStrideFloats, pBindState );
|
||||
|
||||
// Create a mesh per face set
|
||||
int nFaceSetCount = pMesh->FaceSetCount();
|
||||
for ( int i = 0; i < nFaceSetCount; ++i )
|
||||
{
|
||||
CDmeFaceSet *pFaceSet = pMesh->GetFaceSet( i );
|
||||
CDmeMaterial *pMaterial = pFaceSet->GetMaterial();
|
||||
|
||||
int nIndexCount = pFaceSet->NumIndices();
|
||||
int nTrueIndexCount = 0;
|
||||
int nFirstIndex = 0;
|
||||
while( nFirstIndex < nIndexCount )
|
||||
{
|
||||
int nVertexCount = pFaceSet->GetNextPolygonVertexCount( nFirstIndex );
|
||||
int nOutCount = ( nVertexCount - 2 ) * 3;
|
||||
nTrueIndexCount += nOutCount;
|
||||
nFirstIndex += nVertexCount + 1;
|
||||
}
|
||||
|
||||
// Each face set is an individual mesh for now
|
||||
CMesh *pUtilMesh = new CMesh();
|
||||
|
||||
// Allocate space for VB/IB/Attrib
|
||||
pUtilMesh->AllocateMesh( nTrueIndexCount, nTrueIndexCount, nVertexStrideFloats, attributes, nAttributes );
|
||||
uint32 *pUtilIndices = pUtilMesh->m_pIndices;
|
||||
int nUtilIndices = 0;
|
||||
|
||||
// Set material name
|
||||
pUtilMesh->m_materialName = pMaterial->GetMaterialName();
|
||||
|
||||
// Set vertices and indices
|
||||
nFirstIndex = 0;
|
||||
while( nFirstIndex < nIndexCount )
|
||||
{
|
||||
int nVertexCount = pFaceSet->GetNextPolygonVertexCount( nFirstIndex );
|
||||
|
||||
if ( nVertexCount >= 3 )
|
||||
{
|
||||
int nOutCount = ( nVertexCount - 2 ) * 3;
|
||||
int pIndices[ 128 ];// = ( int* )_alloca( nOutCount * sizeof( uint32 ) );
|
||||
Assert( nOutCount <= 128 );
|
||||
pMesh->ComputeTriangulatedIndices( pBindState, pFaceSet, nFirstIndex, pIndices, nOutCount );
|
||||
|
||||
for ( int i=0; i<nOutCount; ++i )
|
||||
{
|
||||
float *pUtilVertex = pUtilMesh->GetVertex( nUtilIndices );
|
||||
int nVertexOffset = 0;
|
||||
int iVertIndex = pIndices[ i ];
|
||||
|
||||
if ( bHasPosition )
|
||||
{
|
||||
int nI = pBindState->GetPositionIndex( iVertIndex );
|
||||
|
||||
Vector vTrans;
|
||||
VectorTransform( positions[ nI ], mat, vTrans );
|
||||
vTrans *= flScale;
|
||||
|
||||
Q_memcpy( pUtilVertex + nVertexOffset, &vTrans, sizeof( Vector ) );
|
||||
nVertexOffset += 3;
|
||||
}
|
||||
|
||||
if ( bHasNormal )
|
||||
{
|
||||
int nI = pBindState->GetNormalIndex( iVertIndex );
|
||||
|
||||
Vector vTrans;
|
||||
VectorRotate( normals[ nI ], normalMat, vTrans );
|
||||
VectorNormalize( vTrans );
|
||||
|
||||
Q_memcpy( pUtilVertex + nVertexOffset, &vTrans, sizeof( Vector ) );
|
||||
nVertexOffset += 3;
|
||||
}
|
||||
|
||||
if ( bHasTexcoord )
|
||||
{
|
||||
int nI = pBindState->GetTexCoordIndex( iVertIndex );
|
||||
|
||||
Vector2D vTrans;
|
||||
vTrans = texcoords[ nI ];
|
||||
if ( bFlipVCoordinate )
|
||||
{
|
||||
vTrans.y = 1.0f - vTrans.y;
|
||||
}
|
||||
|
||||
Q_memcpy( pUtilVertex + nVertexOffset, &vTrans, sizeof( Vector2D ) );
|
||||
nVertexOffset += 2;
|
||||
}
|
||||
|
||||
if ( bHasTangent )
|
||||
{
|
||||
int nI = pBindState->GetTangentIndex( iVertIndex );
|
||||
|
||||
Vector vTrans;
|
||||
VectorRotate( tangents[ nI ].AsVector3D(), normalMat, vTrans );
|
||||
VectorNormalize( vTrans );
|
||||
Vector4D vTrans4D( vTrans.x, vTrans.y, vTrans.z, tangents[ nI ].w );
|
||||
|
||||
Q_memcpy( pUtilVertex + nVertexOffset, &vTrans4D, sizeof( Vector4D ) );
|
||||
nVertexOffset += 4;
|
||||
}
|
||||
|
||||
if ( bHasColor )
|
||||
{
|
||||
int nI = pBindState->GetColorIndex( iVertIndex );
|
||||
Q_memcpy( pUtilVertex + nVertexOffset, &colors[ nI ], sizeof( uint32 ) );
|
||||
nVertexOffset += 1;
|
||||
}
|
||||
|
||||
pUtilIndices[ nUtilIndices ] = nUtilIndices;
|
||||
nUtilIndices ++;
|
||||
}
|
||||
}
|
||||
|
||||
nFirstIndex += nVertexCount + 1; // -1 between faces, to skip over it
|
||||
}
|
||||
|
||||
// Clean and weld the mesh
|
||||
float flEpsilon = 1e-6;
|
||||
float *pEpsilons = new float[ pUtilMesh->m_nVertexStrideFloats ];
|
||||
for ( int e=0; e<pUtilMesh->m_nVertexStrideFloats; ++e )
|
||||
{
|
||||
pEpsilons[ e ] = flEpsilon;
|
||||
}
|
||||
CMesh tempMesh;
|
||||
WeldVertices( &tempMesh, *pUtilMesh, pEpsilons, pUtilMesh->m_nVertexStrideFloats );
|
||||
delete []pEpsilons;
|
||||
pUtilMesh->FreeAllMemory();
|
||||
CleanMesh( pUtilMesh, tempMesh );
|
||||
tempMesh.FreeAllMemory();
|
||||
|
||||
m_OutputDmeDags.AddToTail( pDmeDag );
|
||||
m_outputMeshes.AddToTail( pUtilMesh );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Method used to add mesh data
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDMXLoader::LoadMeshes( const LoadMeshInfo_t &info, CDmeDag *pDag, const matrix3x4_t &parentToBindPose, int nBoneAssign )
|
||||
{
|
||||
// We want to create an aggregate matrix transforming from this dag to its closest
|
||||
// parent which actually is an animated joint. This is done so we can autoskin
|
||||
// meshes to their closest parents if they have not been skinned.
|
||||
matrix3x4_t dagToBindPose;
|
||||
int nFoundIndex = info.m_pModel->GetJointIndex( pDag );
|
||||
if ( nFoundIndex >= 0 /* && ( pDag == info.m_pModel || CastElement< CDmeJoint >( pDag ) ) */ )
|
||||
{
|
||||
nBoneAssign = nFoundIndex;
|
||||
}
|
||||
|
||||
if ( nFoundIndex >= 0 )
|
||||
{
|
||||
ConcatTransforms( parentToBindPose, info.m_pBindPose[nFoundIndex], dagToBindPose );
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: This isn't particularly kosher; we're using the current pose instead of the bind pose
|
||||
// because there's no transform in the bind pose
|
||||
matrix3x4_t dagToParent;
|
||||
pDag->GetTransform()->GetTransform( dagToParent );
|
||||
ConcatTransforms( parentToBindPose, dagToParent, dagToBindPose );
|
||||
}
|
||||
|
||||
CDmeMesh *pMesh = CastElement< CDmeMesh >( pDag->GetShape() );
|
||||
if ( pMesh )
|
||||
{
|
||||
CDmeVertexData *pBindState = pMesh->FindBaseState( "bind" );
|
||||
if ( !pBindState )
|
||||
return false;
|
||||
|
||||
if ( !LoadMesh( pDag, pMesh, pBindState, dagToBindPose, info.m_flScale, nBoneAssign, info.m_pBoneRemap ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
int nCount = pDag->GetChildCount();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeDag *pChild = pDag->GetChild( i );
|
||||
if ( !LoadMeshes( info, pChild, dagToBindPose, nBoneAssign ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Method used to add mesh data
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDMXLoader::LoadMeshes( CDmeModel *pModel, float flScale, int *pBoneRemap )
|
||||
{
|
||||
matrix3x4_t mat;
|
||||
SetIdentityMatrix( mat );
|
||||
|
||||
LoadMeshInfo_t info;
|
||||
info.m_pModel = pModel;
|
||||
info.m_flScale = flScale;
|
||||
info.m_pBoneRemap = pBoneRemap;
|
||||
|
||||
CDmeTransformList *pBindPose = pModel->FindBaseState( "bind" );
|
||||
int nCount = pBindPose ? pBindPose->GetTransformCount() : pModel->GetJointCount();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeTransform *pTransform = pBindPose ? pBindPose->GetTransform(i) : pModel->GetJointTransform(i);
|
||||
|
||||
matrix3x4_t jointTransform;
|
||||
pTransform->GetTransform( info.m_pBindPose[i] );
|
||||
}
|
||||
|
||||
int nChildCount = pModel->GetChildCount();
|
||||
for ( int i = 0; i < nChildCount; ++i )
|
||||
{
|
||||
CDmeDag *pChild = pModel->GetChild( i );
|
||||
if ( !LoadMeshes( info, pChild, mat, -1 ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDMXLoader::LoadDMX( const char *pDMXFile )
|
||||
{
|
||||
bool bRet = true;
|
||||
DmFileId_t fileId;
|
||||
|
||||
// When reading, keep the CRLF; this will make ReadFile read it in binary format
|
||||
// and also append a couple 0s to the end of the buffer.
|
||||
CDmElement *pRoot;
|
||||
if ( g_pDataModel->RestoreFromFile( pDMXFile, NULL, NULL, &pRoot ) == DMFILEID_INVALID )
|
||||
return false;
|
||||
|
||||
CDmeModel *pModel = pRoot->GetValueElement< CDmeModel >( "model" );
|
||||
if ( !LoadMeshes( pModel, 1.0f, NULL ) )
|
||||
return false;
|
||||
|
||||
fileId = pRoot->GetFileId();
|
||||
g_pDataModel->RemoveFileId( fileId );
|
||||
return bRet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main entry point for loading DMX files
|
||||
//-----------------------------------------------------------------------------
|
||||
bool LoadMeshesFromDMX( CUtlVector<CMesh*> &outputMeshes, const char *pDMXFile )
|
||||
{
|
||||
CDMXLoader loader;
|
||||
if ( !loader.LoadDMX( pDMXFile ) )
|
||||
return false;
|
||||
|
||||
CUtlVector<CMesh*> &meshList = loader.GetOutputMeshes();
|
||||
outputMeshes.AddVectorToTail( meshList );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadMeshes( CUtlVector<CMesh*> &outputMeshes, CDmeModel *pModel, float flScale, int *pBoneRemap )
|
||||
{
|
||||
CDMXLoader loader;
|
||||
if ( !loader.LoadMeshes( pModel, flScale, pBoneRemap ) )
|
||||
return false;
|
||||
|
||||
CUtlVector<CMesh*> &meshList = loader.GetOutputMeshes();
|
||||
outputMeshes.AddVectorToTail( meshList );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// A stub that loads mesh without splitting position stream by tangent/uv/etc. in source2; here it just loads the mesh as usual
|
||||
bool LoadCollisionMeshes( CUtlVector< CMesh* > &outputMeshes, CUtlVector< CDmeDag* > &outputDags, CDmeModel *pModel, float flScale )
|
||||
{
|
||||
CDMXLoader loader;//( OUTPUT_MESH_TRIANGLE_MESH );
|
||||
//loader.SetFieldFilter( nFieldMask );
|
||||
//loader.SetCollapseDeltaMeshes( true );
|
||||
//loader.SetKeepPositionConnectivity( true ); // this setting will make loader not merge/split vertices we don't, thus maintaining original connectivity of the mesh
|
||||
//loader.SetCollapseMeshesByMaterial( false );
|
||||
if ( !loader.LoadMeshes( pModel, flScale ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outputMeshes.AddVectorToTail( loader.GetOutputMeshes() );
|
||||
outputDags.AddVectorToTail( loader.GetOutputDmeDags() );
|
||||
return true;
|
||||
}
|
212
dmeutils/savetodmx.cpp
Normal file
212
dmeutils/savetodmx.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
//=========== Copyright <20> 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; a<pMeshIn->m_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; v<pMeshIn->m_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; i<nFaceSetIndices; i+=4 )
|
||||
{
|
||||
pFaceSet->SetIndex( 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<CMesh*> &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<nMeshes; ++m )
|
||||
{
|
||||
CDmeDag *pDmeDag = CreateElement< CDmeDag >( "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;
|
||||
}
|
82
dmeutils/test.py
Normal file
82
dmeutils/test.py
Normal file
@ -0,0 +1,82 @@
|
||||
import vs
|
||||
import vs.dmeutils
|
||||
from vs import dmeutils
|
||||
|
||||
animUtils = dmeutils.CDmAnimUtils
|
||||
DagList = dmeutils.DagList
|
||||
|
||||
|
||||
def AreVectorsEqual( vectorA, vectorB ):
|
||||
if ( vectorA.x != vectorB.y ):
|
||||
return False
|
||||
if ( vectorA.y != vectorB.y ):
|
||||
return False
|
||||
if ( vectorA.z != vectorB.z ):
|
||||
return False
|
||||
return True
|
||||
|
||||
root = vs.g_pDataModel.RestoreFromFile( "./test.dmx" )
|
||||
print root
|
||||
|
||||
# Get the cube and sphere dag nodes from the scene
|
||||
cubeDag = root.model.children[ 0 ]
|
||||
print cubeDag
|
||||
sphereDag = root.model.children[ 1 ]
|
||||
print sphereDag
|
||||
|
||||
# Test getting the position and rotatation of a dag
|
||||
cubePos = animUtils.GetDagPosition( DagList( cubeDag ), vs.TS_WORLD_SPACE )
|
||||
cubeRot = animUtils.GetDagRotation( DagList( cubeDag ), vs.TS_WORLD_SPACE )
|
||||
print cubePos
|
||||
print cubeRot
|
||||
|
||||
# Create a test dag
|
||||
testDag = animUtils.CreateDag( "testDag", vs.vec3_origin, vs.quat_identity )
|
||||
print testDag
|
||||
|
||||
# Test creating a dag list with multiple dag nodes
|
||||
dagList = vs.DagList( cubeDag, sphereDag, testDag )
|
||||
|
||||
# Move the test dag
|
||||
animUtils.TransformDagNodes( vs.Vector( 5, 5, 5 ), vs.quat_identity, DagList( testDag ), False, vs.dmeutils.TS_WORLD_SPACE )
|
||||
testPos = animUtils.GetDagPosition( DagList( testDag ), vs.TS_WORLD_SPACE )
|
||||
print testPos
|
||||
|
||||
# Constrain the test dag, this should overwrite the position of the test dag
|
||||
testConstraint = animUtils.CreatePointConstraint( "testConstraint", testDag, DagList( cubeDag ), False, 1.0 )
|
||||
print testConstraint
|
||||
|
||||
testPos = animUtils.GetDagPosition( DagList( testDag ), vs.TS_WORLD_SPACE )
|
||||
print testPos
|
||||
|
||||
# Generate log samples for the test dag evaluating the constraint
|
||||
animUtils.GenerateLogSamples( testDag, None, True, True )
|
||||
|
||||
|
||||
# Make the sphere a cild of the cube, but keep its world space
|
||||
# position, so the position should not change with this operation
|
||||
print "Re-parent with maintain world space, following position should be the same."
|
||||
spherePos = vs.CDmAnimUtils_GetDagPosition( vs.DagList( sphereDag ), vs.TS_WORLD_SPACE )
|
||||
print spherePos
|
||||
|
||||
vs.dmeutils.CDmAnimUtils_ReParentDagNode( sphereDag, cubeDag, True, vs.REPARENT_LOGS_MAINTAIN_WORLD )
|
||||
spherePos = vs.CDmAnimUtils_GetDagPosition( vs.DagList( sphereDag ), vs.TS_WORLD_SPACE )
|
||||
print spherePos
|
||||
|
||||
# Now move the cube, this should change the position of both the cube
|
||||
# and the sphere since the sphere should now be a child of the cube.
|
||||
print "Now the world space position of the sphere should have changed since its parent position changed"
|
||||
vs.dmeutils.CDmAnimUtils_MoveDagNodes( vs.Vector( 0, 0, 10 ), vs.DagList( cubeDag ), True, vs.dmeutils.TS_WORLD_SPACE )
|
||||
spherePos = vs.CDmAnimUtils_GetDagPosition( vs.DagList( sphereDag ), vs.TS_WORLD_SPACE )
|
||||
print spherePos
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user