diff options
Diffstat (limited to 'public/materialsystem/meshreader.h')
| -rw-r--r-- | public/materialsystem/meshreader.h | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/public/materialsystem/meshreader.h b/public/materialsystem/meshreader.h new file mode 100644 index 0000000..15b6873 --- /dev/null +++ b/public/materialsystem/meshreader.h @@ -0,0 +1,268 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#ifndef MESHREADER_H +#define MESHREADER_H + +#ifdef _WIN32 +#pragma once +#endif + + +//----------------------------------------------------------------------------- +// This is used to read vertex and index data out of already-created meshes. +// xbox uses this a lot so it doesn't have to store sysmem backups of the +// vertex data. +//----------------------------------------------------------------------------- +class CBaseMeshReader : protected MeshDesc_t +{ +// Initialization. +public: + + CBaseMeshReader(); + ~CBaseMeshReader(); + + // Use BeginRead/EndRead to initialize the mesh reader. + void BeginRead( + IMesh* pMesh, + int firstVertex = 0, + int numVertices = 0, + int firstIndex = 0, + int numIndices = 0 ); + + void EndRead(); + + // PC can use this if it stores its own copy of meshes around, in case + // locking static buffers is too costly. + void BeginRead_Direct( const MeshDesc_t &desc, int numVertices, int nIndices ); + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + +protected: + IMesh *m_pMesh; + int m_MaxVertices; + int m_MaxIndices; +}; + + +// A bunch of accessors for the data that CBaseMeshReader sets up. +class CMeshReader : public CBaseMeshReader +{ +public: +// Access to vertex data. +public: + int NumIndices() const; + unsigned short Index( int index ) const; + + const Vector& Position( int iVertex ) const; + + unsigned int Color( int iVertex ) const; + + const float *TexCoord( int iVertex, int stage ) const; + void TexCoord2f( int iVertex, int stage, float &s, float &t ) const; + const Vector2D& TexCoordVector2D( int iVertex, int stage ) const; + + int NumBoneWeights() const; + float Wrinkle( int iVertex ) const; + + const Vector &Normal( int iVertex ) const; + void Normal( int iVertex, Vector &vNormal ) const; + + const Vector &TangentS( int iVertex ) const; + const Vector &TangentT( int iVertex ) const; + float BoneWeight( int iVertex ) const; + +#ifdef NEW_SKINNING + float* BoneMatrix( int iVertex ) const; +#else + unsigned char* BoneMatrix( int iVertex ) const; +#endif +}; + + +//----------------------------------------------------------------------------- +// CBaseMeshReader implementation. +//----------------------------------------------------------------------------- + +inline CBaseMeshReader::CBaseMeshReader() +{ + m_pMesh = NULL; +} + +inline CBaseMeshReader::~CBaseMeshReader() +{ + Assert( !m_pMesh ); +} + +inline void CBaseMeshReader::BeginRead( + IMesh* pMesh, + int firstVertex, + int numVertices, + int firstIndex, + int numIndices ) +{ + Assert( pMesh && (!m_pMesh) ); + + if ( numVertices < 0 ) + { + numVertices = pMesh->VertexCount(); + } + + if ( numIndices < 0 ) + { + numIndices = pMesh->IndexCount(); + } + + m_pMesh = pMesh; + m_MaxVertices = numVertices; + m_MaxIndices = numIndices; + + // UNDONE: support reading from compressed VBs if needed + VertexCompressionType_t compressionType = CompressionType( pMesh->GetVertexFormat() ); + Assert( compressionType == VERTEX_COMPRESSION_NONE ); + if ( compressionType != VERTEX_COMPRESSION_NONE ) + { + Warning( "Cannot use CBaseMeshReader with compressed vertices! Will get junk data or a crash.\n" ); + } + + // Locks mesh for modifying + pMesh->ModifyBeginEx( true, firstVertex, numVertices, firstIndex, numIndices, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CBaseMeshReader::EndRead() +{ + Assert( m_pMesh ); + m_pMesh->ModifyEnd( *this ); + m_pMesh = NULL; +} + +inline void CBaseMeshReader::BeginRead_Direct( const MeshDesc_t &desc, int nVertices, int nIndices ) +{ + MeshDesc_t *pThis = this; + *pThis = desc; + m_MaxVertices = nVertices; + m_MaxIndices = nIndices; + + // UNDONE: support reading from compressed verts if necessary + Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE ); + if ( desc.m_CompressionType != VERTEX_COMPRESSION_NONE ) + { + Warning( "Cannot use CBaseMeshReader with compressed vertices!\n" ); + } +} + +inline void CBaseMeshReader::Reset() +{ +} + + + + +// -------------------------------------------------------------------------------------- // +// CMeshReader implementation. +// -------------------------------------------------------------------------------------- // + +inline int CMeshReader::NumIndices() const +{ + return m_MaxIndices; +} + +inline unsigned short CMeshReader::Index( int index ) const +{ + Assert( (index >= 0) && (index < m_MaxIndices) ); + return m_pIndices[index * m_nIndexSize]; +} + +inline const Vector& CMeshReader::Position( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(Vector*)((char*)m_pPosition + iVertex * m_VertexSize_Position); +} + +inline unsigned int CMeshReader::Color( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + unsigned char *pColor = m_pColor + iVertex * m_VertexSize_Color; + return (pColor[0] << 16) | (pColor[1] << 8) | (pColor[2]) | (pColor[3] << 24); +} + +inline const float *CMeshReader::TexCoord( int iVertex, int iStage ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] ); +} + +inline void CMeshReader::TexCoord2f( int iVertex, int iStage, float &s, float &t ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + float *p = (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] ); + s = p[0]; + t = p[1]; +} + +inline const Vector2D& CMeshReader::TexCoordVector2D( int iVertex, int iStage ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + Vector2D *p = (Vector2D*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] ); + return *p; +} + +inline float CMeshReader::Wrinkle( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(float*)( (char*)m_pWrinkle + iVertex * m_VertexSize_Wrinkle ); +} + +inline int CMeshReader::NumBoneWeights() const +{ + return m_NumBoneWeights; +} + +inline const Vector &CMeshReader::Normal( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(const Vector *)(const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal ); +} + +inline void CMeshReader::Normal( int iVertex, Vector &vNormal ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + const float *p = (const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal ); + vNormal.Init( p[0], p[1], p[2] ); +} + +inline const Vector &CMeshReader::TangentS( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(const Vector*)( (char*)m_pTangentS + iVertex * m_VertexSize_TangentS ); +} + +inline const Vector &CMeshReader::TangentT( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(const Vector*)( (char*)m_pTangentT + iVertex * m_VertexSize_TangentT ); +} + +inline float CMeshReader::BoneWeight( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + float *p = (float*)( (char*)m_pBoneWeight + iVertex * m_VertexSize_BoneWeight ); + return *p; +} + +#endif // MESHREADER_H + + + + + + + |