Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // A class representing vertex data
  4. //
  5. //=============================================================================
  6. #ifndef DMEVERTEXDATA_H
  7. #define DMEVERTEXDATA_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "datamodel/dmelement.h"
  12. #include "datamodel/dmattribute.h"
  13. #include "datamodel/dmattributevar.h"
  14. #include "mathlib/vector.h"
  15. #include "Color.h"
  16. //-----------------------------------------------------------------------------
  17. // Forward declarations
  18. //-----------------------------------------------------------------------------
  19. class Vector;
  20. class Vector4D;
  21. class Color;
  22. //-----------------------------------------------------------------------------
  23. // Used to represent fields
  24. //-----------------------------------------------------------------------------
  25. typedef int FieldIndex_t;
  26. class CDmeVertexDataBase : public CDmElement
  27. {
  28. DEFINE_ELEMENT( CDmeVertexDataBase, CDmElement );
  29. public:
  30. // NOTE: If you add fields to this, add to g_pStandardFieldNames in dmevertexdata.cpp
  31. enum StandardFields_t
  32. {
  33. FIELD_POSITION,
  34. FIELD_NORMAL,
  35. FIELD_TANGENT,
  36. FIELD_TEXCOORD,
  37. FIELD_COLOR,
  38. FIELD_JOINT_WEIGHTS,
  39. FIELD_JOINT_INDICES,
  40. FIELD_BALANCE, // Used by left/right delta states
  41. FIELD_MORPH_SPEED, // Used to author morph speeds
  42. FIELD_WRINKLE, // Used to author morphed wrinklemaps
  43. FIELD_WEIGHT, // Weight is just the different between the base position and the delta position
  44. STANDARD_FIELD_COUNT,
  45. };
  46. // resolve internal data from changed attributes
  47. virtual void Resolve();
  48. // Returns the number of joints per vertex
  49. int JointCount() const;
  50. // Vertex accessors
  51. int VertexCount() const;
  52. const Vector& GetPosition( int nVertexIndex ) const;
  53. const Vector& GetNormal( int nVertexIndex ) const;
  54. const Vector2D& GetTexCoord( int nVertexIndex ) const;
  55. const Vector4D& GetTangent( int nVertexIndex ) const;
  56. const Color& GetColor( int nVertexIndex ) const;
  57. const float *GetJointWeights( int nVertexIndex ) const;
  58. const float *GetJointPositionWeights( int nPositionIndex ) const;
  59. const int *GetJointIndices( int nVertexIndex ) const;
  60. const int *GetJointPositionIndices( int nPositionIndex ) const;
  61. float GetBalance( int nVertexIndex ) const;
  62. float GetMorphSpeed( int nVertexIndex ) const;
  63. float GetWrinkle( int nVertexIndex ) const;
  64. float GetWeight( int nVertexIndex ) const;
  65. // Returns indices into the various fields
  66. int GetPositionIndex( int nVertexIndex ) const;
  67. int GetNormalIndex( int nVertexIndex ) const;
  68. int GetTangentIndex( int nVertexIndex ) const;
  69. int GetTexCoordIndex( int nVertexIndex ) const;
  70. int GetColorIndex( int nVertexIndex ) const;
  71. int GetBalanceIndex( int nVertexIndex ) const;
  72. int GetMorphSpeedIndex( int nVertexIndex ) const;
  73. int GetWrinkleIndex( int nVertexIndex ) const;
  74. int GetWeightIndex( int nVertexIndex ) const;
  75. // Creates a new vertex field. NOTE: This cannot be used to create joint weights + indices
  76. template< class T >
  77. FieldIndex_t CreateField( const char *pFieldName );
  78. FieldIndex_t CreateField( const char *pFieldName, DmAttributeType_t type );
  79. FieldIndex_t CreateField( StandardFields_t fieldId );
  80. // Use this to create vertex fields for joint weights + indices
  81. void CreateJointWeightsAndIndices( int nJointCount, FieldIndex_t *pJointWeightsField, FieldIndex_t *pJointIndicesField );
  82. // Returns the field index of a particular field
  83. FieldIndex_t FindFieldIndex( const char *pFieldName ) const;
  84. FieldIndex_t FindFieldIndex( StandardFields_t nFieldIndex ) const;
  85. // Adds a new vertex, returns the vertex index
  86. // NOTE: This will also add vertex indices for DmeMeshDeltaData
  87. int AddVertexData( FieldIndex_t nFieldIndex, int nCount );
  88. // Sets vertex data
  89. void SetVertexData( FieldIndex_t nFieldIndex, int nFirstVertex, int nCount, DmAttributeType_t valueType, const void *pData );
  90. void SetVertexIndices( FieldIndex_t nFieldIndex, int nFirstIndex, int nCount, const int *pIndices );
  91. // Removes all vertex data associated with a particular field
  92. void RemoveAllVertexData( FieldIndex_t nFieldIndex );
  93. // Returns arbitrary vertex + index data
  94. CDmAttribute* GetVertexData( FieldIndex_t nFieldIndex );
  95. const CDmAttribute* GetVertexData( FieldIndex_t nFieldIndex ) const;
  96. CDmAttribute* GetIndexData( FieldIndex_t nFieldIndex );
  97. const CDmAttribute* GetIndexData( FieldIndex_t nFieldIndex ) const;
  98. // Returns well-known vertex data
  99. const CUtlVector<Vector> &GetPositionData( ) const;
  100. const CUtlVector<Vector> &GetNormalData( ) const;
  101. const CUtlVector<Vector4D> &GetTangentData( ) const;
  102. const CUtlVector<Vector2D> &GetTextureCoordData( ) const;
  103. const CUtlVector<Color> &GetColorData( ) const;
  104. const float *GetJointWeightData( int nDataIndex ) const;
  105. const int *GetJointIndexData( int nDataIndex ) const;
  106. const CUtlVector<float> &GetBalanceData( ) const;
  107. const CUtlVector<float> &GetMorphSpeedData( ) const;
  108. const CUtlVector<float> &GetWrinkleData( ) const;
  109. const CUtlVector<float> &GetWeightData( ) const;
  110. // Returns well-known index data
  111. const CUtlVector<int> &GetVertexIndexData( FieldIndex_t nFieldIndex ) const;
  112. const CUtlVector<int> &GetVertexIndexData( StandardFields_t fieldId ) const;
  113. // Do we have skinning data?
  114. bool HasSkinningData() const;
  115. // Do we need tangent data? (Utility method for applications to know if they should call ComputeDefaultTangentData)
  116. bool NeedsTangentData() const;
  117. // Should we flip the V coordinates?
  118. bool IsVCoordinateFlipped() const;
  119. void FlipVCoordinate( bool bFlip );
  120. // Returns an inverse map from vertex data index to vertex index
  121. const CUtlVector< int > &FindVertexIndicesFromDataIndex( FieldIndex_t nFieldIndex, int nDataIndex );
  122. const CUtlVector< int > &FindVertexIndicesFromDataIndex( StandardFields_t nFieldIndex, int nDataIndex );
  123. int FieldCount() const;
  124. const char *FieldName( int i ) const;
  125. void CopyFrom( CDmeVertexDataBase *pSrc );
  126. void CopyTo( CDmeVertexDataBase *pDst ) const;
  127. protected:
  128. struct FieldInfo_t
  129. {
  130. CUtlString m_Name;
  131. CDmAttribute *m_pVertexData;
  132. CDmAttribute* m_pIndexData;
  133. CUtlVector< CUtlVector< int > > m_InverseMap;
  134. bool m_bInverseMapDirty;
  135. };
  136. // Derived classes must inherit
  137. virtual bool IsVertexDeltaData() const { Assert(0); return false; }
  138. // Computes the vertex count ( min of the index buffers )
  139. void ComputeFieldInfo();
  140. // Computes the vertex count ( min of the index buffers )
  141. void ComputeVertexCount();
  142. // Updates info for fast lookups for well-known fields
  143. void UpdateStandardFieldInfo( int nFieldIndex, const char *pFieldName, DmAttributeType_t attrType );
  144. // Adds a field to the vertex format
  145. void FindOrAddVertexField( const char *pFieldName );
  146. // Returns the index of a particular field
  147. int GetFieldIndex( int nVertexIndex, StandardFields_t nFieldIndex ) const;
  148. // List of names of attributes containing vertex data
  149. CDmaStringArray m_VertexFormat;
  150. CDmaVar< int > m_nJointCount;
  151. CDmaVar< bool > m_bFlipVCoordinates;
  152. CUtlVector< FieldInfo_t > m_FieldInfo;
  153. FieldIndex_t m_pStandardFieldIndex[STANDARD_FIELD_COUNT];
  154. int m_nVertexCount;
  155. };
  156. //-----------------------------------------------------------------------------
  157. // Creates a particular vertex data field + associated index field
  158. //-----------------------------------------------------------------------------
  159. template< class T >
  160. inline FieldIndex_t CDmeVertexDataBase::CreateField( const char *pFieldName )
  161. {
  162. return CreateField( pFieldName, CDmAttributeInfo< CUtlVector<T> >::AttributeType() );
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Returns a standard field index
  166. //-----------------------------------------------------------------------------
  167. inline FieldIndex_t CDmeVertexDataBase::FindFieldIndex( StandardFields_t nFieldIndex ) const
  168. {
  169. return m_pStandardFieldIndex[ nFieldIndex ];
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Vertex field accessors
  173. //-----------------------------------------------------------------------------
  174. inline int CDmeVertexDataBase::VertexCount() const
  175. {
  176. return m_nVertexCount;
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Returns the number of joints per vertex
  180. //-----------------------------------------------------------------------------
  181. inline int CDmeVertexDataBase::JointCount() const
  182. {
  183. return m_nJointCount;
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Should we flip the V coordinates?
  187. //-----------------------------------------------------------------------------
  188. inline bool CDmeVertexDataBase::IsVCoordinateFlipped() const
  189. {
  190. return m_bFlipVCoordinates;
  191. }
  192. inline void CDmeVertexDataBase::FlipVCoordinate( bool bFlip )
  193. {
  194. m_bFlipVCoordinates = bFlip;
  195. }
  196. //-----------------------------------------------------------------------------
  197. // Returns arbitrary vertex data
  198. //-----------------------------------------------------------------------------
  199. inline CDmAttribute* CDmeVertexDataBase::GetVertexData( FieldIndex_t nFieldIndex )
  200. {
  201. return m_FieldInfo[ nFieldIndex ].m_pVertexData;
  202. }
  203. inline const CDmAttribute* CDmeVertexDataBase::GetVertexData( FieldIndex_t nFieldIndex ) const
  204. {
  205. return m_FieldInfo[ nFieldIndex ].m_pVertexData;
  206. }
  207. //-----------------------------------------------------------------------------
  208. // Returns arbitrary index data
  209. //-----------------------------------------------------------------------------
  210. inline CDmAttribute* CDmeVertexDataBase::GetIndexData( FieldIndex_t nFieldIndex )
  211. {
  212. return m_FieldInfo[ nFieldIndex ].m_pIndexData;
  213. }
  214. inline const CDmAttribute* CDmeVertexDataBase::GetIndexData( FieldIndex_t nFieldIndex ) const
  215. {
  216. return m_FieldInfo[ nFieldIndex ].m_pIndexData;
  217. }
  218. //-----------------------------------------------------------------------------
  219. // Utility method for getting at various vertex field indices
  220. //-----------------------------------------------------------------------------
  221. inline int CDmeVertexDataBase::GetFieldIndex( int nVertexIndex, StandardFields_t nFieldId ) const
  222. {
  223. Assert( nVertexIndex < m_nVertexCount );
  224. FieldIndex_t nFieldIndex = m_pStandardFieldIndex[nFieldId];
  225. if ( nFieldIndex < 0 )
  226. return -1;
  227. CDmrArrayConst<int> indices( GetIndexData( nFieldIndex ) );
  228. return indices[ nVertexIndex ];
  229. }
  230. //-----------------------------------------------------------------------------
  231. //
  232. // Vertex Data for base states
  233. //
  234. //-----------------------------------------------------------------------------
  235. class CDmeVertexData : public CDmeVertexDataBase
  236. {
  237. DEFINE_ELEMENT( CDmeVertexData, CDmeVertexDataBase );
  238. public:
  239. // Adds a new vertex; creates a new entry in all vertex data fields
  240. int AddVertexIndices( int nCount );
  241. private:
  242. virtual bool IsVertexDeltaData() const { return false; }
  243. };
  244. //-----------------------------------------------------------------------------
  245. //
  246. // Vertex Data for delta states
  247. //
  248. //-----------------------------------------------------------------------------
  249. class CDmeVertexDeltaData : public CDmeVertexDataBase
  250. {
  251. DEFINE_ELEMENT( CDmeVertexDeltaData, CDmeVertexDataBase );
  252. public:
  253. // Computes wrinkle data from position deltas
  254. // NOTE: Pass in negative scales to get 'compression', positive to get 'expansion'
  255. void GenerateWrinkleDelta( CDmeVertexData *pBindState, float flScale, bool bOverwrite );
  256. // Computes a float map which is the distance between the base and delta position
  257. // The maximum distance any vertex is moved is returned
  258. float GenerateWeightDelta( CDmeVertexData *pBindState );
  259. CDmaVar< bool > m_bCorrected;
  260. private:
  261. virtual bool IsVertexDeltaData() const { return true; }
  262. // Computes max positional delta length
  263. float ComputeMaxDeflection( );
  264. };
  265. #endif // DMEVERTEXDATA_H