|
|
//========= 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
|