Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
891 lines
20 KiB
C++
891 lines
20 KiB
C++
|
|
#include "BGMController.h"
|
|
|
|
#include "RegionTrigger.h"
|
|
#include <vector>
|
|
#include <string>
|
|
#include <math.h>
|
|
#include <algorithm>
|
|
#include <exception>
|
|
#include <d3dx8.h>
|
|
#include <assert.h>
|
|
#include "TriggerEvent.h"
|
|
#include "SceneStateMgr.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
static char BGMDataMark[] = "BGMData";
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
CBGMController & CBGMController::GetInstance( IDirectSound8 * pDSound )
|
|
{
|
|
static CBGMController instance( pDSound );
|
|
return instance;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
CBGMController::CBGMController( IDirectSound8 * pDSound )
|
|
: m_pRegionTrigger( new CRegionTrigger )
|
|
, m_pEvents( new EVENTS )
|
|
, m_pEventArgs( new EVENTARGS )
|
|
, m_iTriggerSelected( UINT_MAX )
|
|
, m_iPointSelected( UINT_MAX )
|
|
, m_iLastDeleted( UINT_MAX )
|
|
, m_pTriggerRegions( new TRIGGERREGIONS )
|
|
, m_pContainer_ObjID( new CONTAINER_OBJID )
|
|
, m_pPrevTrigger( NULL )
|
|
, m_pVertexes( new TRIGGERVERTEXES )
|
|
{
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
CBGMController::~CBGMController()
|
|
{
|
|
delete m_pRegionTrigger;
|
|
delete m_pEvents;
|
|
delete m_pEventArgs;
|
|
delete m_pTriggerRegions;
|
|
delete m_pContainer_ObjID;
|
|
delete m_pVertexes;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Create( const char * szFilename, bool forEdit )
|
|
{
|
|
FILE * fp = fopen( szFilename, "rb" );
|
|
|
|
if( fp == NULL )
|
|
return;
|
|
|
|
//화일 크기를 구함
|
|
fseek( fp, 0, SEEK_END );
|
|
long fileSize = ftell( fp );
|
|
|
|
//화일을 전부 읽음.
|
|
char * Buffer = new char[fileSize+1];
|
|
fseek( fp, 0, SEEK_SET );
|
|
fread( Buffer, fileSize, 1, fp );
|
|
|
|
//strstr함수 호출에 문제가 되므로 NULL문자를 없앰.
|
|
for( int i = 0; i < fileSize; i++ )
|
|
{
|
|
if( Buffer[i] == '\0' )
|
|
Buffer[i] = '\n';
|
|
}
|
|
|
|
//맨 끝에만 NULL 문자를 붙임.
|
|
Buffer[fileSize] = '\0';
|
|
|
|
char * p = strstr( Buffer, BGMDataMark );
|
|
|
|
delete [] Buffer;
|
|
|
|
if( p )
|
|
{
|
|
long offset = p - Buffer;
|
|
|
|
fseek( fp, offset, SEEK_SET );
|
|
|
|
Create( fp, forEdit );
|
|
}
|
|
|
|
fclose( fp );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Create( FILE * fp, bool forEdit )
|
|
{
|
|
Destroy();
|
|
|
|
char szMark[32];
|
|
fread( szMark, sizeof( char ), strlen( BGMDataMark ) + 1, fp );
|
|
|
|
if( strcmp( szMark, BGMDataMark ) != 0 )
|
|
throw bad_exception( "잘못된 트리거 화일입니다. 읽을 수 없습니다." );
|
|
|
|
//화일 포인터의 위치가 올바른지 표식을 통해 확인함.
|
|
char c[2];
|
|
fread( c, sizeof( char ), 2, fp );
|
|
assert( c[0] == 'R' && c[1] == 'E' );
|
|
|
|
m_pRegionTrigger->Create( fp );
|
|
|
|
//표식검사
|
|
fread( c, sizeof( char ), 2, fp );
|
|
assert( c[0] == 'S' && c[1] == 'F' );
|
|
|
|
int size;
|
|
fread( &size, sizeof( int ), 1, fp );
|
|
|
|
for( int i = 0; i < size; i++ )
|
|
{
|
|
m_pEventArgs->push_back( EVENTARG() );
|
|
EVENTARG & eventArg = m_pEventArgs->back();
|
|
|
|
int size2;
|
|
fread( &size2, sizeof( int ), 1, fp );
|
|
|
|
for( int j = 0; j < size2; j++ )
|
|
{
|
|
int eventID;
|
|
fread( &eventID, sizeof( int ), 1, fp );
|
|
|
|
unsigned char ArgLength;
|
|
fread( &ArgLength, sizeof( unsigned char ), 1, fp );
|
|
|
|
char szArgStr[256];
|
|
fread( szArgStr, sizeof( char ), ArgLength, fp );
|
|
szArgStr[ArgLength] = '\0';
|
|
|
|
eventArg.push_back( EVENTARGUNIT( eventID, szArgStr ) );
|
|
}
|
|
}
|
|
|
|
|
|
//TriggerRegions을 로드
|
|
fread( &size, sizeof( int ), 1, fp );
|
|
|
|
for( i = 0; i < size; i++ )
|
|
{
|
|
m_pTriggerRegions->push_back( TRIGGERREGION() );
|
|
TRIGGERREGION & tRegion = m_pTriggerRegions->back();
|
|
TRIGGERLIST & trgList = tRegion.first;
|
|
POLYGON & polygon = tRegion.second;
|
|
|
|
unsigned nTrgList = 0;
|
|
|
|
fread( &nTrgList, sizeof( unsigned ), 1, fp );
|
|
trgList.resize( nTrgList );
|
|
|
|
fread( &trgList[0], sizeof( int ) * nTrgList, 1, fp );
|
|
|
|
unsigned nPoly = 0;
|
|
|
|
fread( &nPoly, sizeof( unsigned ), 1, fp );
|
|
polygon.resize( nPoly );
|
|
|
|
fread( &polygon[0], sizeof( SVector2 ) * nPoly, 1, fp );
|
|
}
|
|
|
|
//표식 검사
|
|
fread( c, sizeof( char ), 2, fp );
|
|
assert( c[0] == 'V' && c[1] == 'T' );
|
|
|
|
if( forEdit )
|
|
{
|
|
//에디터용 세팅들을 해줌
|
|
//Vertex 정보들을 로드...
|
|
int size = 0;
|
|
fread( &size, sizeof( 1 ), 1, fp );
|
|
|
|
for( i = 0; i < size; i++ )
|
|
{
|
|
int size2 = 0;
|
|
fread( &size2, sizeof( int ), 1, fp );
|
|
m_pVertexes->push_back( VERTEXVECTOR() );
|
|
|
|
VERTEXVECTOR & vec = m_pVertexes->back();
|
|
|
|
for( int j = 0; j < size2; j++ )
|
|
{
|
|
float x, y, z;
|
|
fread( &x, sizeof( float ), 1, fp );
|
|
fread( &y, sizeof( float ), 1, fp );
|
|
fread( &z, sizeof( float ), 1, fp );
|
|
|
|
vec.push_back( D3DXVECTOR3( x, y, z ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Save( const char * szFilename )
|
|
{
|
|
FILE * fp = fopen( szFilename, "wb" );
|
|
|
|
Save( fp );
|
|
|
|
fclose( fp );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Save( FILE * fp )
|
|
{
|
|
//BGMController Data의 시작임을 나타내는 표식을 저장
|
|
fwrite( BGMDataMark, sizeof( char ), strlen( BGMDataMark ) + 1, fp );
|
|
|
|
//화일 포인터의 위치가 올바른지 확인하기 위한 표식을 남겨둠
|
|
char c[2] = { 'R', 'E' };
|
|
fwrite( c, sizeof( char ), 2, fp );
|
|
|
|
m_pRegionTrigger->Save( fp );
|
|
|
|
//표식을 또 남김
|
|
char c1[2] = { 'S', 'F' };
|
|
fwrite( c1, sizeof( char ), 2, fp );
|
|
|
|
int size = m_pEventArgs->size();
|
|
fwrite( &size, sizeof( int ), 1, fp );
|
|
|
|
for( int i = 0; i < size; i++ )
|
|
{
|
|
EVENTARG & arg = m_pEventArgs->at( i );
|
|
|
|
int size2 = arg.size();
|
|
fwrite( &size2, sizeof( int ), 1, fp );
|
|
|
|
for( int j = 0; j < size2; j++ )
|
|
{
|
|
int eventID = arg[j].first;
|
|
string & str = arg[j].second;
|
|
unsigned char stringlen = str.size();
|
|
|
|
fwrite( &eventID, sizeof( int ), 1, fp );
|
|
fwrite( &stringlen, sizeof( unsigned char ), 1, fp );
|
|
fwrite( str.c_str(), sizeof( char ), stringlen, fp );
|
|
}
|
|
}
|
|
|
|
//TriggerRegions 저장
|
|
size = m_pTriggerRegions->size();
|
|
|
|
fwrite( &size, sizeof( int ), 1, fp );
|
|
|
|
for( i = 0; i < size; i++ )
|
|
{
|
|
TRIGGERREGION & tRegion = m_pTriggerRegions->at( i );
|
|
TRIGGERLIST & trgList = tRegion.first;
|
|
POLYGON & polygon = tRegion.second;
|
|
|
|
unsigned nTrgList = trgList.size();
|
|
|
|
fwrite( &nTrgList, sizeof( unsigned ), 1, fp );
|
|
fwrite( &trgList[0], sizeof( int ) * nTrgList, 1, fp );
|
|
|
|
unsigned nPoly = polygon.size();
|
|
|
|
fwrite( &nPoly, sizeof( unsigned ), 1, fp );
|
|
fwrite( &polygon[0], sizeof( SVector2 ) * nPoly, 1, fp );
|
|
}
|
|
|
|
//또다른 표식
|
|
char c2[2] = { 'V', 'T' };
|
|
fwrite( c2, sizeof( char ), 2, fp );
|
|
|
|
//Vertex 정보들을 저장
|
|
size = m_pVertexes->size();
|
|
fwrite( &size, sizeof( int ), 1, fp );
|
|
|
|
for( i = 0; i < size; i++ )
|
|
{
|
|
VERTEXVECTOR & vec = m_pVertexes->at( i );
|
|
int size2 = vec.size();
|
|
|
|
fwrite( &size2, sizeof( int ), 1, fp );
|
|
|
|
for( int j = 0; j < size2; j++ )
|
|
{
|
|
fwrite( &vec[j].x, sizeof( float ), 1, fp );
|
|
fwrite( &vec[j].y, sizeof( float ), 1, fp );
|
|
fwrite( &vec[j].z, sizeof( float ), 1, fp );
|
|
}
|
|
}
|
|
|
|
//잘 읽혔는지 검사하기 위한 마지막 표식
|
|
char c3[3] = { 'E', 'N', 'D' };
|
|
fwrite( c3, sizeof( char ), 3, fp );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::DestroyAllEvents()
|
|
{
|
|
for( unsigned i = 0; i < m_pEvents->size(); i++ )
|
|
{
|
|
EVENT & event = m_pEvents->at( i );
|
|
|
|
for( unsigned j = 0; j < event.size(); j++ )
|
|
{
|
|
delete event[j];
|
|
event[j] = NULL;
|
|
}
|
|
}
|
|
|
|
m_pEvents->clear();
|
|
m_pEventArgs->clear();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Destroy()
|
|
{
|
|
DestroyAllEvents();
|
|
|
|
m_pRegionTrigger->Destroy();
|
|
m_pTriggerRegions->clear();
|
|
m_pVertexes->clear();
|
|
m_pContainer_ObjID->clear();
|
|
|
|
m_iTriggerSelected = m_iPointSelected = m_iLastDeleted = UINT_MAX;
|
|
|
|
m_pPrevTrigger = NULL;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Update( float x, float y, float z )
|
|
{
|
|
SVector2 pos( x, z );
|
|
|
|
TRIGGERLIST const * pCurrentTrigger = &m_pRegionTrigger->CheckTrigger( pos );
|
|
|
|
if( m_pPrevTrigger == pCurrentTrigger )
|
|
return;
|
|
|
|
if( m_pPrevTrigger != NULL && pCurrentTrigger != NULL )
|
|
{
|
|
for( int i = 0; i < pCurrentTrigger->size(); i++ )
|
|
{
|
|
int triggerID = pCurrentTrigger->at( i );
|
|
TRIGGERLIST::const_iterator it = find( m_pPrevTrigger->begin(), m_pPrevTrigger->end(), triggerID );
|
|
|
|
if( it == m_pPrevTrigger->end() )
|
|
{
|
|
BeginEvent( triggerID );
|
|
}
|
|
}
|
|
|
|
unsigned prevSize = m_pPrevTrigger->size();
|
|
for( i = 0; i < prevSize; i++ )
|
|
{
|
|
int triggerID = m_pPrevTrigger->at( i );
|
|
TRIGGERLIST::const_iterator it = find( pCurrentTrigger->begin(), pCurrentTrigger->end(), triggerID );
|
|
|
|
if( it == pCurrentTrigger->end() )
|
|
{
|
|
EndEvent( triggerID );
|
|
}
|
|
}
|
|
}
|
|
|
|
m_pPrevTrigger = pCurrentTrigger;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::BeginEvent( int triggerID )
|
|
{
|
|
if( triggerID >= 0 && triggerID < m_pEventArgs->size() )
|
|
{
|
|
EVENTARG & eventArg = m_pEventArgs->at( triggerID );
|
|
|
|
if( triggerID >= m_pEvents->size() )
|
|
m_pEvents->resize( triggerID + 1, EVENT() );
|
|
|
|
EVENT & event = m_pEvents->at( triggerID );
|
|
|
|
//event를 clear한다.
|
|
for( unsigned i = 0; i < event.size(); i++ )
|
|
delete event[i];
|
|
event.clear();
|
|
|
|
for( i = 0; i < eventArg.size(); i++ )
|
|
{
|
|
if( eventArg[i].first == 0 )
|
|
event.push_back( new CEvent_MusicPlay );
|
|
else if( eventArg[i].first == 1 )
|
|
event.push_back( new CEvent_ShowMessage );
|
|
else if( eventArg[i].first == 2 )
|
|
event.push_back( new CEvent_MusicPlayOnce );
|
|
else if( eventArg[i].first == 3 )
|
|
event.push_back( new CEvent_ShowEffect );
|
|
else
|
|
event.push_back( NULL );
|
|
|
|
if( event[i] )
|
|
{
|
|
event[i]->Create( eventArg[i].second.c_str() );
|
|
event[i]->Begin();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBGMController::EndEvent( int triggerID )
|
|
{
|
|
if( triggerID >= 0 && triggerID < m_pEvents->size() )
|
|
{
|
|
EVENT & event = m_pEvents->at( triggerID );
|
|
|
|
for( unsigned i = 0; i < event.size(); i++ )
|
|
{
|
|
if( event[i] )
|
|
{
|
|
event[i]->End();
|
|
delete event[i];
|
|
event[i] = NULL;
|
|
}
|
|
}
|
|
event.clear();
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
//트리거 에디팅을 위한 함수들
|
|
|
|
bool CBGMController::IsValidTriggerSelected()
|
|
{
|
|
if( m_iTriggerSelected >= m_pTriggerRegions->size() )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CBGMController::IsValidPointSelected()
|
|
{
|
|
if( m_iPointSelected >= (*m_pTriggerRegions)[ m_iTriggerSelected ].second.size() )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
|
|
unsigned CBGMController::AddTrigger()
|
|
{
|
|
m_pEventArgs->push_back( EVENTARG() );
|
|
m_pTriggerRegions->push_back( TRIGGERREGION() );
|
|
m_iTriggerSelected = m_pTriggerRegions->size() - 1;
|
|
|
|
TRIGGERREGION & added = m_pTriggerRegions->back();
|
|
added.first.push_back( m_iTriggerSelected );
|
|
|
|
m_pVertexes->push_back( VERTEXVECTOR() );
|
|
|
|
return m_iTriggerSelected;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
template < class T >
|
|
typename vector<T>::iterator GetIteratorOfIndex( vector<T> & Vector, unsigned index )
|
|
{
|
|
unsigned curIndex = 0;
|
|
|
|
for( vector<T>::iterator i = Vector.begin(); i != Vector.end(); i++ )
|
|
{
|
|
if( curIndex == index )
|
|
return i;
|
|
|
|
curIndex++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::DeleteTrigger()
|
|
{
|
|
if( !IsValidTriggerSelected() )
|
|
return;
|
|
|
|
EVENTARGS::iterator i = GetIteratorOfIndex( *m_pEventArgs, m_iTriggerSelected );
|
|
|
|
if( i != m_pEventArgs->end() )
|
|
m_pEventArgs->erase( i );
|
|
|
|
TRIGGERREGIONS::iterator i2 = GetIteratorOfIndex( *m_pTriggerRegions, m_iTriggerSelected );
|
|
|
|
if( i2 != m_pTriggerRegions->end() )
|
|
m_pTriggerRegions->erase( i2 );
|
|
|
|
TRIGGERVERTEXES::iterator i3 = GetIteratorOfIndex( *m_pVertexes, m_iTriggerSelected );
|
|
|
|
if( i3 != m_pVertexes->end() )
|
|
m_pVertexes->erase( i3 );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
bool CBGMController::SelectTrigger( unsigned index )
|
|
{
|
|
if( !IsValidTriggerSelected() )
|
|
return false;
|
|
|
|
m_iTriggerSelected = index;
|
|
m_iPointSelected = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
int CBGMController::AddEvent( int eventID, const char * szArg )
|
|
{
|
|
if( IsValidTriggerSelected() )
|
|
{
|
|
EVENTARG & eventArg = m_pEventArgs->at( m_iTriggerSelected );
|
|
eventArg.push_back( EVENTARGUNIT( eventID, szArg ) );
|
|
|
|
for( int i = 0; i < eventArg.size(); i++ )
|
|
{
|
|
EVENTARGUNIT & arg = eventArg[i];
|
|
}
|
|
|
|
return eventArg.size() - 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool CBGMController::SetEvent( int Event, int eventType, const char * szArg )
|
|
{
|
|
if( IsValidTriggerSelected() )
|
|
{
|
|
EVENTARG & eventArg = m_pEventArgs->at( m_iTriggerSelected );
|
|
eventArg[ Event ].first = eventType;
|
|
eventArg[ Event ].second = szArg;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CBGMController::GetEvent( int Event, int & eventType, char * szArg )
|
|
{
|
|
if( IsValidTriggerSelected() )
|
|
{
|
|
EVENTARG & eventArg = m_pEventArgs->at( m_iTriggerSelected );
|
|
eventType = eventArg[ Event ].first;
|
|
strcpy( szArg, eventArg[ Event ].second.c_str() );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CBGMController::DeleteEvent( int Event )
|
|
{
|
|
if( IsValidTriggerSelected() )
|
|
{
|
|
EVENTARG & eventArg = m_pEventArgs->at( m_iTriggerSelected );
|
|
EVENTARG::iterator iter = GetIteratorOfIndex( eventArg, Event );
|
|
if( iter != eventArg.end() )
|
|
eventArg.erase( iter );
|
|
|
|
|
|
for( int i = 0; i < eventArg.size(); i++ )
|
|
{
|
|
EVENTARGUNIT & arg = eventArg[i];
|
|
}
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::AddPointToVertexes( unsigned triggerIndex, float x, float y, float z )
|
|
{
|
|
if( triggerIndex >= m_pVertexes->size() )
|
|
return;
|
|
|
|
VERTEXVECTOR & vec = m_pVertexes->at( triggerIndex );
|
|
|
|
vec.push_back( D3DXVECTOR3( x, y, z ) );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::MovePointAtVertexes( unsigned triggerIndex, unsigned pointIndex, float x, float y, float z )
|
|
{
|
|
if( triggerIndex >= m_pVertexes->size() )
|
|
return;
|
|
|
|
VERTEXVECTOR & vec = m_pVertexes->at( triggerIndex );
|
|
|
|
vec[pointIndex] = D3DXVECTOR3( x, y, z );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::DeletePointAtVertexes( unsigned triggerIndex, unsigned pointIndex )
|
|
{
|
|
if( triggerIndex >= m_pVertexes->size() )
|
|
return;
|
|
|
|
VERTEXVECTOR & vec = m_pVertexes->at( triggerIndex );
|
|
|
|
VERTEXVECTOR::iterator it = GetIteratorOfIndex( vec, triggerIndex );
|
|
|
|
if( it == vec.end() )
|
|
return;
|
|
|
|
vec.erase( it );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
unsigned CBGMController::AddPoint( float x, float y, float z, long objID )
|
|
{
|
|
if( !IsValidTriggerSelected() )
|
|
return -1;
|
|
|
|
TRIGGERREGION & region = m_pTriggerRegions->at( m_iTriggerSelected );
|
|
region.second.push_back( SVector2( x, z ) );
|
|
|
|
unsigned size = region.second.size();
|
|
|
|
if( m_iTriggerSelected >= m_pContainer_ObjID->size() )
|
|
m_pContainer_ObjID->resize( m_iTriggerSelected + 1 );
|
|
|
|
m_iPointSelected = region.second.size() - 1;
|
|
|
|
if( m_iPointSelected >= (*m_pContainer_ObjID)[ m_iTriggerSelected ].size() )
|
|
(*m_pContainer_ObjID)[ m_iTriggerSelected ].resize( m_iPointSelected + 1 );
|
|
|
|
(*m_pContainer_ObjID)[ m_iTriggerSelected ][ m_iPointSelected ] = objID;
|
|
|
|
AddPointToVertexes( m_iTriggerSelected, x, y, z );
|
|
|
|
return m_iPointSelected;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::MovePoint( float x, float y, float z )
|
|
{
|
|
if( !IsValidTriggerSelected() )
|
|
return;
|
|
|
|
if( !IsValidPointSelected() )
|
|
return;
|
|
|
|
TRIGGERREGION & region = m_pTriggerRegions->at( m_iTriggerSelected );
|
|
|
|
region.second[ m_iPointSelected ].x = x;
|
|
region.second[ m_iPointSelected ].y = z;
|
|
|
|
MovePointAtVertexes( m_iTriggerSelected, m_iPointSelected, x, y, z );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::SetObjID( long objID )
|
|
{
|
|
if( m_iTriggerSelected >= m_pContainer_ObjID->size() )
|
|
m_pContainer_ObjID->resize( m_iTriggerSelected + 1 );
|
|
|
|
if( m_iPointSelected >= (*m_pContainer_ObjID)[ m_iTriggerSelected ].size() )
|
|
(*m_pContainer_ObjID)[ m_iTriggerSelected ].resize( m_iPointSelected + 1 );
|
|
|
|
(*m_pContainer_ObjID)[ m_iTriggerSelected ][ m_iPointSelected ] = objID;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::DeletePoint()
|
|
{
|
|
m_iLastDeleted = UINT_MAX;
|
|
|
|
if( !IsValidTriggerSelected() )
|
|
return;
|
|
|
|
if( !IsValidPointSelected() )
|
|
return;
|
|
|
|
TRIGGERREGION & region = m_pTriggerRegions->at( m_iTriggerSelected );
|
|
|
|
|
|
if( region.second.size() <= 3 )
|
|
{
|
|
throw bad_exception( "트리거를 이루는 점들이 3개 이상이 되어야 하므로 주어진 노드를 지울 수 없습니다." );
|
|
}
|
|
|
|
POLYGON::iterator it = GetIteratorOfIndex( region.second, m_iPointSelected );
|
|
region.second.erase( it );
|
|
|
|
DeletePointAtVertexes( m_iTriggerSelected, m_iPointSelected );
|
|
|
|
m_iLastDeleted = ( m_iTriggerSelected << 14 ) | m_iPointSelected;
|
|
|
|
m_iPointSelected--;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
/*
|
|
bool CBGMController::SelectPoint( unsigned index )
|
|
{
|
|
m_iPointSelected = index & 0x00003fff;
|
|
m_iTriggerSelected = ( index & 0xfffc000 ) >> 14;
|
|
|
|
if( !IsValidTriggerSelected() )
|
|
return false;
|
|
|
|
if( !IsValidPointSelected() )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
*/
|
|
bool CBGMController::SelectPoint( unsigned triggerIndex, unsigned pointIndex )
|
|
{
|
|
m_iPointSelected = pointIndex;
|
|
m_iTriggerSelected = triggerIndex;
|
|
|
|
if( !IsValidTriggerSelected() )
|
|
return false;
|
|
|
|
if( !IsValidPointSelected() )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
#define DISTANCE( x1, y1, x2, y2 ) sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
|
|
|
|
void CBGMController::SelectClosestPoint( float x, float y, float z, float limitDistance )
|
|
{
|
|
double fDistance = 100000.0f;
|
|
unsigned triggerIndex = UINT_MAX;
|
|
unsigned polygonIndex = UINT_MAX;
|
|
|
|
for( unsigned i = 0; i < m_pTriggerRegions->size(); i++ )
|
|
{
|
|
POLYGON & polygon = m_pTriggerRegions->at( i ).second;
|
|
|
|
for( unsigned i2 = 0; i2 < polygon.size(); i2++ )
|
|
{
|
|
double dist = DISTANCE( polygon[i2].x, polygon[i2].y, x, z ); //y는 높이 값이므로 무시
|
|
|
|
if( dist < fDistance )
|
|
{
|
|
fDistance = dist;
|
|
triggerIndex = i;
|
|
polygonIndex = i2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( fDistance <= limitDistance )
|
|
SelectPoint( triggerIndex, polygonIndex );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::GetPoint( float & x, float & y, float & z, long & objID )
|
|
{
|
|
TRIGGERREGION & region = m_pTriggerRegions->at( m_iTriggerSelected );
|
|
VERTEXVECTOR & vec = m_pVertexes->at( m_iTriggerSelected );
|
|
|
|
x = vec[m_iPointSelected].x;
|
|
y = vec[m_iPointSelected].y;
|
|
z = vec[m_iPointSelected].z;
|
|
|
|
// x = region.second[ m_iPointSelected ].x;
|
|
// y = 0.0f;
|
|
// z = region.second[ m_iPointSelected ].y;
|
|
objID = (*m_pContainer_ObjID)[ m_iTriggerSelected ][ m_iPointSelected ];
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Rebuild( float Epsilon )
|
|
{
|
|
m_pPrevTrigger = NULL;
|
|
m_pRegionTrigger->Create( *m_pTriggerRegions, Epsilon );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CBGMController::Render( IDirect3DDevice8 * p3DDevice )
|
|
{
|
|
DWORD cullmode = 0;
|
|
DWORD fillmode = 0;
|
|
p3DDevice->GetRenderState( D3DRS_CULLMODE, &cullmode );
|
|
p3DDevice->GetRenderState( D3DRS_CULLMODE, &fillmode );
|
|
CSceneStateMgr::_SetD3DRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
|
|
CSceneStateMgr::_SetD3DRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
|
p3DDevice->SetVertexShader( D3DFVF_XYZ );
|
|
|
|
for( unsigned i = 0; i < m_pVertexes->size(); i++ )
|
|
{
|
|
VERTEXVECTOR & vertex = m_pVertexes->at( i );
|
|
|
|
if( vertex.size() >= 3 )
|
|
{
|
|
p3DDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, vertex.size() - 2, vertex[0], sizeof( D3DXVECTOR3 ) );
|
|
}
|
|
}
|
|
CSceneStateMgr::_SetD3DRenderState( D3DRS_CULLMODE, cullmode );
|
|
CSceneStateMgr::_SetD3DRenderState( D3DRS_FILLMODE, fillmode );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
int CBGMController::GetPolygonCount()
|
|
{
|
|
return m_pVertexes->size();
|
|
}
|
|
|
|
int CBGMController::GetVertexCount( int i )
|
|
{
|
|
VERTEXVECTOR & vec = m_pVertexes->at( i );
|
|
return vec.size();
|
|
}
|
|
|
|
void CBGMController::GetVertex( int i, int j, float & x, float & y, float & z )
|
|
{
|
|
VERTEXVECTOR & vec = m_pVertexes->at( i );
|
|
x = vec[j].x;
|
|
y = vec[j].y;
|
|
z = vec[j].z;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|