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.
416 lines
12 KiB
416 lines
12 KiB
//========= 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 |
|
|
|
|