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.

268 lines
6.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=====================================================================================//
  6. #ifndef MESHREADER_H
  7. #define MESHREADER_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. //-----------------------------------------------------------------------------
  12. // This is used to read vertex and index data out of already-created meshes.
  13. // xbox uses this a lot so it doesn't have to store sysmem backups of the
  14. // vertex data.
  15. //-----------------------------------------------------------------------------
  16. class CBaseMeshReader : protected MeshDesc_t
  17. {
  18. // Initialization.
  19. public:
  20. CBaseMeshReader();
  21. ~CBaseMeshReader();
  22. // Use BeginRead/EndRead to initialize the mesh reader.
  23. void BeginRead(
  24. IMesh* pMesh,
  25. int firstVertex = 0,
  26. int numVertices = 0,
  27. int firstIndex = 0,
  28. int numIndices = 0 );
  29. void EndRead();
  30. // PC can use this if it stores its own copy of meshes around, in case
  31. // locking static buffers is too costly.
  32. void BeginRead_Direct( const MeshDesc_t &desc, int numVertices, int nIndices );
  33. // Resets the mesh builder so it points to the start of everything again
  34. void Reset();
  35. protected:
  36. IMesh *m_pMesh;
  37. int m_MaxVertices;
  38. int m_MaxIndices;
  39. };
  40. // A bunch of accessors for the data that CBaseMeshReader sets up.
  41. class CMeshReader : public CBaseMeshReader
  42. {
  43. public:
  44. // Access to vertex data.
  45. public:
  46. int NumIndices() const;
  47. unsigned short Index( int index ) const;
  48. const Vector& Position( int iVertex ) const;
  49. unsigned int Color( int iVertex ) const;
  50. const float *TexCoord( int iVertex, int stage ) const;
  51. void TexCoord2f( int iVertex, int stage, float &s, float &t ) const;
  52. const Vector2D& TexCoordVector2D( int iVertex, int stage ) const;
  53. int NumBoneWeights() const;
  54. float Wrinkle( int iVertex ) const;
  55. const Vector &Normal( int iVertex ) const;
  56. void Normal( int iVertex, Vector &vNormal ) const;
  57. const Vector &TangentS( int iVertex ) const;
  58. const Vector &TangentT( int iVertex ) const;
  59. float BoneWeight( int iVertex ) const;
  60. #ifdef NEW_SKINNING
  61. float* BoneMatrix( int iVertex ) const;
  62. #else
  63. unsigned char* BoneMatrix( int iVertex ) const;
  64. #endif
  65. };
  66. //-----------------------------------------------------------------------------
  67. // CBaseMeshReader implementation.
  68. //-----------------------------------------------------------------------------
  69. inline CBaseMeshReader::CBaseMeshReader()
  70. {
  71. m_pMesh = NULL;
  72. }
  73. inline CBaseMeshReader::~CBaseMeshReader()
  74. {
  75. Assert( !m_pMesh );
  76. }
  77. inline void CBaseMeshReader::BeginRead(
  78. IMesh* pMesh,
  79. int firstVertex,
  80. int numVertices,
  81. int firstIndex,
  82. int numIndices )
  83. {
  84. Assert( pMesh && (!m_pMesh) );
  85. if ( numVertices < 0 )
  86. {
  87. numVertices = pMesh->VertexCount();
  88. }
  89. if ( numIndices < 0 )
  90. {
  91. numIndices = pMesh->IndexCount();
  92. }
  93. m_pMesh = pMesh;
  94. m_MaxVertices = numVertices;
  95. m_MaxIndices = numIndices;
  96. // UNDONE: support reading from compressed VBs if needed
  97. VertexCompressionType_t compressionType = CompressionType( pMesh->GetVertexFormat() );
  98. Assert( compressionType == VERTEX_COMPRESSION_NONE );
  99. if ( compressionType != VERTEX_COMPRESSION_NONE )
  100. {
  101. Warning( "Cannot use CBaseMeshReader with compressed vertices! Will get junk data or a crash.\n" );
  102. }
  103. // Locks mesh for modifying
  104. pMesh->ModifyBeginEx( true, firstVertex, numVertices, firstIndex, numIndices, *this );
  105. // Point to the start of the buffers..
  106. Reset();
  107. }
  108. inline void CBaseMeshReader::EndRead()
  109. {
  110. Assert( m_pMesh );
  111. m_pMesh->ModifyEnd( *this );
  112. m_pMesh = NULL;
  113. }
  114. inline void CBaseMeshReader::BeginRead_Direct( const MeshDesc_t &desc, int nVertices, int nIndices )
  115. {
  116. MeshDesc_t *pThis = this;
  117. *pThis = desc;
  118. m_MaxVertices = nVertices;
  119. m_MaxIndices = nIndices;
  120. // UNDONE: support reading from compressed verts if necessary
  121. Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE );
  122. if ( desc.m_CompressionType != VERTEX_COMPRESSION_NONE )
  123. {
  124. Warning( "Cannot use CBaseMeshReader with compressed vertices!\n" );
  125. }
  126. }
  127. inline void CBaseMeshReader::Reset()
  128. {
  129. }
  130. // -------------------------------------------------------------------------------------- //
  131. // CMeshReader implementation.
  132. // -------------------------------------------------------------------------------------- //
  133. inline int CMeshReader::NumIndices() const
  134. {
  135. return m_MaxIndices;
  136. }
  137. inline unsigned short CMeshReader::Index( int index ) const
  138. {
  139. Assert( (index >= 0) && (index < m_MaxIndices) );
  140. return m_pIndices[index * m_nIndexSize];
  141. }
  142. inline const Vector& CMeshReader::Position( int iVertex ) const
  143. {
  144. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  145. return *(Vector*)((char*)m_pPosition + iVertex * m_VertexSize_Position);
  146. }
  147. inline unsigned int CMeshReader::Color( int iVertex ) const
  148. {
  149. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  150. unsigned char *pColor = m_pColor + iVertex * m_VertexSize_Color;
  151. return (pColor[0] << 16) | (pColor[1] << 8) | (pColor[2]) | (pColor[3] << 24);
  152. }
  153. inline const float *CMeshReader::TexCoord( int iVertex, int iStage ) const
  154. {
  155. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  156. return (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] );
  157. }
  158. inline void CMeshReader::TexCoord2f( int iVertex, int iStage, float &s, float &t ) const
  159. {
  160. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  161. float *p = (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] );
  162. s = p[0];
  163. t = p[1];
  164. }
  165. inline const Vector2D& CMeshReader::TexCoordVector2D( int iVertex, int iStage ) const
  166. {
  167. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  168. Vector2D *p = (Vector2D*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] );
  169. return *p;
  170. }
  171. inline float CMeshReader::Wrinkle( int iVertex ) const
  172. {
  173. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  174. return *(float*)( (char*)m_pWrinkle + iVertex * m_VertexSize_Wrinkle );
  175. }
  176. inline int CMeshReader::NumBoneWeights() const
  177. {
  178. return m_NumBoneWeights;
  179. }
  180. inline const Vector &CMeshReader::Normal( int iVertex ) const
  181. {
  182. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  183. return *(const Vector *)(const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal );
  184. }
  185. inline void CMeshReader::Normal( int iVertex, Vector &vNormal ) const
  186. {
  187. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  188. const float *p = (const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal );
  189. vNormal.Init( p[0], p[1], p[2] );
  190. }
  191. inline const Vector &CMeshReader::TangentS( int iVertex ) const
  192. {
  193. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  194. return *(const Vector*)( (char*)m_pTangentS + iVertex * m_VertexSize_TangentS );
  195. }
  196. inline const Vector &CMeshReader::TangentT( int iVertex ) const
  197. {
  198. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  199. return *(const Vector*)( (char*)m_pTangentT + iVertex * m_VertexSize_TangentT );
  200. }
  201. inline float CMeshReader::BoneWeight( int iVertex ) const
  202. {
  203. Assert( iVertex >= 0 && iVertex < m_MaxVertices );
  204. float *p = (float*)( (char*)m_pBoneWeight + iVertex * m_VertexSize_BoneWeight );
  205. return *p;
  206. }
  207. #endif // MESHREADER_H