diff options
Diffstat (limited to 'hammer/SmoothingGroupMgr.cpp')
| -rw-r--r-- | hammer/SmoothingGroupMgr.cpp | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/hammer/SmoothingGroupMgr.cpp b/hammer/SmoothingGroupMgr.cpp new file mode 100644 index 0000000..83f8461 --- /dev/null +++ b/hammer/SmoothingGroupMgr.cpp @@ -0,0 +1,416 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include <stdafx.h> +#include "smoothinggroupmgr.h" +#include "mapface.h" +#include "ChunkFile.h" + +class CSmoothingGroupMgr : public ISmoothingGroupMgr +{ +public: + + CSmoothingGroupMgr(); + ~CSmoothingGroupMgr(); + + SmoothingGroupHandle_t CreateGroup( void ); + void DestroyGroup( SmoothingGroupHandle_t hGroup ); + + bool IsGroup( SmoothingGroupHandle_t hGroup ); + + void AddFaceToGroup( SmoothingGroupHandle_t hGroup, CMapFace *pFace ); + void RemoveFaceFromGroup( SmoothingGroupHandle_t hGroup, CMapFace *pFace ); + + void SetGroupSmoothingAngle( SmoothingGroupHandle_t hGroup, float flAngle ); + float GetGroupSmoothingAngle( SmoothingGroupHandle_t hGroup ); + + int GetFaceCountInGroup( SmoothingGroupHandle_t hGroup ); + CMapFace *GetFaceFromGroup( SmoothingGroupHandle_t hGroup, int iFace ); + + ChunkFileResult_t SaveVMF( CChunkFile *pFile, CSaveInfo *pSaveInfo ); + ChunkFileResult_t LoadVMF( CChunkFile *pFile ); + +private: + +#if 0 + static ChunkFileResult_t LoadSmoothingGroupMgrCallback( const char *szKey, const char *szValue, CSmoothingGroupMgr *pSmoothingGroupMgr ); + static ChunkFileResult_t LoadSmoothingGroupMgrKeyCallback( const char *szKey, const char *szValue, CSmoothingGroupMgr *pSmoothingGroupMgr ); + + static ChunkFileResult_t LoadSmoothingGroupCallback( CChunkFile *pFile, SmoothingGroup_t *pGroup ); + static ChunkFileResult_t LoadSmoothingGroupKeyCallback( const char *szKey, const char *szValue, SmoothingGroup_t *pGroup ); +#endif + +private: + + struct SmoothingGroup_t + { + int m_nID; + CUtlVector<CMapFace*> m_aFaces; + float m_flSmoothingAngle; + }; + + CUtlVector<SmoothingGroup_t> m_aSmoothingGroups; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ISmoothingGroupMgr *SmoothingGroupMgr( void ) +{ + static CSmoothingGroupMgr s_SmoothingGroupMgr; + return &s_SmoothingGroupMgr; +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CSmoothingGroupMgr::CSmoothingGroupMgr() +{ + m_aSmoothingGroups.SetSize( MAX_SMOOTHING_GROUP_COUNT ); +} + +//----------------------------------------------------------------------------- +// Purpose: Deconstructor +//----------------------------------------------------------------------------- +CSmoothingGroupMgr::~CSmoothingGroupMgr() +{ + m_aSmoothingGroups.Purge(); +} + +//----------------------------------------------------------------------------- +// Purpose: Add a face to the smoothing group. +//----------------------------------------------------------------------------- +void CSmoothingGroupMgr::AddFaceToGroup( SmoothingGroupHandle_t hGroup, CMapFace *pFace ) +{ + // Validate data. + Assert( hGroup != INVALID_SMOOTHING_GROUP ); + Assert( hGroup >= 0 ); + Assert( hGroup < MAX_SMOOTHING_GROUP_COUNT ); + + int iGroup = static_cast<int>( hGroup ); + SmoothingGroup_t *pGroup = &m_aSmoothingGroups[iGroup]; + if ( pGroup ) + { + // Check to see if we already have this face in this group. + if ( pGroup->m_aFaces.Find( pFace ) == -1 ) + { + pFace->AddSmoothingGroupHandle( hGroup ); + pGroup->m_aFaces.AddToTail( pFace ); + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CSmoothingGroupMgr::RemoveFaceFromGroup( SmoothingGroupHandle_t hGroup, CMapFace *pFace ) +{ + // Validate data. + Assert( hGroup != INVALID_SMOOTHING_GROUP ); + Assert( hGroup >= 0 ); + Assert( hGroup < MAX_SMOOTHING_GROUP_COUNT ); + + int iGroup = static_cast<int>( hGroup ); + SmoothingGroup_t *pGroup = &m_aSmoothingGroups[iGroup]; + if ( pGroup ) + { + int iFace = pGroup->m_aFaces.Find( pFace ); + if ( iFace != -1 ) + { + pFace->RemoveSmoothingGroupHandle( hGroup ); + pGroup->m_aFaces.Remove( iFace ); + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CSmoothingGroupMgr::SetGroupSmoothingAngle( SmoothingGroupHandle_t hGroup, float flAngle ) +{ + // Validate data. + Assert( hGroup != INVALID_SMOOTHING_GROUP ); + Assert( hGroup >= 0 ); + Assert( hGroup < MAX_SMOOTHING_GROUP_COUNT ); + + int iGroup = static_cast<int>( hGroup ); + SmoothingGroup_t *pGroup = &m_aSmoothingGroups[iGroup]; + if ( pGroup ) + { + pGroup->m_flSmoothingAngle = flAngle; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +float CSmoothingGroupMgr::GetGroupSmoothingAngle( SmoothingGroupHandle_t hGroup ) +{ + // Validate data. + Assert( hGroup != INVALID_SMOOTHING_GROUP ); + Assert( hGroup >= 0 ); + Assert( hGroup < MAX_SMOOTHING_GROUP_COUNT ); + + int iGroup = static_cast<int>( hGroup ); + SmoothingGroup_t *pGroup = &m_aSmoothingGroups[iGroup]; + if ( pGroup ) + { + return pGroup->m_flSmoothingAngle; + } + + return -1.0f; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CSmoothingGroupMgr::GetFaceCountInGroup( SmoothingGroupHandle_t hGroup ) +{ + // Validate data. + Assert( hGroup != INVALID_SMOOTHING_GROUP ); + Assert( hGroup >= 0 ); + Assert( hGroup < MAX_SMOOTHING_GROUP_COUNT ); + + int iGroup = static_cast<int>( hGroup ); + SmoothingGroup_t *pGroup = &m_aSmoothingGroups[iGroup]; + if ( pGroup ) + { + return pGroup->m_aFaces.Count(); + } + + return -1; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CMapFace *CSmoothingGroupMgr::GetFaceFromGroup( SmoothingGroupHandle_t hGroup, int iFace ) +{ + // Validate data. + Assert( hGroup != INVALID_SMOOTHING_GROUP ); + Assert( hGroup >= 0 ); + Assert( hGroup < MAX_SMOOTHING_GROUP_COUNT ); + + int iGroup = static_cast<int>( hGroup ); + SmoothingGroup_t *pGroup = &m_aSmoothingGroups[iGroup]; + if ( pGroup ) + { + return pGroup->m_aFaces[iFace]; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: Save the smoothing group data. +//----------------------------------------------------------------------------- +ChunkFileResult_t CSmoothingGroupMgr::SaveVMF( CChunkFile *pFile, CSaveInfo *pSaveInfo ) +{ + int nGroupCount = 0; + for ( int iGroup = 0; iGroup < MAX_SMOOTHING_GROUP_COUNT; ++iGroup ) + { + if ( m_aSmoothingGroups[iGroup].m_aFaces.Count() != 0 ) + { + nGroupCount++; + } + } + + if ( nGroupCount == 0 ) + return ChunkFile_Ok; + + ChunkFileResult_t eResult = pFile->BeginChunk( "smoothing_groups" ); + + for ( iGroup = 0; iGroup < MAX_SMOOTHING_GROUP_COUNT; ++iGroup ) + { + SmoothingGroup_t *pGroup = &m_aSmoothingGroups[iGroup]; + int nFaceCount = pGroup->m_aFaces.Count(); + if ( nFaceCount == 0 ) + continue; + + char szBuf[MAX_KEYVALUE_LEN]; + char szTemp[80]; + + // Save the smoothing group. + if ( eResult == ChunkFile_Ok ) + { + eResult = pFile->BeginChunk( "group" ); + if ( eResult == ChunkFile_Ok ) + { + eResult = pFile->WriteKeyValueInt( "id", iGroup ); + + if ( eResult == ChunkFile_Ok ) + { + eResult = pFile->WriteKeyValueFloat( "angle", pGroup->m_flSmoothingAngle ); + } + + if ( eResult == ChunkFile_Ok ) + { + eResult = pFile->WriteKeyValueInt( "number_faces", nFaceCount ); + } + + if ( eResult == ChunkFile_Ok ) + { + int nColCount = 20; + int nRowCount = ( nFaceCount / nColCount ) + 1; + + for ( int iRow = 0; iRow < nRowCount; ++iRow ) + { + bool bFirst = true; + szBuf[0] = '\0'; + + for ( int iCol = 0; iCol < nColCount; ++iCol ) + { + int iFace = ( iRow * 20 ) + iCol; + if ( iFace >= nFaceCount ) + continue; + + if (!bFirst) + { + strcat(szBuf, " "); + } + + CMapFace *pFace = pGroup->m_aFaces[iFace]; + if ( pFace ) + { + bFirst = false; + sprintf( szTemp, "%d", pFace->GetFaceID() ); + strcat( szBuf, szTemp ); + } + } + + char szKey[10]; + sprintf( szKey, "row%d", iRow ); + eResult = pFile->WriteKeyValue( szKey, szBuf ); + } + } + } + + if ( eResult == ChunkFile_Ok ) + { + eResult = pFile->EndChunk(); + } + } + } + + if ( eResult == ChunkFile_Ok ) + { + eResult = pFile->EndChunk(); + } + + return eResult; +} + +//----------------------------------------------------------------------------- +// Purpose: Load smoothing group data. +//----------------------------------------------------------------------------- +ChunkFileResult_t CSmoothingGroupMgr::LoadVMF( CChunkFile *pFile ) +{ +// ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadSmoothingGroupMgrCallback, this ); +// return eResult; + + return ChunkFile_Ok; +} + +#if 0 + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CSmoothingGroupMgr::LoadSmoothingGroupMgrCallback( const char *szKey, const char *szValue, + CSmoothingGroupMgr *pSmoothingGroupMgr ) +{ + // Get a pointer to the next available smoothing group slot. + SmoothingGroup_t *pGroup = new SmoothingGroup_t; + if ( !pGroup ) + return; + + // Set up handlers for the subchunks that we are interested in. + CChunkHandlerMap Handlers; + Handlers.AddHandler( "group", ( ChunkHandler_t )LoadsSmoothingGroupCallback, SmoothingGroup_t *pGroup ); + + pFile->PushHandlers( &Handlers ); + ChunkFileResult_t eResult = pFile->ReadChunk( ( KeyHandler_t )LoadSmoothingGroupMgrCallback, this ); + pFile->PopHandlers(); + + if ( eResult == ChunkFile_Ok ) + { + pGroup->m_nID + + SmoothingGroup_t *pLoadGroup = &pSmoothingGroupMgr->m_aSmoothingGroups[pGroup->m_nID]; + if ( pLoadGroup ) + { + pLoadGroup->m_nID = pGroup->m_nID; + pLoadGroup->m_flSmoothingAngle = pGroup->m_flSmoothingAngle; + pLoadGroup->m_aFaces.CopyArray( pGroup->m_aFaces.Base(), pGroup->m_aFaces.Count() ); + } + } + + return eResult; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CSmoothingGroupMgr::LoadSmoothingGroupMgrKeyCallback( const char *szKey, const char *szValue, + CSmoothingGroupMgr *pSmoothingGroupMgr ) +{ + return; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CSmoothingGroupMgr::LoadSmoothingGroupCallback( CChunkFile *pFile, SmoothingGroup_t *pGroup ) +{ + return( pFile->ReadChunk( ( KeyHandler_t )LoadDispNormalsKeyCallback, pGroup ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +ChunkFileResult_t CSmoothingGroupMgr::LoadSmoothingGroupKeyCallback( const char *szKey, const char *szValue, SmoothingGroup_t *pGroup ) +{ + int nId; + if ( !strnicmp( szKey, "id", 2 ) ) + { + CChunkFile::ReadKeyValueInt( szValue, pGroup->m_nID ); + } + + if ( !strnicmp( szKey, "angle", 5 ) ) + { + CChunkFile::ReadKeyValueFloat( szValue, pGroup->m_flSmoothingAngle ); + } + + if ( !strnicmp( szKey, "number_faces", 12 ) ) + { + int nFaceCount; + CChunkFile::ReadKeyValueInt( szValue, nFaceCount ); + pGroup->m_aFaces.SetSize( nFaceCount ); + } + + if ( !strnicmp(szKey, "row", 3 ) ) + { + CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); + + char szBuf[MAX_KEYVALUE_LEN]; + strcpy( szBuf, szValue ); + + int iRow = atoi( &szKey[3] ); + + char *pszNext = strtok( szBuf, " " ); + int nIndex = nRow * 20; + + int nFaceID; + while ( pszNext != NULL ) + { + nFaceID = ( float )atof( pszNext ); + CMapFace *pFace = + + + +CMapFace *CMapWorld::FaceID_FaceForID(int nFaceID) + + + pszNext = strtok( NULL, " " ); + nIndex++; + } + } + + return ChunkFile_Ok ; +} +#endif + |