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.
 
 
 
 
 
 

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