|
|
//====== Copyright � 1996-2004, 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
FIELD_CLOTH_ENABLE, 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 have cloth_enable data?
bool HasClothData(); // 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;
// Reskins the vertex data to new bones
// The joint index remap maps an initial bone index to a new bone index
void Reskin( const int *pJointTransformIndexRemap );
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, bool bUseNormalForSign = false );
// Updates existing data or generates new data
void UpdateWrinkleDelta( CDmeVertexData *pBindState, float flOldScale, float flNewScale );
// 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; CDmaVar< bool > m_bRenderVerts;
private: virtual bool IsVertexDeltaData() const { return true; }
// Computes max positional delta length
float ComputeMaxDeflection( ); };
#endif // DMEVERTEXDATA_H
|