You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
12 KiB
337 lines
12 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// A class representing vertex data
|
|
//
|
|
//=============================================================================
|
|
|
|
#ifndef DMEVERTEXDATA_H
|
|
#define DMEVERTEXDATA_H
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "datamodel/dmelement.h"
|
|
#include "datamodel/dmattribute.h"
|
|
#include "datamodel/dmattributevar.h"
|
|
#include "mathlib/vector.h"
|
|
#include "Color.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Forward declarations
|
|
//-----------------------------------------------------------------------------
|
|
class Vector;
|
|
class Vector4D;
|
|
class Color;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Used to represent fields
|
|
//-----------------------------------------------------------------------------
|
|
typedef int FieldIndex_t;
|
|
|
|
|
|
class CDmeVertexDataBase : public CDmElement
|
|
{
|
|
DEFINE_ELEMENT( CDmeVertexDataBase, CDmElement );
|
|
|
|
public:
|
|
// NOTE: If you add fields to this, add to g_pStandardFieldNames in dmevertexdata.cpp
|
|
enum StandardFields_t
|
|
{
|
|
FIELD_POSITION,
|
|
FIELD_NORMAL,
|
|
FIELD_TANGENT,
|
|
FIELD_TEXCOORD,
|
|
FIELD_COLOR,
|
|
FIELD_JOINT_WEIGHTS,
|
|
FIELD_JOINT_INDICES,
|
|
FIELD_BALANCE, // Used by left/right delta states
|
|
FIELD_MORPH_SPEED, // Used to author morph speeds
|
|
FIELD_WRINKLE, // Used to author morphed wrinklemaps
|
|
FIELD_WEIGHT, // Weight is just the different between the base position and the delta position
|
|
STANDARD_FIELD_COUNT,
|
|
};
|
|
|
|
// resolve internal data from changed attributes
|
|
virtual void Resolve();
|
|
|
|
// Returns the number of joints per vertex
|
|
int JointCount() const;
|
|
|
|
// Vertex accessors
|
|
int VertexCount() const;
|
|
const Vector& GetPosition( int nVertexIndex ) const;
|
|
const Vector& GetNormal( int nVertexIndex ) const;
|
|
const Vector2D& GetTexCoord( int nVertexIndex ) const;
|
|
const Vector4D& GetTangent( int nVertexIndex ) const;
|
|
const Color& GetColor( int nVertexIndex ) const;
|
|
const float *GetJointWeights( int nVertexIndex ) const;
|
|
const float *GetJointPositionWeights( int nPositionIndex ) const;
|
|
const int *GetJointIndices( int nVertexIndex ) const;
|
|
const int *GetJointPositionIndices( int nPositionIndex ) const;
|
|
float GetBalance( int nVertexIndex ) const;
|
|
float GetMorphSpeed( int nVertexIndex ) const;
|
|
float GetWrinkle( int nVertexIndex ) const;
|
|
float GetWeight( int nVertexIndex ) const;
|
|
|
|
// Returns indices into the various fields
|
|
int GetPositionIndex( int nVertexIndex ) const;
|
|
int GetNormalIndex( int nVertexIndex ) const;
|
|
int GetTangentIndex( int nVertexIndex ) const;
|
|
int GetTexCoordIndex( int nVertexIndex ) const;
|
|
int GetColorIndex( int nVertexIndex ) const;
|
|
int GetBalanceIndex( int nVertexIndex ) const;
|
|
int GetMorphSpeedIndex( int nVertexIndex ) const;
|
|
int GetWrinkleIndex( int nVertexIndex ) const;
|
|
int GetWeightIndex( int nVertexIndex ) const;
|
|
|
|
// Creates a new vertex field. NOTE: This cannot be used to create joint weights + indices
|
|
template< class T >
|
|
FieldIndex_t CreateField( const char *pFieldName );
|
|
FieldIndex_t CreateField( const char *pFieldName, DmAttributeType_t type );
|
|
FieldIndex_t CreateField( StandardFields_t fieldId );
|
|
|
|
// Use this to create vertex fields for joint weights + indices
|
|
void CreateJointWeightsAndIndices( int nJointCount, FieldIndex_t *pJointWeightsField, FieldIndex_t *pJointIndicesField );
|
|
|
|
// Returns the field index of a particular field
|
|
FieldIndex_t FindFieldIndex( const char *pFieldName ) const;
|
|
FieldIndex_t FindFieldIndex( StandardFields_t nFieldIndex ) const;
|
|
|
|
// Adds a new vertex, returns the vertex index
|
|
// NOTE: This will also add vertex indices for DmeMeshDeltaData
|
|
int AddVertexData( FieldIndex_t nFieldIndex, int nCount );
|
|
|
|
// Sets vertex data
|
|
void SetVertexData( FieldIndex_t nFieldIndex, int nFirstVertex, int nCount, DmAttributeType_t valueType, const void *pData );
|
|
void SetVertexIndices( FieldIndex_t nFieldIndex, int nFirstIndex, int nCount, const int *pIndices );
|
|
|
|
// Removes all vertex data associated with a particular field
|
|
void RemoveAllVertexData( FieldIndex_t nFieldIndex );
|
|
|
|
// Returns arbitrary vertex + index data
|
|
CDmAttribute* GetVertexData( FieldIndex_t nFieldIndex );
|
|
const CDmAttribute* GetVertexData( FieldIndex_t nFieldIndex ) const;
|
|
CDmAttribute* GetIndexData( FieldIndex_t nFieldIndex );
|
|
const CDmAttribute* GetIndexData( FieldIndex_t nFieldIndex ) const;
|
|
|
|
// Returns well-known vertex data
|
|
const CUtlVector<Vector> &GetPositionData( ) const;
|
|
const CUtlVector<Vector> &GetNormalData( ) const;
|
|
const CUtlVector<Vector4D> &GetTangentData( ) const;
|
|
const CUtlVector<Vector2D> &GetTextureCoordData( ) const;
|
|
const CUtlVector<Color> &GetColorData( ) const;
|
|
const float *GetJointWeightData( int nDataIndex ) const;
|
|
const int *GetJointIndexData( int nDataIndex ) const;
|
|
const CUtlVector<float> &GetBalanceData( ) const;
|
|
const CUtlVector<float> &GetMorphSpeedData( ) const;
|
|
const CUtlVector<float> &GetWrinkleData( ) const;
|
|
const CUtlVector<float> &GetWeightData( ) const;
|
|
|
|
// Returns well-known index data
|
|
const CUtlVector<int> &GetVertexIndexData( FieldIndex_t nFieldIndex ) const;
|
|
const CUtlVector<int> &GetVertexIndexData( StandardFields_t fieldId ) const;
|
|
|
|
// Do we have skinning data?
|
|
bool HasSkinningData() const;
|
|
|
|
// Do we need tangent data? (Utility method for applications to know if they should call ComputeDefaultTangentData)
|
|
bool NeedsTangentData() const;
|
|
|
|
// Should we flip the V coordinates?
|
|
bool IsVCoordinateFlipped() const;
|
|
void FlipVCoordinate( bool bFlip );
|
|
|
|
// Returns an inverse map from vertex data index to vertex index
|
|
const CUtlVector< int > &FindVertexIndicesFromDataIndex( FieldIndex_t nFieldIndex, int nDataIndex );
|
|
const CUtlVector< int > &FindVertexIndicesFromDataIndex( StandardFields_t nFieldIndex, int nDataIndex );
|
|
|
|
int FieldCount() const;
|
|
|
|
const char *FieldName( int i ) const;
|
|
|
|
void CopyFrom( CDmeVertexDataBase *pSrc );
|
|
|
|
void CopyTo( CDmeVertexDataBase *pDst ) const;
|
|
|
|
protected:
|
|
struct FieldInfo_t
|
|
{
|
|
CUtlString m_Name;
|
|
CDmAttribute *m_pVertexData;
|
|
CDmAttribute* m_pIndexData;
|
|
CUtlVector< CUtlVector< int > > m_InverseMap;
|
|
bool m_bInverseMapDirty;
|
|
};
|
|
|
|
// Derived classes must inherit
|
|
virtual bool IsVertexDeltaData() const { Assert(0); return false; }
|
|
|
|
// Computes the vertex count ( min of the index buffers )
|
|
void ComputeFieldInfo();
|
|
|
|
// Computes the vertex count ( min of the index buffers )
|
|
void ComputeVertexCount();
|
|
|
|
// Updates info for fast lookups for well-known fields
|
|
void UpdateStandardFieldInfo( int nFieldIndex, const char *pFieldName, DmAttributeType_t attrType );
|
|
|
|
// Adds a field to the vertex format
|
|
void FindOrAddVertexField( const char *pFieldName );
|
|
|
|
// Returns the index of a particular field
|
|
int GetFieldIndex( int nVertexIndex, StandardFields_t nFieldIndex ) const;
|
|
// List of names of attributes containing vertex data
|
|
CDmaStringArray m_VertexFormat;
|
|
|
|
CDmaVar< int > m_nJointCount;
|
|
CDmaVar< bool > m_bFlipVCoordinates;
|
|
CUtlVector< FieldInfo_t > m_FieldInfo;
|
|
FieldIndex_t m_pStandardFieldIndex[STANDARD_FIELD_COUNT];
|
|
int m_nVertexCount;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Creates a particular vertex data field + associated index field
|
|
//-----------------------------------------------------------------------------
|
|
template< class T >
|
|
inline FieldIndex_t CDmeVertexDataBase::CreateField( const char *pFieldName )
|
|
{
|
|
return CreateField( pFieldName, CDmAttributeInfo< CUtlVector<T> >::AttributeType() );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a standard field index
|
|
//-----------------------------------------------------------------------------
|
|
inline FieldIndex_t CDmeVertexDataBase::FindFieldIndex( StandardFields_t nFieldIndex ) const
|
|
{
|
|
return m_pStandardFieldIndex[ nFieldIndex ];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Vertex field accessors
|
|
//-----------------------------------------------------------------------------
|
|
inline int CDmeVertexDataBase::VertexCount() const
|
|
{
|
|
return m_nVertexCount;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the number of joints per vertex
|
|
//-----------------------------------------------------------------------------
|
|
inline int CDmeVertexDataBase::JointCount() const
|
|
{
|
|
return m_nJointCount;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Should we flip the V coordinates?
|
|
//-----------------------------------------------------------------------------
|
|
inline bool CDmeVertexDataBase::IsVCoordinateFlipped() const
|
|
{
|
|
return m_bFlipVCoordinates;
|
|
}
|
|
|
|
inline void CDmeVertexDataBase::FlipVCoordinate( bool bFlip )
|
|
{
|
|
m_bFlipVCoordinates = bFlip;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns arbitrary vertex data
|
|
//-----------------------------------------------------------------------------
|
|
inline CDmAttribute* CDmeVertexDataBase::GetVertexData( FieldIndex_t nFieldIndex )
|
|
{
|
|
return m_FieldInfo[ nFieldIndex ].m_pVertexData;
|
|
}
|
|
|
|
inline const CDmAttribute* CDmeVertexDataBase::GetVertexData( FieldIndex_t nFieldIndex ) const
|
|
{
|
|
return m_FieldInfo[ nFieldIndex ].m_pVertexData;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns arbitrary index data
|
|
//-----------------------------------------------------------------------------
|
|
inline CDmAttribute* CDmeVertexDataBase::GetIndexData( FieldIndex_t nFieldIndex )
|
|
{
|
|
return m_FieldInfo[ nFieldIndex ].m_pIndexData;
|
|
}
|
|
|
|
inline const CDmAttribute* CDmeVertexDataBase::GetIndexData( FieldIndex_t nFieldIndex ) const
|
|
{
|
|
return m_FieldInfo[ nFieldIndex ].m_pIndexData;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Utility method for getting at various vertex field indices
|
|
//-----------------------------------------------------------------------------
|
|
inline int CDmeVertexDataBase::GetFieldIndex( int nVertexIndex, StandardFields_t nFieldId ) const
|
|
{
|
|
Assert( nVertexIndex < m_nVertexCount );
|
|
FieldIndex_t nFieldIndex = m_pStandardFieldIndex[nFieldId];
|
|
if ( nFieldIndex < 0 )
|
|
return -1;
|
|
|
|
CDmrArrayConst<int> indices( GetIndexData( nFieldIndex ) );
|
|
return indices[ nVertexIndex ];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Vertex Data for base states
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class CDmeVertexData : public CDmeVertexDataBase
|
|
{
|
|
DEFINE_ELEMENT( CDmeVertexData, CDmeVertexDataBase );
|
|
|
|
public:
|
|
// Adds a new vertex; creates a new entry in all vertex data fields
|
|
int AddVertexIndices( int nCount );
|
|
|
|
private:
|
|
virtual bool IsVertexDeltaData() const { return false; }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Vertex Data for delta states
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class CDmeVertexDeltaData : public CDmeVertexDataBase
|
|
{
|
|
DEFINE_ELEMENT( CDmeVertexDeltaData, CDmeVertexDataBase );
|
|
|
|
public:
|
|
// Computes wrinkle data from position deltas
|
|
// NOTE: Pass in negative scales to get 'compression', positive to get 'expansion'
|
|
void GenerateWrinkleDelta( CDmeVertexData *pBindState, float flScale, bool bOverwrite );
|
|
|
|
// Computes a float map which is the distance between the base and delta position
|
|
// The maximum distance any vertex is moved is returned
|
|
float GenerateWeightDelta( CDmeVertexData *pBindState );
|
|
|
|
CDmaVar< bool > m_bCorrected;
|
|
|
|
private:
|
|
virtual bool IsVertexDeltaData() const { return true; }
|
|
|
|
// Computes max positional delta length
|
|
float ComputeMaxDeflection( );
|
|
};
|
|
|
|
|
|
#endif // DMEVERTEXDATA_H
|