layout: restructure into src/ tests/ android/ scripts/ tools/
- extension/src/{port,platform,codepage} -> src/; native_render -> src/host
(+ dxt, shaders/); libgr2 -> src/gr2; extension/third_party -> third_party
- extension/tests -> tests/port, libgr2/tests -> tests/gr2
- android-native -> android (build.sh, push-client.sh moved in)
- script -> scripts; tools/40250 -> tools/server; oracle -> tools/granny-oracle;
perf tools -> tools/perf
- all build trees under build/ (native, release, android, port-gate)
- xrender:: CMake aliases -> mt::; port-map ledger impl paths rewritten
No code changes. ctest 15/15, port_gate macos+android PASS, port_map check 0 errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
70710477cf
commit
a46093104c
@@ -0,0 +1,200 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterBase/Utils.h"
|
||||
#include "AttributeData.h"
|
||||
|
||||
const char c_szAttributeDataFileHeader[] = "AttributeData";
|
||||
const int c_iAttributeDataFileHeaderLength = 13;
|
||||
|
||||
/*DWORD CAttributeData::GetCollisionDataCount() const
|
||||
{
|
||||
return m_CollisionDataVector.size();
|
||||
}
|
||||
|
||||
BOOL CAttributeData::GetCollisionDataPointer(DWORD dwIndex, const TCollisionData ** c_ppCollisionData) const
|
||||
{
|
||||
if (dwIndex >= GetCollisionDataCount())
|
||||
return FALSE;
|
||||
|
||||
*c_ppCollisionData = &m_CollisionDataVector[dwIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
const CStaticCollisionDataVector & CAttributeData::GetCollisionDataVector() const
|
||||
{
|
||||
return m_StaticCollisionDataVector;
|
||||
}
|
||||
|
||||
const THeightDataVector & CAttributeData::GetHeightDataVector() const
|
||||
{
|
||||
return m_HeightDataVector;
|
||||
}
|
||||
|
||||
DWORD CAttributeData::GetHeightDataCount() const
|
||||
{
|
||||
return m_HeightDataVector.size();
|
||||
}
|
||||
|
||||
BOOL CAttributeData::GetHeightDataPointer(DWORD dwIndex, const THeightData ** c_ppHeightData) const
|
||||
{
|
||||
if (dwIndex >= GetHeightDataCount())
|
||||
return FALSE;
|
||||
|
||||
*c_ppHeightData = &m_HeightDataVector[dwIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
float CAttributeData::GetMaximizeRadius()
|
||||
{
|
||||
return m_fMaximizeRadius;
|
||||
}
|
||||
|
||||
size_t CAttributeData::AddCollisionData(const CStaticCollisionData& data)
|
||||
{
|
||||
m_StaticCollisionDataVector.push_back(data);
|
||||
return m_StaticCollisionDataVector.size();
|
||||
}
|
||||
|
||||
bool CAttributeData::OnLoad(int /*iSize*/, const void * c_pvBuf)
|
||||
{
|
||||
if (!c_pvBuf)
|
||||
{
|
||||
// NOTE: 파일이 존재하지 않으면 다른곳에서 그래픽 모델을 기반으로 충돌 데이터를 생성하니 리소스를 파괴하지 않고 유지시킴.
|
||||
return true;
|
||||
}
|
||||
|
||||
const BYTE * c_pbBuf = static_cast<const BYTE *> (c_pvBuf);
|
||||
|
||||
char szHeader[c_iAttributeDataFileHeaderLength+1];
|
||||
memcpy(szHeader, c_pbBuf, c_iAttributeDataFileHeaderLength+1);
|
||||
c_pbBuf += c_iAttributeDataFileHeaderLength+1;
|
||||
if (strcmp(szHeader, c_szAttributeDataFileHeader))
|
||||
return FALSE;
|
||||
|
||||
DWORD dwCollisionDataCount;
|
||||
DWORD dwHeightDataCount;
|
||||
memcpy(&dwCollisionDataCount, c_pbBuf, sizeof(DWORD));
|
||||
c_pbBuf += sizeof(DWORD);
|
||||
memcpy(&dwHeightDataCount, c_pbBuf, sizeof(DWORD));
|
||||
c_pbBuf += sizeof(DWORD);
|
||||
|
||||
m_StaticCollisionDataVector.clear();
|
||||
m_StaticCollisionDataVector.resize(dwCollisionDataCount);
|
||||
m_HeightDataVector.clear();
|
||||
m_HeightDataVector.resize(dwHeightDataCount);
|
||||
|
||||
for (DWORD i = 0; i < dwCollisionDataCount; ++i)
|
||||
{
|
||||
CStaticCollisionData & rCollisionData = m_StaticCollisionDataVector[i];
|
||||
memcpy(&rCollisionData.dwType, c_pbBuf, sizeof(DWORD));
|
||||
c_pbBuf += sizeof(DWORD);
|
||||
memcpy(rCollisionData.szName, c_pbBuf, 32);
|
||||
c_pbBuf += 32;
|
||||
memcpy(&rCollisionData.v3Position, c_pbBuf, sizeof(D3DXVECTOR3));
|
||||
c_pbBuf += sizeof(D3DXVECTOR3);
|
||||
|
||||
switch(rCollisionData.dwType)
|
||||
{
|
||||
case COLLISION_TYPE_PLANE:
|
||||
memcpy(rCollisionData.fDimensions, c_pbBuf, 2*sizeof(float));
|
||||
c_pbBuf += 2*sizeof(float);
|
||||
break;
|
||||
case COLLISION_TYPE_BOX:
|
||||
memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float));
|
||||
c_pbBuf += 3*sizeof(float);
|
||||
break;
|
||||
case COLLISION_TYPE_SPHERE:
|
||||
memcpy(rCollisionData.fDimensions, c_pbBuf, sizeof(float));
|
||||
c_pbBuf += sizeof(float);
|
||||
break;
|
||||
case COLLISION_TYPE_CYLINDER:
|
||||
memcpy(rCollisionData.fDimensions, c_pbBuf, 2*sizeof(float));
|
||||
c_pbBuf += 2*sizeof(float);
|
||||
break;
|
||||
case COLLISION_TYPE_AABB:
|
||||
memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float));
|
||||
c_pbBuf += 3*sizeof(float);
|
||||
break;
|
||||
case COLLISION_TYPE_OBB:
|
||||
memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float));
|
||||
c_pbBuf += 3*sizeof(float);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(rCollisionData.quatRotation, c_pbBuf, sizeof(D3DXQUATERNION));
|
||||
c_pbBuf += sizeof(D3DXQUATERNION);
|
||||
}
|
||||
|
||||
for (DWORD j = 0; j < dwHeightDataCount; ++j)
|
||||
{
|
||||
THeightData & rHeightData = m_HeightDataVector[j];
|
||||
memcpy(rHeightData.szName, c_pbBuf, 32);
|
||||
c_pbBuf += 32;
|
||||
|
||||
DWORD dwPrimitiveCount;
|
||||
memcpy(&dwPrimitiveCount, c_pbBuf, sizeof(DWORD));
|
||||
c_pbBuf += sizeof(DWORD);
|
||||
|
||||
rHeightData.v3VertexVector.clear();
|
||||
rHeightData.v3VertexVector.resize(dwPrimitiveCount);
|
||||
memcpy(&rHeightData.v3VertexVector[0], c_pbBuf, dwPrimitiveCount*sizeof(D3DXVECTOR3));
|
||||
c_pbBuf += dwPrimitiveCount*sizeof(D3DXVECTOR3);
|
||||
|
||||
// Getting Maximize Radius
|
||||
for (DWORD k = 0; k < rHeightData.v3VertexVector.size(); ++k)
|
||||
{
|
||||
m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].x)+50.0f);
|
||||
m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].y)+50.0f);
|
||||
m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].z)+50.0f);
|
||||
}
|
||||
// Getting Maximize Radius
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAttributeData::OnClear()
|
||||
{
|
||||
m_StaticCollisionDataVector.clear();
|
||||
m_HeightDataVector.clear();
|
||||
}
|
||||
|
||||
bool CAttributeData::OnIsEmpty() const
|
||||
{
|
||||
if (!m_StaticCollisionDataVector.empty())
|
||||
return false;
|
||||
if (!m_HeightDataVector.empty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAttributeData::OnIsType(TType type)
|
||||
{
|
||||
if (CAttributeData::Type() == type)
|
||||
return true;
|
||||
|
||||
return CResource::OnIsType(type);
|
||||
}
|
||||
|
||||
CAttributeData::TType CAttributeData::Type()
|
||||
{
|
||||
static TType s_type = StringToType("CAttributeData");
|
||||
return s_type;
|
||||
}
|
||||
|
||||
void CAttributeData::OnSelfDestruct()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CAttributeData::CAttributeData(const char * c_szFileName) : CResource(c_szFileName)
|
||||
{
|
||||
m_fMaximizeRadius = 0.0f;
|
||||
}
|
||||
|
||||
CAttributeData::~CAttributeData()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Ref.h"
|
||||
#include "CollisionData.h"
|
||||
|
||||
typedef struct SHeightData
|
||||
{
|
||||
char szName[32+1];
|
||||
std::vector<D3DXVECTOR3> v3VertexVector;
|
||||
} THeightData;
|
||||
|
||||
typedef std::vector<THeightData> THeightDataVector;
|
||||
|
||||
class CAttributeData : public CResource
|
||||
{
|
||||
public:
|
||||
typedef CRef<CAttributeData> TRef;
|
||||
|
||||
/*
|
||||
enum ECollisionType
|
||||
{
|
||||
COLLISION_TYPE_PLANE,
|
||||
COLLISION_TYPE_BOX,
|
||||
COLLISION_TYPE_SPHERE,
|
||||
COLLISION_TYPE_CYLINDER,
|
||||
};
|
||||
|
||||
typedef struct SCollisionData
|
||||
{
|
||||
DWORD dwType;
|
||||
char szName[32+1];
|
||||
|
||||
D3DXVECTOR3 v3Position;
|
||||
float fDimensions[3];
|
||||
D3DXQUATERNION quatRotation;
|
||||
} TCollisionData;*/
|
||||
|
||||
public:
|
||||
static TType Type();
|
||||
|
||||
public:
|
||||
CAttributeData(const char * c_szFileName);
|
||||
virtual ~CAttributeData();
|
||||
|
||||
//DWORD GetCollisionDataCount() const;
|
||||
//BOOL GetCollisionDataPointer(DWORD dwIndex, const TCollisionData ** c_ppCollisionData) const;
|
||||
const CStaticCollisionDataVector & GetCollisionDataVector() const;
|
||||
const THeightDataVector & GetHeightDataVector() const;
|
||||
|
||||
size_t AddCollisionData(const CStaticCollisionData& collisionData); // return m_StaticCollisionDataVector.size();
|
||||
|
||||
DWORD GetHeightDataCount() const;
|
||||
BOOL GetHeightDataPointer(DWORD dwIndex, const THeightData ** c_ppHeightData) const;
|
||||
|
||||
float GetMaximizeRadius();
|
||||
|
||||
protected:
|
||||
bool OnLoad(int iSize, const void * c_pvBuf);
|
||||
void OnClear();
|
||||
bool OnIsEmpty() const;
|
||||
bool OnIsType(TType type);
|
||||
void OnSelfDestruct();
|
||||
|
||||
protected:
|
||||
float m_fMaximizeRadius;
|
||||
|
||||
//std::vector<TCollisionData> m_CollisionDataVector;
|
||||
CStaticCollisionDataVector m_StaticCollisionDataVector;
|
||||
THeightDataVector m_HeightDataVector;
|
||||
};
|
||||
@@ -0,0 +1,222 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterBase/Utils.h"
|
||||
#include "AttributeInstance.h"
|
||||
#include "GrpMath.h"
|
||||
|
||||
CDynamicPool<CAttributeInstance> CAttributeInstance::ms_kPool;
|
||||
|
||||
const float c_fStepSize = 50.0f;
|
||||
|
||||
bool CAttributeInstance::Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y)
|
||||
{
|
||||
if (IsEmpty())
|
||||
return FALSE;
|
||||
//fy *= -1.0f;
|
||||
|
||||
bool bPicked = false;
|
||||
float nx = 0;
|
||||
float ny = 0;
|
||||
|
||||
for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i)
|
||||
for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3)
|
||||
{
|
||||
const D3DXVECTOR3 & cv0 = m_v3HeightDataVector[i][j];
|
||||
const D3DXVECTOR3 & cv2 = m_v3HeightDataVector[i][j+1];
|
||||
const D3DXVECTOR3 & cv1 = m_v3HeightDataVector[i][j+2];
|
||||
|
||||
D3DXVECTOR3 n;
|
||||
const auto vvv = (cv1 - cv0);
|
||||
const auto vvv2 = (cv2 - cv0);
|
||||
const auto vvv3 = (cv2 - cv1);
|
||||
D3DXVec3Cross(&n,&vvv,&vvv2);
|
||||
D3DXVECTOR3 x;
|
||||
float t;
|
||||
const auto _vv = (v - cv0);
|
||||
t = - D3DXVec3Dot(&_vv,&n)/D3DXVec3Dot(&dir,&n);
|
||||
|
||||
x = v+t*dir;
|
||||
const auto vvv4 = (x - cv0);
|
||||
const auto vvv5 = (x - cv1);
|
||||
const auto vvv6 = (x - cv2);
|
||||
D3DXVECTOR3 temp;
|
||||
D3DXVec3Cross(&temp,&vvv,&vvv4);
|
||||
if (D3DXVec3Dot(&temp,&n)<0) continue;
|
||||
D3DXVec3Cross(&temp,&vvv3,&vvv5);
|
||||
if (D3DXVec3Dot(&temp,&n)<0) continue;
|
||||
const auto _vv_ = (cv0 - cv2);
|
||||
D3DXVec3Cross(&temp,&_vv_,&vvv6);
|
||||
if (D3DXVec3Dot(&temp,&n)<0) continue;
|
||||
|
||||
if (bPicked)
|
||||
{
|
||||
if ((v.x-x.x)*(v.x-x.x)+(v.y-x.y)*(v.y-x.y)<(v.x-nx)*(v.x-nx)+(v.y-ny)*(v.y-ny))
|
||||
{
|
||||
nx=x.x;
|
||||
ny=x.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nx = x.x;
|
||||
ny = x.y;
|
||||
}
|
||||
bPicked = true;
|
||||
}
|
||||
if (bPicked)
|
||||
{
|
||||
out_x = nx;
|
||||
out_y = ny;
|
||||
}
|
||||
return bPicked;
|
||||
}
|
||||
|
||||
BOOL CAttributeInstance::GetHeight(float fx, float fy, float * pfHeight)
|
||||
{
|
||||
if(IsEmpty())
|
||||
return FALSE;
|
||||
|
||||
fy *= -1.0f;
|
||||
|
||||
if (!IsInHeight(fx, fy))
|
||||
return FALSE;
|
||||
|
||||
BOOL bFlag = FALSE;
|
||||
|
||||
for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i)
|
||||
for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3)
|
||||
{
|
||||
const D3DXVECTOR3 & c_rv3Vertex0 = m_v3HeightDataVector[i][j];
|
||||
const D3DXVECTOR3 & c_rv3Vertex1 = m_v3HeightDataVector[i][j+1];
|
||||
const D3DXVECTOR3 & c_rv3Vertex2 = m_v3HeightDataVector[i][j+2];
|
||||
|
||||
if (
|
||||
fx<c_rv3Vertex0.x && fx<c_rv3Vertex1.x && fx<c_rv3Vertex2.x ||
|
||||
fx>c_rv3Vertex0.x && fx>c_rv3Vertex1.x && fx>c_rv3Vertex2.x ||
|
||||
fy<c_rv3Vertex0.y && fy<c_rv3Vertex1.y && fy<c_rv3Vertex2.y ||
|
||||
fy>c_rv3Vertex0.y && fy>c_rv3Vertex1.y && fy>c_rv3Vertex2.y
|
||||
)
|
||||
continue;
|
||||
|
||||
if (IsInTriangle2D(c_rv3Vertex0.x, c_rv3Vertex0.y,
|
||||
c_rv3Vertex1.x, c_rv3Vertex1.y,
|
||||
c_rv3Vertex2.x, c_rv3Vertex2.y, fx, fy))
|
||||
{
|
||||
D3DXVECTOR3 v3Line1 = c_rv3Vertex1 - c_rv3Vertex0;
|
||||
D3DXVECTOR3 v3Line2 = c_rv3Vertex2 - c_rv3Vertex0;
|
||||
D3DXVECTOR3 v3Cross;
|
||||
|
||||
D3DXVec3Cross(&v3Cross, &v3Line1, &v3Line2);
|
||||
D3DXVec3Normalize(&v3Cross, &v3Cross);
|
||||
|
||||
if (0.0f != v3Cross.z)
|
||||
{
|
||||
float fd = (v3Cross.x*c_rv3Vertex0.x + v3Cross.y*c_rv3Vertex0.y + v3Cross.z*c_rv3Vertex0.z);
|
||||
float fm = (v3Cross.x*fx + v3Cross.y*fy);
|
||||
*pfHeight = fMAX((fd - fm) / v3Cross.z, *pfHeight);
|
||||
|
||||
bFlag = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bFlag;
|
||||
}
|
||||
|
||||
CAttributeData * CAttributeInstance::GetObjectPointer() const
|
||||
{
|
||||
return m_roAttributeData.GetPointer();
|
||||
}
|
||||
BOOL CAttributeInstance::IsInHeight(float fx, float fy)
|
||||
{
|
||||
float fdx = m_matGlobal._41 - fx;
|
||||
float fdy = m_matGlobal._42 - fy;
|
||||
if (sqrtf(fdx*fdx + fdy*fdy) > m_fHeightRadius)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CAttributeInstance::SetObjectPointer(CAttributeData * pAttributeData)
|
||||
{
|
||||
Clear();
|
||||
m_roAttributeData.SetPointer(pAttributeData);
|
||||
}
|
||||
|
||||
void CAttributeInstance::RefreshObject(const D3DXMATRIX & c_rmatGlobal)
|
||||
{
|
||||
assert(!m_roAttributeData.IsNull());
|
||||
|
||||
m_matGlobal = c_rmatGlobal;
|
||||
|
||||
// Height
|
||||
m_fHeightRadius = m_roAttributeData->GetMaximizeRadius();
|
||||
|
||||
DWORD dwHeightDataCount = m_roAttributeData->GetHeightDataCount();
|
||||
m_v3HeightDataVector.clear();
|
||||
m_v3HeightDataVector.resize(dwHeightDataCount);
|
||||
for (DWORD i = 0; i < dwHeightDataCount; ++i)
|
||||
{
|
||||
const THeightData * c_pHeightData;
|
||||
if (!m_roAttributeData->GetHeightDataPointer(i, &c_pHeightData))
|
||||
continue;
|
||||
|
||||
DWORD dwVertexCount = c_pHeightData->v3VertexVector.size();
|
||||
m_v3HeightDataVector[i].clear();
|
||||
m_v3HeightDataVector[i].resize(dwVertexCount);
|
||||
for (DWORD j = 0; j < dwVertexCount; ++j)
|
||||
{
|
||||
D3DXVec3TransformCoord(&m_v3HeightDataVector[i][j], &c_pHeightData->v3VertexVector[j], &m_matGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char * CAttributeInstance::GetDataFileName() const
|
||||
{
|
||||
return m_roAttributeData->GetFileName();
|
||||
}
|
||||
|
||||
void CAttributeInstance::CreateSystem(UINT uCapacity)
|
||||
{
|
||||
ms_kPool.Create(uCapacity);
|
||||
}
|
||||
|
||||
void CAttributeInstance::DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
}
|
||||
|
||||
CAttributeInstance* CAttributeInstance::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CAttributeInstance::Delete(CAttributeInstance* pkInst)
|
||||
{
|
||||
ms_kPool.Free(pkInst);
|
||||
}
|
||||
|
||||
BOOL CAttributeInstance::IsEmpty() const
|
||||
{
|
||||
if (!m_v3HeightDataVector.empty())
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CAttributeInstance::Clear()
|
||||
{
|
||||
m_fHeightRadius = 0.0f;
|
||||
m_fCollisionRadius = 0.0f;
|
||||
D3DXMatrixIdentity(&m_matGlobal);
|
||||
|
||||
m_v3HeightDataVector.clear();
|
||||
|
||||
m_roAttributeData.SetPointer(NULL);
|
||||
}
|
||||
|
||||
CAttributeInstance::CAttributeInstance()
|
||||
{
|
||||
}
|
||||
CAttributeInstance::~CAttributeInstance()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "AttributeData.h"
|
||||
#include "Pool.h"
|
||||
|
||||
class CAttributeInstance
|
||||
{
|
||||
public:
|
||||
CAttributeInstance();
|
||||
virtual ~CAttributeInstance();
|
||||
|
||||
void Clear();
|
||||
BOOL IsEmpty() const;
|
||||
|
||||
const char * GetDataFileName() const;
|
||||
|
||||
// NOTE : Object 전용
|
||||
void SetObjectPointer(CAttributeData * pAttributeData);
|
||||
void RefreshObject(const D3DXMATRIX & c_rmatGlobal);
|
||||
CAttributeData * GetObjectPointer() const;
|
||||
|
||||
bool Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y);
|
||||
|
||||
BOOL IsInHeight(float fx, float fy);
|
||||
BOOL GetHeight(float fx, float fy, float * pfHeight);
|
||||
|
||||
BOOL IsHeightData() const;
|
||||
|
||||
protected:
|
||||
void SetGlobalMatrix(const D3DXMATRIX & c_rmatGlobal);
|
||||
void SetGlobalPosition(const D3DXVECTOR3 & c_rv3Position);
|
||||
|
||||
protected:
|
||||
float m_fCollisionRadius;
|
||||
float m_fHeightRadius;
|
||||
|
||||
D3DXMATRIX m_matGlobal;
|
||||
|
||||
std::vector< std::vector<D3DXVECTOR3> > m_v3HeightDataVector;
|
||||
|
||||
CAttributeData::TRef m_roAttributeData;
|
||||
|
||||
/*
|
||||
BOOL m_isHeightCached;
|
||||
struct SHeightCacheData
|
||||
{
|
||||
float fxMin;
|
||||
float fyMin;
|
||||
float fxMax;
|
||||
float fyMax;
|
||||
DWORD dwxStep;
|
||||
DWORD dwyStep;
|
||||
std::vector<float> kVec_fHeight;
|
||||
} m_kHeightCacheData;
|
||||
*/
|
||||
|
||||
public:
|
||||
static void CreateSystem(UINT uCapacity);
|
||||
static void DestroySystem();
|
||||
|
||||
static CAttributeInstance* New();
|
||||
static void Delete(CAttributeInstance* pkInst);
|
||||
|
||||
static CDynamicPool<CAttributeInstance> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,644 @@
|
||||
// Camera.cpp: implementation of the CCamera class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "../EterBase/Utils.h"
|
||||
#include "Camera.h"
|
||||
|
||||
const float c_fDefaultResistance = 0.3f;
|
||||
|
||||
CCameraManager aCameraManager; // CCameraManager Instance
|
||||
|
||||
void CCamera::SetCameraMaxDistance(float fMax)
|
||||
{
|
||||
CAMERA_MAX_DISTANCE = fMax;
|
||||
}
|
||||
|
||||
float CCamera::GetTargetHeight()
|
||||
{
|
||||
return m_fTarget_;
|
||||
}
|
||||
|
||||
void CCamera::SetTargetHeight(float fTarget)
|
||||
{
|
||||
m_fTarget_=fTarget;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CCamera
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
CCamera::CCamera() :
|
||||
m_fEyeGroundHeightRatio(0.3f),
|
||||
m_fTargetHeightLimitRatio(2.0f),
|
||||
m_fResistance(c_fDefaultResistance),
|
||||
m_isLock(false)
|
||||
{
|
||||
m_fDistance = 1.0f;
|
||||
m_eCameraState = CAMERA_STATE_NORMAL;
|
||||
m_eCameraStatePrev = CAMERA_STATE_NORMAL;
|
||||
m_ulNumScreenBuilding = 0;
|
||||
|
||||
m_fPitchSum = 0.0f;
|
||||
m_fRollSum = 0.0f;
|
||||
|
||||
m_fTerrainCollisionRadius = 50.0f;
|
||||
m_fObjectCollisionRadius = 50.0f;
|
||||
|
||||
m_bDrag = false;
|
||||
|
||||
m_lMousePosX = -1;
|
||||
m_lMousePosY = -1;
|
||||
|
||||
m_fTarget_ = CAMERA_TARGET_STANDARD;
|
||||
|
||||
m_v3AngularAcceleration = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_v3AngularVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_bProcessTerrainCollision = true;
|
||||
|
||||
SetViewParams(D3DXVECTOR3(0.0f,0.0f,1.0f), D3DXVECTOR3(0.0f,0.0f,0.0f), D3DXVECTOR3(0.0f,1.0f,0.0f));
|
||||
}
|
||||
|
||||
CCamera::~CCamera()
|
||||
{
|
||||
}
|
||||
|
||||
void CCamera::Lock()
|
||||
{
|
||||
m_isLock = true;
|
||||
}
|
||||
|
||||
void CCamera::Unlock()
|
||||
{
|
||||
m_isLock = false;
|
||||
}
|
||||
|
||||
bool CCamera::IsLock()
|
||||
{
|
||||
return m_isLock;
|
||||
}
|
||||
|
||||
void CCamera::SetResistance(float fResistance)
|
||||
{
|
||||
m_fResistance = c_fDefaultResistance * fResistance;
|
||||
}
|
||||
|
||||
void CCamera::Wheel(int nLen)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
float fAdd = (float)(nLen) * m_fResistance;
|
||||
if ((m_v3AngularVelocity.y > 0.0f && fAdd < 0.0f) || (m_v3AngularVelocity.y < 0.0f && fAdd > 0.0f))
|
||||
m_v3AngularVelocity.y = fAdd;
|
||||
else
|
||||
m_v3AngularVelocity.y += fAdd;
|
||||
|
||||
if (m_v3AngularVelocity.y > 500.0f)
|
||||
m_v3AngularVelocity.y = 500.0f;
|
||||
else if (m_v3AngularVelocity.y < -500.0f)
|
||||
m_v3AngularVelocity.y = -500.0f;
|
||||
}
|
||||
|
||||
void CCamera::BeginDrag(int nMouseX, int nMouseY)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
m_bDrag = true;
|
||||
m_lMousePosX = nMouseX;
|
||||
m_lMousePosY = nMouseY;
|
||||
m_fPitchSum = 0.0f;
|
||||
m_fRollSum = 0.0f;
|
||||
}
|
||||
|
||||
bool CCamera::IsDraging()
|
||||
{
|
||||
if (IsLock())
|
||||
return false;
|
||||
|
||||
return m_bDrag;
|
||||
}
|
||||
|
||||
bool CCamera::EndDrag()
|
||||
{
|
||||
if (IsLock())
|
||||
return false;
|
||||
|
||||
m_bDrag = false;
|
||||
|
||||
float fSum=sqrt(m_fPitchSum*m_fPitchSum+m_fRollSum*m_fRollSum);
|
||||
|
||||
m_fPitchSum = 0.0f;
|
||||
m_fRollSum = 0.0f;
|
||||
|
||||
if (fSum<1.0f)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCamera::Drag(int nMouseX, int nMouseY, LPPOINT lpReturnPoint)
|
||||
{
|
||||
if (IsLock())
|
||||
return false;
|
||||
|
||||
if (!m_bDrag)
|
||||
{
|
||||
m_lMousePosX = nMouseX;
|
||||
m_lMousePosY = nMouseY;
|
||||
lpReturnPoint->x = m_lMousePosX;
|
||||
lpReturnPoint->y = m_lMousePosY;
|
||||
return false;
|
||||
}
|
||||
|
||||
long lMouseX = nMouseX;
|
||||
long lMouseY = nMouseY;
|
||||
|
||||
float fNewPitchVelocity = (float)(lMouseY - m_lMousePosY) * m_fResistance;
|
||||
float fNewRotationVelocity = (float)(lMouseX - m_lMousePosX) * m_fResistance;
|
||||
|
||||
m_fPitchSum += fNewPitchVelocity;
|
||||
m_fRollSum += fNewRotationVelocity;
|
||||
|
||||
|
||||
if (CAMERA_STATE_CANTGOLEFT == GetCameraState())
|
||||
fNewRotationVelocity = fMAX(0.0f, fNewRotationVelocity);
|
||||
if (CAMERA_STATE_CANTGORIGHT == GetCameraState())
|
||||
fNewRotationVelocity = fMIN(0.0f, fNewRotationVelocity);
|
||||
if (CAMERA_STATE_CANTGODOWN == GetCameraState())
|
||||
fNewPitchVelocity = fMAX(0.0f, fNewPitchVelocity);
|
||||
|
||||
m_v3AngularVelocity.x = fNewRotationVelocity;
|
||||
m_v3AngularVelocity.z = fNewPitchVelocity;
|
||||
|
||||
m_lMousePosX = lMouseX;
|
||||
m_lMousePosY = lMouseY;
|
||||
lpReturnPoint->x = m_lMousePosX;
|
||||
lpReturnPoint->y = m_lMousePosY;
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Update
|
||||
|
||||
void CCamera::SetCameraState(eCameraState eNewCameraState)
|
||||
{
|
||||
if (eNewCameraState == m_eCameraState)
|
||||
return;
|
||||
|
||||
m_eCameraStatePrev = m_eCameraState;
|
||||
m_eCameraState = eNewCameraState;
|
||||
|
||||
/*
|
||||
if ((CAMERA_STATE_NORMAL == m_eCameraStatePrev))
|
||||
{
|
||||
m_fDistanceBackup = m_fDistance;
|
||||
m_fPitchBackup = m_fPitch;
|
||||
m_fRollBackup = m_fRoll;
|
||||
}
|
||||
else if ((CAMERA_STATE_CANTGODOWN == m_eCameraStatePrev) && (CAMERA_STATE_CANTGODOWN == m_eCameraState) )
|
||||
{
|
||||
m_v3EyeBackup = m_v3Eye;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CCamera::IncreaseNumSrcreenBuilding()
|
||||
{
|
||||
++m_ulNumScreenBuilding;
|
||||
}
|
||||
|
||||
void CCamera::ResetNumScreenBuilding()
|
||||
{
|
||||
m_ulNumScreenBuilding = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Property
|
||||
void CCamera::SetViewParams( const D3DXVECTOR3 &v3Eye, const D3DXVECTOR3& v3Target, const D3DXVECTOR3& v3Up)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
// Set attributes for the view matrix
|
||||
m_v3Eye = v3Eye;
|
||||
m_v3Target = v3Target;
|
||||
m_v3Up = v3Up;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::SetEye(const D3DXVECTOR3 & v3Eye)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
m_v3Eye = v3Eye;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::SetTarget(const D3DXVECTOR3 & v3Target)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
m_v3Target = v3Target;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::SetUp(const D3DXVECTOR3 & v3Up)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
m_v3Up = v3Up;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::SetViewMatrix()
|
||||
{
|
||||
m_v3View = m_v3Target - m_v3Eye;
|
||||
D3DXVECTOR3 v3CenterRay = -m_v3View;
|
||||
CalculateRoll();
|
||||
m_fDistance = D3DXVec3Length(&m_v3View);
|
||||
assert(m_fDistance >= 0);
|
||||
D3DXVec3Normalize(&m_v3View , &m_v3View);
|
||||
|
||||
D3DXVec3Cross(&m_v3Cross, &m_v3Up, &m_v3View);
|
||||
D3DXVec3Normalize(&m_v3Cross, &m_v3Cross);
|
||||
|
||||
D3DXVec3Cross(&m_v3Up, &m_v3View, &m_v3Cross);
|
||||
D3DXVec3Normalize(&m_v3Up, &m_v3Up);
|
||||
const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
m_fPitch = D3DXVec3Dot(&m_v3Up, &vv);// / D3DXVec2Length(&v2ViewYZ);
|
||||
if (m_fPitch >= 1)
|
||||
m_fPitch = 1;
|
||||
else if (m_fPitch <= -1)
|
||||
m_fPitch = -1;
|
||||
m_fPitch = acosf(m_fPitch);
|
||||
m_fPitch *= (180.0f / D3DX_PI);
|
||||
if ( 0 < m_v3View.z )
|
||||
m_fPitch = -m_fPitch;
|
||||
|
||||
D3DXMatrixLookAtRH(&m_matView, &m_v3Eye, &m_v3Target, &m_v3Up);
|
||||
|
||||
float fDeterminantD3DMatView = D3DXMatrixfDeterminant(&m_matView);
|
||||
D3DXMatrixInverse(&m_matInverseView, &fDeterminantD3DMatView, &m_matView);
|
||||
|
||||
m_matBillboard = m_matInverseView;
|
||||
m_matBillboard._41 = 0.0f;
|
||||
m_matBillboard._42 = 0.0f;
|
||||
m_matBillboard._43 = 0.0f;
|
||||
|
||||
m_ViewRay.SetStartPoint(m_v3Target);
|
||||
m_ViewRay.SetDirection(v3CenterRay, m_fDistance);
|
||||
|
||||
m_kCameraBottomToTerrainRay.SetStartPoint(m_v3Eye);
|
||||
m_kCameraFrontToTerrainRay.SetStartPoint(m_v3Eye);
|
||||
m_kCameraBackToTerrainRay.SetStartPoint(m_v3Eye);
|
||||
m_kCameraLeftToTerrainRay.SetStartPoint(m_v3Eye);
|
||||
m_kCameraRightToTerrainRay.SetStartPoint(m_v3Eye);
|
||||
m_kTargetToCameraBottomRay.SetStartPoint(m_v3Target);
|
||||
|
||||
m_kCameraBottomToTerrainRay.SetDirection(-m_v3Up, 2.0f * m_fTerrainCollisionRadius);
|
||||
m_kCameraFrontToTerrainRay.SetDirection(m_v3View, 4.0f * m_fTerrainCollisionRadius);
|
||||
m_kCameraBackToTerrainRay.SetDirection(-m_v3View, m_fTerrainCollisionRadius);
|
||||
m_kCameraLeftToTerrainRay.SetDirection(-m_v3Cross, 3.0f * m_fTerrainCollisionRadius);
|
||||
m_kCameraRightToTerrainRay.SetDirection(m_v3Cross, 3.0f * m_fTerrainCollisionRadius);
|
||||
const auto vv2 = (v3CenterRay - m_fTerrainCollisionRadius * m_v3Up);
|
||||
m_kTargetToCameraBottomRay.SetDirection(v3CenterRay - m_fTerrainCollisionRadius * m_v3Up, D3DXVec3Length(&vv2));
|
||||
|
||||
m_kLeftObjectCollisionRay.SetStartPoint(m_v3Target);
|
||||
m_kTopObjectCollisionRay.SetStartPoint(m_v3Target);
|
||||
m_kRightObjectCollisionRay.SetStartPoint(m_v3Target);
|
||||
m_kBottomObjectCollisionRay.SetStartPoint(m_v3Target);
|
||||
const auto vv3 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Cross);
|
||||
const auto vv4 = (v3CenterRay - m_fObjectCollisionRadius * m_v3Cross);
|
||||
const auto vv5 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Up);
|
||||
const auto vv6 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Up);
|
||||
m_kLeftObjectCollisionRay.SetDirection(v3CenterRay + m_fObjectCollisionRadius * m_v3Cross, D3DXVec3Length(&vv3));
|
||||
m_kRightObjectCollisionRay.SetDirection(v3CenterRay - m_fObjectCollisionRadius * m_v3Cross, D3DXVec3Length(&vv4));
|
||||
m_kTopObjectCollisionRay.SetDirection(v3CenterRay + m_fObjectCollisionRadius * m_v3Up, D3DXVec3Length(&vv5));
|
||||
m_kBottomObjectCollisionRay.SetDirection(v3CenterRay - m_fObjectCollisionRadius * m_v3Up, D3DXVec3Length(&vv6));
|
||||
}
|
||||
|
||||
void CCamera::Move(const D3DXVECTOR3 & v3Displacement)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
m_v3Eye += v3Displacement;
|
||||
m_v3Target += v3Displacement;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::Zoom(float fRatio)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
if (fRatio == 1.0f)
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 v3Temp = m_v3Eye - m_v3Target;
|
||||
v3Temp *= fRatio;
|
||||
m_v3Eye = v3Temp + m_v3Target;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::MoveAlongView(float fDistance)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 v3Temp;
|
||||
D3DXVec3Normalize(&v3Temp, &m_v3View);
|
||||
|
||||
m_v3Eye += v3Temp * fDistance;
|
||||
m_v3Target += v3Temp * fDistance;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::MoveAlongCross(float fDistance)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 v3Temp;
|
||||
D3DXVec3Normalize(&v3Temp, &m_v3Cross);
|
||||
|
||||
m_v3Eye += v3Temp * fDistance;
|
||||
m_v3Target += v3Temp * fDistance;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::MoveAlongUp(FLOAT fDistance)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 v3Temp ;
|
||||
D3DXVec3Normalize(&v3Temp, &m_v3Up);
|
||||
m_v3Target += v3Temp * fDistance;
|
||||
m_v3Eye += v3Temp * fDistance;
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::MoveLateral(float fDistance)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
MoveAlongCross(fDistance);
|
||||
}
|
||||
|
||||
void CCamera::MoveFront(float fDistance)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 v3Temp = D3DXVECTOR3(m_v3View.x, m_v3View.y, 0.0f);
|
||||
D3DXVec3Normalize(&v3Temp, &v3Temp);
|
||||
|
||||
m_v3Eye += v3Temp * fDistance;
|
||||
m_v3Target += v3Temp * fDistance;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::MoveVertical(float fDistance)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
m_v3Eye.z += fDistance;
|
||||
m_v3Target.z += fDistance;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
//void CCamera::RotateUpper(float fDegree)
|
||||
//{
|
||||
// D3DXMATRIX matRot;
|
||||
// D3DXMatrixRotationAxis(&matRot, &m_v3Cross, -D3DXToRadian(fDegree));
|
||||
// D3DXVec3TransformCoord(&m_v3View, &m_v3View, &matRot) ;
|
||||
// D3DXVec3Cross(&m_v3Up, &m_v3View, &m_v3Cross);
|
||||
//
|
||||
// m_v3Target = m_v3Eye + m_v3View;
|
||||
//
|
||||
// SetViewMatrix() ;
|
||||
//}
|
||||
|
||||
void CCamera::RotateEyeAroundTarget(float fPitchDegree, float fRollDegree)
|
||||
{
|
||||
if (IsLock())
|
||||
return;
|
||||
|
||||
D3DXMATRIX matRot, matRotPitch, matRotRoll;
|
||||
|
||||
// 머리위로 넘어가기 막기...
|
||||
if (m_fPitch + fPitchDegree > 80.0f)
|
||||
{
|
||||
fPitchDegree = 80.0f - m_fPitch;
|
||||
}
|
||||
else if( m_fPitch + fPitchDegree < -80.0f)
|
||||
{
|
||||
fPitchDegree = -80.0f - m_fPitch;
|
||||
}
|
||||
|
||||
D3DXMatrixRotationAxis(&matRotPitch, &m_v3Cross, D3DXToRadian(fPitchDegree));
|
||||
|
||||
D3DXMatrixRotationZ(&matRotRoll, -D3DXToRadian(fRollDegree));
|
||||
matRot = matRotPitch * matRotRoll;
|
||||
|
||||
D3DXVECTOR3 v3Temp = m_v3Eye - m_v3Target;
|
||||
D3DXVec3TransformCoord(&m_v3Eye, &v3Temp, &matRot);
|
||||
m_v3Eye += m_v3Target;
|
||||
|
||||
SetUp(D3DXVECTOR3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
m_fRoll += fRollDegree;
|
||||
|
||||
if (m_fRoll > 360.0f)
|
||||
m_fRoll -= 360.0f;
|
||||
else if (m_fRoll < -360.0f)
|
||||
m_fRoll += 360.0f;
|
||||
}
|
||||
|
||||
void CCamera::RotateEyeAroundPoint(const D3DXVECTOR3 & v3Point, float fPitchDegree, float fRollDegree)
|
||||
{
|
||||
// if (IsLock())
|
||||
// return;
|
||||
|
||||
D3DXMATRIX matRot, matRotPitch, matRotRoll;
|
||||
|
||||
D3DXMatrixRotationAxis(&matRotPitch, &m_v3Cross, D3DXToRadian(fPitchDegree));
|
||||
|
||||
D3DXMatrixRotationZ(&matRotRoll, -D3DXToRadian(fRollDegree));
|
||||
matRot = matRotPitch * matRotRoll;
|
||||
|
||||
D3DXVECTOR3 v3Temp = m_v3Eye - v3Point;
|
||||
D3DXVec3TransformCoord(&m_v3Eye, &v3Temp, &matRot);
|
||||
m_v3Eye += v3Point;
|
||||
|
||||
const auto vv2 = (v3Temp + m_v3Up);
|
||||
D3DXVec3TransformCoord(&m_v3Up, &vv2, &matRot);
|
||||
m_v3Up -= (m_v3Eye - v3Point);
|
||||
|
||||
v3Temp = m_v3Target - v3Point;
|
||||
D3DXVec3TransformCoord(&m_v3Target, &v3Temp, &matRot);
|
||||
m_v3Target += v3Point;
|
||||
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CCamera::Pitch(const float fPitchDelta)
|
||||
{
|
||||
// if (IsLock())
|
||||
// return;
|
||||
|
||||
RotateEyeAroundTarget(fPitchDelta, 0.0f);
|
||||
}
|
||||
|
||||
void CCamera::Roll(const float fRollDelta)
|
||||
{
|
||||
// if (IsLock())
|
||||
// return;
|
||||
|
||||
RotateEyeAroundTarget(0.0f, fRollDelta);
|
||||
}
|
||||
|
||||
void CCamera::SetDistance(const float fdistance)
|
||||
{
|
||||
// if (IsLock())
|
||||
// return;
|
||||
|
||||
Zoom(fdistance/m_fDistance);
|
||||
}
|
||||
|
||||
void CCamera::CalculateRoll()
|
||||
{
|
||||
D3DXVECTOR2 v2ViewXY;
|
||||
v2ViewXY.x = m_v3View.x;
|
||||
v2ViewXY.y = m_v3View.y;
|
||||
D3DXVec2Normalize(&v2ViewXY, &v2ViewXY);
|
||||
const auto vv = D3DXVECTOR2(0.0f, 1.0f);
|
||||
float fDot = D3DXVec2Dot(&v2ViewXY, &vv);
|
||||
if (fDot >= 1)
|
||||
fDot = 1;
|
||||
else if (fDot <= -1)
|
||||
fDot = -1;
|
||||
fDot = acosf(fDot);
|
||||
fDot *= (180.0f / D3DX_PI);
|
||||
float fCross = D3DXVec2CCW (&v2ViewXY, &vv);
|
||||
if ( 0 > fCross)
|
||||
{
|
||||
fDot = -fDot;
|
||||
}
|
||||
|
||||
m_fRoll = fDot;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CCameraMananger
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CCameraManager::CCameraManager() :
|
||||
m_pCurrentCamera(NULL),
|
||||
m_pPreviousCamera(NULL)
|
||||
{
|
||||
AddCamera(DEFAULT_PERSPECTIVE_CAMERA);
|
||||
AddCamera(DEFAULT_ORTHO_CAMERA);
|
||||
|
||||
SetCurrentCamera(DEFAULT_PERSPECTIVE_CAMERA);
|
||||
}
|
||||
|
||||
CCameraManager::~CCameraManager()
|
||||
{
|
||||
for (TCameraMap::iterator itor = m_CameraMap.begin(); itor != m_CameraMap.end(); ++itor)
|
||||
{
|
||||
delete (*itor).second;
|
||||
}
|
||||
m_CameraMap.clear();
|
||||
}
|
||||
|
||||
CCamera * CCameraManager::GetCurrentCamera()
|
||||
{
|
||||
if (!m_pCurrentCamera)
|
||||
assert(false);
|
||||
return m_pCurrentCamera;
|
||||
}
|
||||
|
||||
void CCameraManager::SetCurrentCamera(unsigned char ucCameraNum)
|
||||
{
|
||||
if (m_pCurrentCamera != m_CameraMap[ucCameraNum])
|
||||
m_pPreviousCamera = m_pCurrentCamera;
|
||||
|
||||
m_pCurrentCamera = m_CameraMap[ucCameraNum];
|
||||
}
|
||||
|
||||
void CCameraManager::ResetToPreviousCamera()
|
||||
{
|
||||
if (!m_pPreviousCamera)
|
||||
assert(false);
|
||||
m_pCurrentCamera = m_pPreviousCamera;
|
||||
m_pPreviousCamera = NULL;
|
||||
}
|
||||
|
||||
bool CCameraManager::isCurrentCamera(unsigned char ucCameraNum)
|
||||
{
|
||||
if (m_CameraMap[ucCameraNum] == m_pCurrentCamera)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 잡스러운 함수들...
|
||||
bool CCameraManager::AddCamera(unsigned char ucCameraNum)
|
||||
{
|
||||
if(m_CameraMap.end() != m_CameraMap.find(ucCameraNum))
|
||||
return false;
|
||||
m_CameraMap.insert(TCameraMap::value_type(ucCameraNum, new CCamera));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCameraManager::RemoveCamera(unsigned char ucCameraNum)
|
||||
{
|
||||
TCameraMap::iterator itor = m_CameraMap.find(ucCameraNum);
|
||||
if(m_CameraMap.end() == itor)
|
||||
return false;
|
||||
m_CameraMap.erase(itor);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char CCameraManager::GetCurrentCameraNum()
|
||||
{
|
||||
if (!m_pCurrentCamera)
|
||||
return NO_CURRENT_CAMERA;
|
||||
for (TCameraMap::iterator itor = m_CameraMap.begin(); itor != m_CameraMap.end(); ++itor)
|
||||
if(m_pCurrentCamera == (*itor).second)
|
||||
return (*itor).first;
|
||||
return NO_CURRENT_CAMERA;
|
||||
}
|
||||
|
||||
bool CCameraManager::isTerrainCollisionEnable()
|
||||
{
|
||||
return m_pCurrentCamera->isTerrainCollisionEnable();
|
||||
}
|
||||
|
||||
void CCameraManager::SetTerrainCollision(bool bEnable)
|
||||
{
|
||||
m_pCurrentCamera->SetTerrainCollision(bEnable);
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
// Camera.h: interface for the CCamera class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_)
|
||||
#define AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../EterBase/Singleton.h"
|
||||
#include "Ray.h"
|
||||
|
||||
const float CAMERA_TARGET_STANDARD = 100.0f;
|
||||
const float CAMERA_TARGET_FACE = 150.0f;
|
||||
|
||||
|
||||
typedef enum _eCameraState_
|
||||
{
|
||||
CAMERA_STATE_NORMAL,
|
||||
CAMERA_STATE_CANTGODOWN,
|
||||
CAMERA_STATE_CANTGORIGHT,
|
||||
CAMERA_STATE_CANTGOLEFT,
|
||||
CAMERA_STATE_SCREEN_BY_BUILDING,
|
||||
CAMERA_STATE_SCREEN_BY_BUILDING_AND_TOOCLOSE,
|
||||
} eCameraState;
|
||||
|
||||
class CCamera
|
||||
{
|
||||
public:
|
||||
CCamera();
|
||||
virtual ~CCamera();
|
||||
|
||||
static void SetCameraMaxDistance(float fMax);
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool IsLock();
|
||||
|
||||
void Wheel(int nWheelLen);
|
||||
bool Drag(int nMouseX, int nMouseY, LPPOINT lpReturnPoint);
|
||||
|
||||
bool EndDrag();
|
||||
void BeginDrag(int nMouseX, int nMouseY);
|
||||
|
||||
bool IsDraging();
|
||||
|
||||
void SetResistance(float fResistance);
|
||||
|
||||
private:
|
||||
const CCamera & operator = (const CCamera &) ; // 지원하지 않음
|
||||
CCamera (const CCamera & ) ; //지원하지 않음
|
||||
|
||||
// Camera Update
|
||||
eCameraState m_eCameraState;
|
||||
eCameraState m_eCameraStatePrev;
|
||||
float m_fPitchBackup;
|
||||
float m_fRollBackup;
|
||||
float m_fDistanceBackup;
|
||||
float m_fTargetZBackUp;
|
||||
|
||||
D3DXVECTOR3 m_v3EyeBackup;
|
||||
|
||||
unsigned long m_ulNumScreenBuilding;
|
||||
|
||||
// protected:
|
||||
|
||||
bool m_isLock;
|
||||
|
||||
// Attributes for view matrix
|
||||
D3DXVECTOR3 m_v3Eye;
|
||||
D3DXVECTOR3 m_v3Target;
|
||||
D3DXVECTOR3 m_v3Up;
|
||||
|
||||
// m_v3View = m_v3Target - m_v3Eye
|
||||
D3DXVECTOR3 m_v3View;
|
||||
// m_v3Cross = Cross(m_v3Up, m_v3View)
|
||||
D3DXVECTOR3 m_v3Cross;
|
||||
|
||||
//ViewMatrixes
|
||||
D3DXMATRIX m_matView;
|
||||
D3DXMATRIX m_matInverseView;
|
||||
D3DXMATRIX m_matBillboard; // Special matrix for billboarding effects
|
||||
|
||||
//추가분
|
||||
float m_fPitch;
|
||||
float m_fRoll;
|
||||
float m_fDistance;
|
||||
|
||||
// 카메라 AI를 위한 Ray 들
|
||||
|
||||
// 카메라를 둘러싼 Ray
|
||||
CRay m_kCameraBottomToTerrainRay;
|
||||
CRay m_kCameraFrontToTerrainRay;
|
||||
CRay m_kCameraBackToTerrainRay;
|
||||
CRay m_kCameraLeftToTerrainRay;
|
||||
CRay m_kCameraRightToTerrainRay;
|
||||
|
||||
CRay m_kTargetToCameraBottomRay;
|
||||
|
||||
CRay m_ViewRay;
|
||||
CRay m_kLeftObjectCollisionRay;
|
||||
CRay m_kTopObjectCollisionRay;
|
||||
CRay m_kRightObjectCollisionRay;
|
||||
CRay m_kBottomObjectCollisionRay;
|
||||
|
||||
float m_fTerrainCollisionRadius;
|
||||
float m_fObjectCollisionRadius;
|
||||
|
||||
// protected:
|
||||
float m_fTarget_;
|
||||
|
||||
float m_fEyeGroundHeightRatio;
|
||||
float m_fTargetHeightLimitRatio;
|
||||
float m_fPitchSum;
|
||||
float m_fRollSum;
|
||||
|
||||
long m_lMousePosX;
|
||||
long m_lMousePosY;
|
||||
|
||||
bool m_bDrag;
|
||||
|
||||
// protected:
|
||||
// 물리
|
||||
D3DXVECTOR3 m_v3AngularAcceleration;
|
||||
D3DXVECTOR3 m_v3AngularVelocity;
|
||||
|
||||
float m_fResistance;
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 물리
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetAngularAcceleration(D3DXVECTOR3 v3AngularAcceleration) { m_v3AngularAcceleration = v3AngularAcceleration; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AI
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetTerrainCollisionRadius(float fTerrainCollisionRadius) { m_fTerrainCollisionRadius = fTerrainCollisionRadius; }
|
||||
void SetObjectCollisionRadius(float fObjectCollisionRadius) { m_fObjectCollisionRadius = fObjectCollisionRadius; }
|
||||
|
||||
CRay & GetViewRay() { return m_ViewRay; }
|
||||
CRay & GetLeftObjectCollisionRay() { return m_kLeftObjectCollisionRay; }
|
||||
CRay & GetRightObjectCollisionRay() { return m_kRightObjectCollisionRay; }
|
||||
CRay & GetTopObjectCollisionRay() { return m_kTopObjectCollisionRay; }
|
||||
CRay & GetBottomObjectCollisionRay() { return m_kBottomObjectCollisionRay; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Update
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Update();
|
||||
eCameraState GetCameraState() {return m_eCameraState;}
|
||||
void SetCameraState(eCameraState eNewCameraState);
|
||||
void IncreaseNumSrcreenBuilding();
|
||||
void ResetNumScreenBuilding();
|
||||
unsigned long & GetNumScreenBuilding() { return m_ulNumScreenBuilding; }
|
||||
|
||||
const float & GetPitchBackUp() { return m_fPitchBackup; }
|
||||
const float & GetRollBackUp() { return m_fRollBackup; }
|
||||
const float & GetDistanceBackUp() { return m_fDistanceBackup; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// properties
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const D3DXVECTOR3 & GetEye() const { return m_v3Eye; }
|
||||
const D3DXVECTOR3 & GetTarget() const { return m_v3Target; }
|
||||
const D3DXVECTOR3 & GetUp() const { return m_v3Up; }
|
||||
const D3DXVECTOR3 & GetView() const { return m_v3View; }
|
||||
const D3DXVECTOR3 & GetCross() const { return m_v3Cross; }
|
||||
|
||||
const D3DXMATRIX & GetViewMatrix() const { return m_matView; }
|
||||
const D3DXMATRIX & GetInverseViewMatrix() const { return m_matInverseView; }
|
||||
const D3DXMATRIX & GetBillboardMatrix()const { return m_matBillboard; }
|
||||
|
||||
void SetViewParams(const D3DXVECTOR3 & v3Eye, const D3DXVECTOR3& v3Target, const D3DXVECTOR3& v3Up );
|
||||
|
||||
void SetEye(const D3DXVECTOR3 & v3Eye);
|
||||
void SetTarget(const D3DXVECTOR3 & v3Target);
|
||||
void SetUp(const D3DXVECTOR3 & v3Up);
|
||||
|
||||
float GetPitch() const { return m_fPitch; }
|
||||
float GetRoll() const { return m_fRoll; }
|
||||
float GetDistance() const { return m_fDistance; }
|
||||
|
||||
void Pitch(const float fPitchDelta); //돌아가는 각도를 넣는다.
|
||||
void Roll(const float fRollDelta);
|
||||
void SetDistance(const float fdistance);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// camera movement
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 말그대로 이동... 카메라 위치와 타겟 위치가 모두 달라진다.
|
||||
void Move(const D3DXVECTOR3 & v3Displacement);
|
||||
// 줌.. 카메라 위치만 이동.. 타겟 위치는 고정...
|
||||
void Zoom(float fRatio);
|
||||
|
||||
// 뷰 방향으로 이동.. 타겟위치가 달라지므로 줌과는 다르다...
|
||||
void MoveAlongView(float fDistance);
|
||||
// 카메라 옆 방향으로 이동..
|
||||
void MoveAlongCross(float fDistance);
|
||||
// 카메라 업벡터 방향으로 이동...
|
||||
void MoveAlongUp(float fDistance);
|
||||
|
||||
// 카메라 옆 방향으로 이동... MoveAlongCross과 동일..
|
||||
void MoveLateral(float fDistance);
|
||||
// 뷰 방향의 Z 성분을 무시한 XY평면 방향으로 이동..
|
||||
void MoveFront(float fDistance);
|
||||
// Z방향(연직 방향)으로 이동...
|
||||
void MoveVertical(float fDistance);
|
||||
|
||||
// //카메라 위치는 고정시키고 머리만 든다. 타겟이 달라지겠죠?
|
||||
// //회전각을 라디안이 아닌 "도(Degree)"로 넣는다.
|
||||
// void RotateUpper(float fDegree);
|
||||
|
||||
// 타겟 중심으로 돈다. Eterlib의 SetAroundCamera의 기능과 유사...
|
||||
// fPitchDegree는 수평(0도)로부터 아랫쪽으로 꺽어지는 각도...
|
||||
// fRollDegree는 타겟 중심으로 시계방향으로 도는 각도...
|
||||
void RotateEyeAroundTarget(float fPitchDegree, float fRollDegree);
|
||||
|
||||
// 도는 중심점을 따로 지정 그 점을 중심으로 돈다. 타겟 점도 달라지겠죠?
|
||||
void RotateEyeAroundPoint(const D3DXVECTOR3 & v3Point, float fPitchDegree, float fRollDegree);
|
||||
|
||||
protected:
|
||||
void SetViewMatrix();
|
||||
void CalculateRoll();
|
||||
|
||||
public:
|
||||
float GetTargetHeight();
|
||||
void SetTargetHeight(float fTarget);
|
||||
bool isTerrainCollisionEnable() { return m_bProcessTerrainCollision; }
|
||||
void SetTerrainCollision(bool bEnable) { m_bProcessTerrainCollision = bEnable; }
|
||||
|
||||
private:
|
||||
void ProcessTerrainCollision();
|
||||
void ProcessBuildingCollision();
|
||||
|
||||
private:
|
||||
bool m_bProcessTerrainCollision;
|
||||
|
||||
static float CAMERA_MIN_DISTANCE;
|
||||
static float CAMERA_MAX_DISTANCE;
|
||||
};
|
||||
|
||||
typedef std::map<BYTE, CCamera *> TCameraMap;
|
||||
|
||||
class CCameraManager : public CSingleton<CCameraManager>
|
||||
{
|
||||
public:
|
||||
enum ECameraNum
|
||||
{
|
||||
NO_CURRENT_CAMERA,
|
||||
DEFAULT_PERSPECTIVE_CAMERA,
|
||||
DEFAULT_ORTHO_CAMERA,
|
||||
CAMERA_MAX = 255
|
||||
};
|
||||
|
||||
CCameraManager();
|
||||
virtual ~CCameraManager();
|
||||
|
||||
bool AddCamera(unsigned char ucCameraNum);
|
||||
bool RemoveCamera(unsigned char ucCameraNum);
|
||||
|
||||
CCamera * GetCurrentCamera();
|
||||
void SetCurrentCamera(unsigned char ucCameraNum);
|
||||
void ResetToPreviousCamera();
|
||||
|
||||
bool isCurrentCamera(unsigned char ucCameraNum);
|
||||
|
||||
unsigned char GetCurrentCameraNum();
|
||||
|
||||
bool isTerrainCollisionEnable();
|
||||
void SetTerrainCollision(bool bEnable);
|
||||
|
||||
private:
|
||||
TCameraMap m_CameraMap;
|
||||
CCamera * m_pCurrentCamera;
|
||||
CCamera * m_pPreviousCamera;
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_)
|
||||
@@ -0,0 +1,840 @@
|
||||
#include "StdAfx.h"
|
||||
#include "CollisionData.h"
|
||||
#include "Pool.h"
|
||||
#include "GrpScreen.h"
|
||||
#include "GrpMath.h"
|
||||
#include "lineintersect_utils.h"
|
||||
#include "StateManager.h"
|
||||
const float gc_fReduceMove = 0.5f;
|
||||
|
||||
//const float gc_fSlideMoveSpeed = 5.0f;
|
||||
/*inline D3DXVECTOR3 FitAtSpecifiedLength(const D3DXVECTOR3 & v3Vector, float length)
|
||||
{
|
||||
D3DXVECTOR3 v;
|
||||
D3DXVec3Normalize(&v,&v3Vector);
|
||||
return v*length;
|
||||
}
|
||||
*/
|
||||
CDynamicPool<CSphereCollisionInstance> gs_sci;
|
||||
CDynamicPool<CCylinderCollisionInstance> gs_cci;
|
||||
CDynamicPool<CPlaneCollisionInstance> gs_pci;
|
||||
CDynamicPool<CAABBCollisionInstance> gs_aci;
|
||||
CDynamicPool<COBBCollisionInstance> gs_oci;
|
||||
|
||||
void DestroyCollisionInstanceSystem()
|
||||
{
|
||||
gs_sci.Destroy();
|
||||
gs_cci.Destroy();
|
||||
gs_pci.Destroy();
|
||||
gs_aci.Destroy();
|
||||
gs_oci.Destroy();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Base
|
||||
CBaseCollisionInstance * CBaseCollisionInstance::BuildCollisionInstance(const CStaticCollisionData * c_pCollisionData, const D3DXMATRIX * pMat)
|
||||
{
|
||||
switch(c_pCollisionData->dwType)
|
||||
{
|
||||
case COLLISION_TYPE_PLANE:
|
||||
{
|
||||
CPlaneCollisionInstance * ppci = gs_pci.Alloc();
|
||||
D3DXMATRIX matRotation;
|
||||
D3DXMATRIX matTranslationLocal;
|
||||
D3DXMatrixRotationQuaternion(&matRotation, &c_pCollisionData->quatRotation);
|
||||
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
|
||||
D3DXMATRIX matTransform = matRotation * matTranslationLocal * *pMat;
|
||||
|
||||
TPlaneData & PlaneData = ppci->GetAttribute();
|
||||
D3DXVec3TransformCoord(&PlaneData.v3Position, &c_pCollisionData->v3Position, pMat);
|
||||
float fHalfWidth = c_pCollisionData->fDimensions[0] / 2.0f;
|
||||
float fHalfLength = c_pCollisionData->fDimensions[1] / 2.0f;
|
||||
|
||||
PlaneData.v3QuadPosition[0].x = -fHalfWidth;
|
||||
PlaneData.v3QuadPosition[0].y = -fHalfLength;
|
||||
PlaneData.v3QuadPosition[0].z = 0.0f;
|
||||
PlaneData.v3QuadPosition[1].x = +fHalfWidth;
|
||||
PlaneData.v3QuadPosition[1].y = -fHalfLength;
|
||||
PlaneData.v3QuadPosition[1].z = 0.0f;
|
||||
PlaneData.v3QuadPosition[2].x = -fHalfWidth;
|
||||
PlaneData.v3QuadPosition[2].y = +fHalfLength;
|
||||
PlaneData.v3QuadPosition[2].z = 0.0f;
|
||||
PlaneData.v3QuadPosition[3].x = +fHalfWidth;
|
||||
PlaneData.v3QuadPosition[3].y = +fHalfLength;
|
||||
PlaneData.v3QuadPosition[3].z = 0.0f;
|
||||
for (DWORD i = 0; i < 4; ++i)
|
||||
D3DXVec3TransformCoord(&PlaneData.v3QuadPosition[i], &PlaneData.v3QuadPosition[i], &matTransform);
|
||||
D3DXVECTOR3 v3Line0 = PlaneData.v3QuadPosition[1] - PlaneData.v3QuadPosition[0];
|
||||
D3DXVECTOR3 v3Line1 = PlaneData.v3QuadPosition[2] - PlaneData.v3QuadPosition[0];
|
||||
D3DXVECTOR3 v3Line2 = PlaneData.v3QuadPosition[1] - PlaneData.v3QuadPosition[3];
|
||||
D3DXVECTOR3 v3Line3 = PlaneData.v3QuadPosition[2] - PlaneData.v3QuadPosition[3];
|
||||
D3DXVec3Normalize(&v3Line0, &v3Line0);
|
||||
D3DXVec3Normalize(&v3Line1, &v3Line1);
|
||||
D3DXVec3Normalize(&v3Line2, &v3Line2);
|
||||
D3DXVec3Normalize(&v3Line3, &v3Line3);
|
||||
D3DXVec3Cross(&PlaneData.v3Normal, &v3Line0, &v3Line1);
|
||||
D3DXVec3Normalize(&PlaneData.v3Normal, &PlaneData.v3Normal);
|
||||
|
||||
D3DXVec3Cross(&PlaneData.v3InsideVector[0], &PlaneData.v3Normal, &v3Line0 );
|
||||
D3DXVec3Cross(&PlaneData.v3InsideVector[1], &v3Line1, &PlaneData.v3Normal);
|
||||
D3DXVec3Cross(&PlaneData.v3InsideVector[2], &v3Line2, &PlaneData.v3Normal);
|
||||
D3DXVec3Cross(&PlaneData.v3InsideVector[3], &PlaneData.v3Normal, &v3Line3);
|
||||
|
||||
return ppci;
|
||||
}
|
||||
break;
|
||||
case COLLISION_TYPE_BOX:
|
||||
assert(false && "COLLISION_TYPE_BOX not implemented");
|
||||
break;
|
||||
case COLLISION_TYPE_AABB:
|
||||
{
|
||||
CAABBCollisionInstance * paci = gs_aci.Alloc();
|
||||
|
||||
D3DXMATRIX matTranslationLocal;
|
||||
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
|
||||
D3DXMATRIX matTransform = *pMat;
|
||||
|
||||
D3DXVECTOR3 v3Pos;
|
||||
v3Pos.x = matTranslationLocal._41;
|
||||
v3Pos.y = matTranslationLocal._42;
|
||||
v3Pos.z = matTranslationLocal._43;
|
||||
|
||||
TAABBData & AABBData = paci->GetAttribute();
|
||||
AABBData.v3Min.x = v3Pos.x - c_pCollisionData->fDimensions[0];
|
||||
AABBData.v3Min.y = v3Pos.y - c_pCollisionData->fDimensions[1];
|
||||
AABBData.v3Min.z = v3Pos.z - c_pCollisionData->fDimensions[2];
|
||||
AABBData.v3Max.x = v3Pos.x + c_pCollisionData->fDimensions[0];
|
||||
AABBData.v3Max.y = v3Pos.y + c_pCollisionData->fDimensions[1];
|
||||
AABBData.v3Max.z = v3Pos.z + c_pCollisionData->fDimensions[2];
|
||||
|
||||
D3DXVec3TransformCoord(&AABBData.v3Min, &AABBData.v3Min, &matTransform);
|
||||
D3DXVec3TransformCoord(&AABBData.v3Max, &AABBData.v3Max, &matTransform);
|
||||
|
||||
return paci;
|
||||
}
|
||||
break;
|
||||
case COLLISION_TYPE_OBB:
|
||||
{
|
||||
COBBCollisionInstance * poci = gs_oci.Alloc();
|
||||
|
||||
D3DXMATRIX matTranslationLocal; D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
|
||||
D3DXMATRIX matRotation; D3DXMatrixRotationQuaternion(&matRotation, &c_pCollisionData->quatRotation);
|
||||
|
||||
D3DXMATRIX matTranslationWorld; D3DXMatrixIdentity(&matTranslationWorld);
|
||||
matTranslationWorld._41 = pMat->_41; matTranslationWorld._42 = pMat->_42; matTranslationWorld._43 = pMat->_43; matTranslationWorld._44 = pMat->_44;
|
||||
|
||||
D3DXVECTOR3 v3Min, v3Max;
|
||||
v3Min.x = c_pCollisionData->v3Position.x - c_pCollisionData->fDimensions[0];
|
||||
v3Min.y = c_pCollisionData->v3Position.y - c_pCollisionData->fDimensions[1];
|
||||
v3Min.z = c_pCollisionData->v3Position.z - c_pCollisionData->fDimensions[2];
|
||||
v3Max.x = c_pCollisionData->v3Position.x + c_pCollisionData->fDimensions[0];
|
||||
v3Max.y = c_pCollisionData->v3Position.y + c_pCollisionData->fDimensions[1];
|
||||
v3Max.z = c_pCollisionData->v3Position.z + c_pCollisionData->fDimensions[2];
|
||||
|
||||
D3DXVec3TransformCoord(&v3Min, &v3Min, pMat);
|
||||
D3DXVec3TransformCoord(&v3Max, &v3Max, pMat);
|
||||
D3DXVECTOR3 v3Position = (v3Min + v3Max) * 0.5f;
|
||||
|
||||
TOBBData & OBBData = poci->GetAttribute();
|
||||
OBBData.v3Min.x = v3Position.x - c_pCollisionData->fDimensions[0];
|
||||
OBBData.v3Min.y = v3Position.y - c_pCollisionData->fDimensions[1];
|
||||
OBBData.v3Min.z = v3Position.z - c_pCollisionData->fDimensions[2];
|
||||
OBBData.v3Max.x = v3Position.x + c_pCollisionData->fDimensions[0];
|
||||
OBBData.v3Max.y = v3Position.y + c_pCollisionData->fDimensions[1];
|
||||
OBBData.v3Max.z = v3Position.z + c_pCollisionData->fDimensions[2];
|
||||
|
||||
|
||||
|
||||
D3DXMATRIX matTransform = *pMat;
|
||||
|
||||
D3DXMatrixIdentity(&OBBData.matRot); OBBData.matRot = *pMat;
|
||||
OBBData.matRot._41 = 0; OBBData.matRot._42 = 0; OBBData.matRot._43 = 0; OBBData.matRot._44 = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
return poci;
|
||||
}
|
||||
break;
|
||||
case COLLISION_TYPE_SPHERE:
|
||||
{
|
||||
CSphereCollisionInstance * psci = gs_sci.Alloc();
|
||||
|
||||
D3DXMATRIX matTranslationLocal;
|
||||
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
|
||||
matTranslationLocal = matTranslationLocal * *pMat;
|
||||
|
||||
TSphereData & SphereData = psci->GetAttribute();
|
||||
SphereData.v3Position.x = matTranslationLocal._41;
|
||||
SphereData.v3Position.y = matTranslationLocal._42;
|
||||
SphereData.v3Position.z = matTranslationLocal._43;
|
||||
SphereData.fRadius = c_pCollisionData->fDimensions[0];
|
||||
|
||||
return psci;
|
||||
}
|
||||
break;
|
||||
case COLLISION_TYPE_CYLINDER:
|
||||
{
|
||||
CCylinderCollisionInstance * pcci = gs_cci.Alloc();
|
||||
|
||||
D3DXMATRIX matTranslationLocal;
|
||||
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
|
||||
matTranslationLocal = matTranslationLocal * *pMat;
|
||||
|
||||
TCylinderData & CylinderData = pcci->GetAttribute();
|
||||
CylinderData.fRadius = c_pCollisionData->fDimensions[0];
|
||||
CylinderData.fHeight = c_pCollisionData->fDimensions[1];
|
||||
CylinderData.v3Position.x = matTranslationLocal._41;
|
||||
CylinderData.v3Position.y = matTranslationLocal._42;
|
||||
CylinderData.v3Position.z = matTranslationLocal._43 /*+ CylinderData.fHeight/2.0f*/;
|
||||
|
||||
return pcci;
|
||||
}
|
||||
break;
|
||||
}
|
||||
assert(false && "NOT_REACHED");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CBaseCollisionInstance::Destroy()
|
||||
{
|
||||
OnDestroy();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*------------------------------------------------------Sphere---------------------------------------------------------------*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
TSphereData & CSphereCollisionInstance::GetAttribute()
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
const TSphereData & CSphereCollisionInstance::GetAttribute() const
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
void CSphereCollisionInstance::Render(D3DFILLMODE d3dFillMode)
|
||||
{
|
||||
static CScreen s;
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
|
||||
s.RenderSphere(NULL, m_attribute.v3Position.x, m_attribute.v3Position.y, m_attribute.v3Position.z, m_attribute.fRadius, d3dFillMode);
|
||||
}
|
||||
|
||||
void CSphereCollisionInstance::OnDestroy()
|
||||
{
|
||||
gs_sci.Free(this);
|
||||
}
|
||||
|
||||
bool CSphereCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
if (square_distance_between_linesegment_and_point(s.v3LastPosition,s.v3Position,m_attribute.v3Position) < (m_attribute.fRadius+s.fRadius)*(m_attribute.fRadius+s.fRadius))
|
||||
{
|
||||
// NOTE : 거리가 가까워 졌을때만.. - [levites]
|
||||
if (GetVector3Distance(s.v3Position, m_attribute.v3Position) <
|
||||
GetVector3Distance(s.v3LastPosition, m_attribute.v3Position))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSphereCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
//Tracef("OnCollisionDynamicSphere\n");
|
||||
|
||||
if (square_distance_between_linesegment_and_point(s.v3LastPosition,s.v3Position,m_attribute.v3Position)<(m_attribute.fRadius+s.fRadius)*(m_attribute.fRadius+s.fRadius))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 CSphereCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
const auto _vv__ = (s.v3Position - m_attribute.v3Position);
|
||||
if (D3DXVec3LengthSq(&_vv__)>=(s.fRadius+m_attribute.fRadius)*(m_attribute.fRadius+s.fRadius))
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
D3DXVECTOR3 c;
|
||||
const auto _vv__2 = (s.v3Position - s.v3LastPosition);
|
||||
const auto _vv_s_2 = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
D3DXVec3Cross(&c, &_vv__2, &_vv_s_2);
|
||||
|
||||
float sum = - D3DXVec3Dot(&c,&_vv__);
|
||||
float mul = (s.fRadius+m_attribute.fRadius)*(s.fRadius+m_attribute.fRadius)-D3DXVec3LengthSq(&_vv__);
|
||||
|
||||
if (sum*sum-4*mul<=0)
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
float sq = sqrt(sum*sum-4*mul);
|
||||
float t1=-sum-sq, t2=-sum+sq;
|
||||
t1*=0.5f;
|
||||
t2*=0.5f;
|
||||
|
||||
if (fabs(t1)<=fabs(t2))
|
||||
{
|
||||
return (gc_fReduceMove*t1)*c;
|
||||
}
|
||||
else
|
||||
return (gc_fReduceMove*t2)*c;
|
||||
|
||||
/*
|
||||
D3DXVECTOR3 p1 = s.v3Position+t1*c;
|
||||
D3DXVECTOR3 p2 = s.v3Position+t2*c;
|
||||
|
||||
if (D3DXVec3LengthSq(&(p2-s.v3Position))>D3DXVec3LengthSq(&(p1-s.v3Position)))
|
||||
{
|
||||
return p1-s.v3Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
return p2-s.v3Position;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Plane
|
||||
TPlaneData & CPlaneCollisionInstance::GetAttribute()
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
const TPlaneData & CPlaneCollisionInstance::GetAttribute() const
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
bool CPlaneCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
D3DXVECTOR3 v3SpherePosition = s.v3Position - m_attribute.v3Position;
|
||||
D3DXVECTOR3 v3SphereLastPosition = s.v3LastPosition - m_attribute.v3Position;
|
||||
|
||||
float fPosition1 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SpherePosition);
|
||||
float fPosition2 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SphereLastPosition);
|
||||
|
||||
if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f
|
||||
|| (fPosition1) <= s.fRadius && fPosition1 >= -s.fRadius)
|
||||
{
|
||||
D3DXVECTOR3 v3QuadPosition1 = s.v3Position - m_attribute.v3QuadPosition[0];
|
||||
D3DXVECTOR3 v3QuadPosition2 = s.v3Position - m_attribute.v3QuadPosition[3];
|
||||
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[0]) > - s.fRadius/*0.0f*/)
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[1]) > -s.fRadius/*0.0f*/)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[2]) > - s.fRadius/*0.0f*/)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[3]) > - s.fRadius/*0.0f*/)
|
||||
{
|
||||
// NOTE : 거리가 가까워 졌을때만.. - [levites]
|
||||
const auto _vv__3 = (s.v3Position - m_attribute.v3Position);
|
||||
const auto _vv__4 = (s.v3LastPosition - m_attribute.v3Position);
|
||||
if (fabs(D3DXVec3Dot(&_vv__3, &m_attribute.v3Normal)) <
|
||||
fabs(D3DXVec3Dot(&_vv__4, &m_attribute.v3Normal)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CPlaneCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
//Tracef("OnCollisionDynamicSphere\n");
|
||||
|
||||
D3DXVECTOR3 v3SpherePosition = s.v3Position - m_attribute.v3Position;
|
||||
D3DXVECTOR3 v3SphereLastPosition = s.v3LastPosition - m_attribute.v3Position;
|
||||
|
||||
float fPosition1 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SpherePosition);
|
||||
float fPosition2 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SphereLastPosition);
|
||||
|
||||
if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f
|
||||
|| (fPosition1) <= s.fRadius && fPosition1 >= -s.fRadius)
|
||||
{
|
||||
D3DXVECTOR3 v3QuadPosition1 = s.v3Position - m_attribute.v3QuadPosition[0];
|
||||
D3DXVECTOR3 v3QuadPosition2 = s.v3Position - m_attribute.v3QuadPosition[3];
|
||||
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[0]) > - s.fRadius/*0.0f*/)
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[1]) > -s.fRadius/*0.0f*/)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[2]) > - s.fRadius/*0.0f*/)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[3]) > - s.fRadius/*0.0f*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 CPlaneCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
D3DXVECTOR3 advance = s.v3Position-s.v3LastPosition;
|
||||
|
||||
float d = D3DXVec3Dot(&m_attribute.v3Normal, &advance);
|
||||
if (d>=-0.0001 && d<=0.0001)
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
const auto vv = (s.v3Position - m_attribute.v3Position);
|
||||
float t= - D3DXVec3Dot(&m_attribute.v3Normal, &vv)/d;
|
||||
|
||||
//D3DXVECTOR3 onplane = s.v3Position+t*advance;
|
||||
|
||||
if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
|
||||
{
|
||||
//return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
|
||||
return t*advance -s.fRadius*m_attribute.v3Normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
//return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
|
||||
return t*advance +s.fRadius*m_attribute.v3Normal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
|
||||
{
|
||||
Tracef("%f %f\n",s.fRadius,-(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position))));
|
||||
return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracef("%f %f\n",(s.fRadius),(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position))));
|
||||
return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
|
||||
}*/
|
||||
|
||||
|
||||
/*
|
||||
D3DXVECTOR3 advance = s.v3Position-s.v3LastPosition;
|
||||
D3DXVECTOR3 slide(-advance.y,advance.x,advance.z);
|
||||
slide = m_attribute.v3Normal;
|
||||
|
||||
D3DXVECTOR3 radius_adjust = advance;
|
||||
D3DXVec3Normalize(&radius_adjust,&radius_adjust);
|
||||
radius_adjust*=s.fRadius;
|
||||
|
||||
float d = D3DXVec3Dot(&m_attribute.v3Normal, &slide);
|
||||
if (d>=-0.0001 && d<=0.0001)
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
|
||||
float t= - D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position+radius_adjust-m_attribute.v3Position))
|
||||
/ d;*/
|
||||
|
||||
//D3DXVECTOR3 nextposition;
|
||||
//nextposition = s.v3Position + t*slide;
|
||||
//Tracef("$T %f",t);
|
||||
//if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
|
||||
// return (t*slide - m_attribute.v3Normal * s.fRadius)/**gc_fReduceMove*/;
|
||||
//else
|
||||
// return (t*slide + m_attribute.v3Normal * s.fRadius)/*gc_fReduceMove*/;
|
||||
//if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
|
||||
// return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/** s.fRadius*/)*gc_fReduceMove;
|
||||
//else
|
||||
// return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/*s.fRadius*/)*gc_fReduceMove;
|
||||
//
|
||||
}
|
||||
|
||||
void CPlaneCollisionInstance::Render(D3DFILLMODE /*d3dFillMode*/)
|
||||
{
|
||||
static CScreen s;
|
||||
s.RenderBar3d(m_attribute.v3QuadPosition);
|
||||
}
|
||||
|
||||
void CPlaneCollisionInstance::OnDestroy()
|
||||
{
|
||||
gs_pci.Free(this);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Cylinder
|
||||
TCylinderData & CCylinderCollisionInstance::GetAttribute()
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
const TCylinderData & CCylinderCollisionInstance::GetAttribute() const
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
bool CCylinderCollisionInstance::CollideCylinderVSDynamicSphere(const TCylinderData & c_rattribute, const CDynamicSphereInstance & s) const
|
||||
{
|
||||
if (s.v3Position.z + s.fRadius < c_rattribute.v3Position.z)
|
||||
return false;
|
||||
|
||||
if (s.v3Position.z - s.fRadius > c_rattribute.v3Position.z + c_rattribute.fHeight)
|
||||
return false;
|
||||
|
||||
/*D3DXVECTOR2 v2curDistance(s.v3Position.x - c_rattribute.v3Position.x, s.v3Position.y - c_rattribute.v3Position.y);
|
||||
float fDistance = D3DXVec2Length(&v2curDistance);
|
||||
if (fDistance <= s.fRadius + c_rattribute.fRadius)
|
||||
return true;
|
||||
*/
|
||||
|
||||
D3DXVECTOR3 oa, ob;
|
||||
IntersectLineSegments(c_rattribute.v3Position, D3DXVECTOR3(c_rattribute.v3Position.x,c_rattribute.v3Position.y,c_rattribute.v3Position.z+c_rattribute.fHeight), s.v3LastPosition, s.v3Position, oa, ob);
|
||||
const auto vv = (oa - ob);
|
||||
return (D3DXVec3LengthSq(&vv)<=(c_rattribute.fRadius+s.fRadius)*(c_rattribute.fRadius+s.fRadius));
|
||||
}
|
||||
|
||||
bool CCylinderCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
if (CollideCylinderVSDynamicSphere(m_attribute, s))
|
||||
{
|
||||
// NOTE : 거리가 가까워 졌을때만.. - [levites]
|
||||
if (GetVector3Distance(s.v3Position, m_attribute.v3Position) <
|
||||
GetVector3Distance(s.v3LastPosition, m_attribute.v3Position))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// NOTE : 이동 거리가 클 경우 빈틈없이 (원 크기 단위로) 이동하면서 전부 체크 해 본다 - [levites]
|
||||
D3DXVECTOR3 v3Distance = s.v3Position - s.v3LastPosition;
|
||||
float fDistance = D3DXVec3Length(&v3Distance);
|
||||
if (s.fRadius<=0.0001f)
|
||||
return false;
|
||||
if (fDistance >= s.fRadius*2.0f)
|
||||
{
|
||||
TCylinderData cylinder;
|
||||
cylinder = m_attribute;
|
||||
cylinder.v3Position = s.v3LastPosition;
|
||||
|
||||
int iStep = fDistance / s.fRadius*2.0f;
|
||||
D3DXVECTOR3 v3Step = v3Distance / float(iStep);
|
||||
|
||||
for (int i = 0; i < iStep; ++i)
|
||||
{
|
||||
cylinder.v3Position += v3Step;
|
||||
if (CollideCylinderVSDynamicSphere(cylinder, s))
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCylinderCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
//Tracef("OnCollisionDynamicSphere\n");
|
||||
|
||||
return (CollideCylinderVSDynamicSphere(m_attribute, s));
|
||||
}
|
||||
|
||||
D3DXVECTOR3 CCylinderCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
D3DXVECTOR3 v3Position = m_attribute.v3Position;
|
||||
v3Position.z = s.v3Position.z;
|
||||
const auto vv = (s.v3Position - v3Position);
|
||||
if (D3DXVec3LengthSq(&vv)>=(s.fRadius+m_attribute.fRadius)*(m_attribute.fRadius+s.fRadius))
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
D3DXVECTOR3 c;
|
||||
D3DXVECTOR3 advance = s.v3Position - s.v3LastPosition;
|
||||
advance.z = 0;
|
||||
const auto vssa = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
D3DXVec3Cross(&c, &advance, &vssa);
|
||||
|
||||
const auto svsvs = (s.v3Position - v3Position);
|
||||
float sum = - D3DXVec3Dot(&c,&svsvs);
|
||||
float mul = (s.fRadius+m_attribute.fRadius)*(s.fRadius+m_attribute.fRadius)-D3DXVec3LengthSq(&svsvs);
|
||||
|
||||
if (sum*sum-4*mul<=0)
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
float sq = sqrt(sum*sum-4*mul);
|
||||
float t1=-sum-sq, t2=-sum+sq;
|
||||
t1*=0.5f;
|
||||
t2*=0.5f;
|
||||
|
||||
|
||||
if (fabs(t1)<=fabs(t2))
|
||||
{
|
||||
return (gc_fReduceMove*t1)*c;
|
||||
}
|
||||
else
|
||||
return (gc_fReduceMove*t2)*c;
|
||||
|
||||
/*D3DXVECTOR3 p1 = s.v3Position+t1*c;
|
||||
D3DXVECTOR3 p2 = s.v3Position+t2*c;
|
||||
|
||||
if (D3DXVec3LengthSq(&(p2-s.v3Position))>D3DXVec3LengthSq(&(p1-s.v3Position)))
|
||||
{
|
||||
return p1-s.v3Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
return p2-s.v3Position;
|
||||
}*/
|
||||
}
|
||||
|
||||
void CCylinderCollisionInstance::Render(D3DFILLMODE d3dFillMode)
|
||||
{
|
||||
static CScreen s;
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
|
||||
s.RenderCylinder(NULL, m_attribute.v3Position.x, m_attribute.v3Position.y, m_attribute.v3Position.z+m_attribute.fHeight/2, m_attribute.fRadius, m_attribute.fHeight, d3dFillMode);
|
||||
}
|
||||
|
||||
void CCylinderCollisionInstance::OnDestroy()
|
||||
{
|
||||
gs_cci.Free(this);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// AABB (Aligned Axis Bounding Box)
|
||||
TAABBData & CAABBCollisionInstance::GetAttribute()
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
const TAABBData & CAABBCollisionInstance::GetAttribute() const
|
||||
{
|
||||
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
bool CAABBCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
D3DXVECTOR3 v;
|
||||
D3DXVECTOR3 v3center = (m_attribute.v3Min + m_attribute.v3Max) * 0.5f;
|
||||
|
||||
memcpy(&v, &s.v3Position, sizeof(D3DXVECTOR3));
|
||||
|
||||
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
|
||||
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
|
||||
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
|
||||
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
|
||||
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
|
||||
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
|
||||
|
||||
if(GetVector3Distance(v, s.v3Position) <= s.fRadius * s.fRadius)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
memcpy(&v, &s.v3LastPosition, sizeof(D3DXVECTOR3));
|
||||
|
||||
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
|
||||
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
|
||||
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
|
||||
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
|
||||
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
|
||||
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
|
||||
|
||||
if(GetVector3Distance(v, s.v3LastPosition) <= s.fRadius * s.fRadius)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CAABBCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
D3DXVECTOR3 v;
|
||||
memcpy(&v, &s.v3Position, sizeof(D3DXVECTOR3));
|
||||
|
||||
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
|
||||
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
|
||||
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
|
||||
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
|
||||
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
|
||||
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
|
||||
|
||||
if(v.x > m_attribute.v3Min.x && v.x < m_attribute.v3Max.x &&
|
||||
v.y > m_attribute.v3Min.y && v.y < m_attribute.v3Max.y &&
|
||||
v.z > m_attribute.v3Min.z && v.z < m_attribute.v3Max.z) { return true; }
|
||||
|
||||
if(GetVector3Distance(v, s.v3Position) <= s.fRadius * s.fRadius) { return true; }
|
||||
|
||||
|
||||
memcpy(&v, &s.v3LastPosition, sizeof(D3DXVECTOR3));
|
||||
|
||||
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
|
||||
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
|
||||
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
|
||||
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
|
||||
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
|
||||
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
|
||||
|
||||
|
||||
|
||||
if(v.x > m_attribute.v3Min.x && v.x < m_attribute.v3Max.x &&
|
||||
v.y > m_attribute.v3Min.y && v.y < m_attribute.v3Max.y &&
|
||||
v.z > m_attribute.v3Min.z && v.z < m_attribute.v3Max.z) { return true; }
|
||||
|
||||
if(GetVector3Distance(v, s.v3LastPosition) <= s.fRadius * s.fRadius) { return true; }
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 CAABBCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
|
||||
//Tracef("OnGetCollisionMovementAdjust v3Min.x = %f, v3Max.x = %f\n", m_attribute.v3Min.x, m_attribute.v3Max.x);
|
||||
/*
|
||||
float fARadius = D3DXVec3Length(&(m_attribute.v3Min - m_attribute.v3Max));
|
||||
if (D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)))>=(s.fRadius+fARadius)*(fARadius+s.fRadius))
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
D3DXVECTOR3 c;
|
||||
D3DXVec3Cross(&c, &(s.v3Position-s.v3LastPosition), &D3DXVECTOR3(0.0f,0.0f,1.0f) );
|
||||
|
||||
float sum = - D3DXVec3Dot(&c,&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)));
|
||||
float mul = (s.fRadius+fARadius)*(s.fRadius+fARadius)-D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)));
|
||||
|
||||
if (sum*sum-4*mul<=0)
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
float sq = sqrt(sum*sum-4*mul);
|
||||
float t1=-sum-sq, t2=-sum+sq;
|
||||
t1*=0.5f;
|
||||
t2*=0.5f;
|
||||
|
||||
if (fabs(t1)<=fabs(t2))
|
||||
{
|
||||
return (gc_fReduceMove*t1)*c;
|
||||
}
|
||||
else
|
||||
return (gc_fReduceMove*t2)*c;
|
||||
*/
|
||||
|
||||
D3DXVECTOR3 v3Temp;
|
||||
if(s.v3Position.x + s.fRadius <= m_attribute.v3Min.x) { v3Temp.x = m_attribute.v3Min.x; }
|
||||
else if(s.v3Position.x - s.fRadius >= m_attribute.v3Max.x) { v3Temp.x = m_attribute.v3Max.x; }
|
||||
else if(s.v3Position.x + s.fRadius >= m_attribute.v3Min.x && s.v3Position.x + s.fRadius <= m_attribute.v3Max.x) { v3Temp.x = s.v3Position.x + s.fRadius; }
|
||||
else { v3Temp.x = s.v3Position.x - s.fRadius; }
|
||||
|
||||
if(s.v3Position.y + s.fRadius <= m_attribute.v3Min.y) { v3Temp.y = m_attribute.v3Min.y; }
|
||||
else if(s.v3Position.y - s.fRadius >= m_attribute.v3Max.y) { v3Temp.y = m_attribute.v3Max.y; }
|
||||
else if(s.v3Position.y + s.fRadius >= m_attribute.v3Min.y && s.v3Position.y + s.fRadius <= m_attribute.v3Max.y) { v3Temp.y = s.v3Position.y + s.fRadius; }
|
||||
else { v3Temp.y = s.v3Position.y - s.fRadius; }
|
||||
|
||||
if(s.v3Position.z + s.fRadius <= m_attribute.v3Min.z) { v3Temp.z = m_attribute.v3Min.z; }
|
||||
else if(s.v3Position.z - s.fRadius >= m_attribute.v3Max.z) { v3Temp.z = m_attribute.v3Max.z; }
|
||||
else if(s.v3Position.z + s.fRadius >= m_attribute.v3Min.z && s.v3Position.z + s.fRadius <= m_attribute.v3Max.z) { v3Temp.z = s.v3Position.z + s.fRadius; }
|
||||
else { v3Temp.z = s.v3Position.z - s.fRadius; }
|
||||
|
||||
|
||||
const auto vv = (v3Temp - s.v3Position);
|
||||
if(D3DXVec3LengthSq(&vv) < s.fRadius * s.fRadius)
|
||||
return D3DXVECTOR3(.0f, .0f, .0f);
|
||||
|
||||
return D3DXVECTOR3(.0f, .0f, .0f);
|
||||
|
||||
}
|
||||
|
||||
void CAABBCollisionInstance::Render(D3DFILLMODE d3dFillMode)
|
||||
{
|
||||
static CScreen s;
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
|
||||
s.RenderCube(m_attribute.v3Min.x, m_attribute.v3Min.y, m_attribute.v3Min.z, m_attribute.v3Max.x, m_attribute.v3Max.y, m_attribute.v3Max.z);
|
||||
return;
|
||||
}
|
||||
|
||||
void CAABBCollisionInstance::OnDestroy()
|
||||
{
|
||||
gs_aci.Free(this);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// OBB
|
||||
|
||||
TOBBData & COBBCollisionInstance::GetAttribute()
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
const TOBBData & COBBCollisionInstance::GetAttribute() const
|
||||
{
|
||||
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
bool COBBCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
D3DXVECTOR3 v3Center = 0.5f * (m_attribute.v3Min + m_attribute.v3Max);
|
||||
D3DXVECTOR3 v3Sphere = s.v3Position - v3Center;
|
||||
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
|
||||
v3Sphere = v3Sphere + v3Center;
|
||||
|
||||
D3DXVECTOR3 v3Point = v3Sphere;
|
||||
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
|
||||
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
|
||||
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
|
||||
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
|
||||
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
|
||||
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
|
||||
|
||||
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
|
||||
|
||||
v3Sphere = s.v3LastPosition - v3Center;
|
||||
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
|
||||
v3Sphere = v3Sphere + v3Center;
|
||||
|
||||
v3Point = v3Sphere;
|
||||
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
|
||||
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
|
||||
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
|
||||
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
|
||||
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
|
||||
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
|
||||
|
||||
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COBBCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
|
||||
D3DXVECTOR3 v3Center = 0.5f * (m_attribute.v3Min + m_attribute.v3Max);
|
||||
D3DXVECTOR3 v3Sphere = s.v3Position - v3Center;
|
||||
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
|
||||
v3Sphere = v3Sphere + v3Center;
|
||||
|
||||
D3DXVECTOR3 v3Point = v3Sphere;
|
||||
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
|
||||
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
|
||||
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
|
||||
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
|
||||
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
|
||||
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
|
||||
|
||||
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
|
||||
|
||||
v3Sphere = s.v3LastPosition - v3Center;
|
||||
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
|
||||
v3Sphere = v3Sphere + v3Center;
|
||||
|
||||
v3Point = v3Sphere;
|
||||
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
|
||||
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
|
||||
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
|
||||
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
|
||||
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
|
||||
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
|
||||
|
||||
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 COBBCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
|
||||
return D3DXVECTOR3(.0f, .0f, .0f);
|
||||
|
||||
}
|
||||
|
||||
void COBBCollisionInstance::Render(D3DFILLMODE d3dFillMode)
|
||||
{
|
||||
static CScreen s;
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
|
||||
s.RenderCube(m_attribute.v3Min.x, m_attribute.v3Min.y, m_attribute.v3Min.z, m_attribute.v3Max.x, m_attribute.v3Max.y, m_attribute.v3Max.z, m_attribute.matRot);
|
||||
return;
|
||||
}
|
||||
|
||||
void COBBCollisionInstance::OnDestroy()
|
||||
{
|
||||
gs_oci.Free(this);
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
#pragma once
|
||||
|
||||
// Collision Detection
|
||||
typedef struct SSphereData
|
||||
{
|
||||
D3DXVECTOR3 v3Position;
|
||||
float fRadius;
|
||||
} TSphereData;
|
||||
|
||||
typedef struct SPlaneData
|
||||
{
|
||||
D3DXVECTOR3 v3Position;
|
||||
D3DXVECTOR3 v3Normal;
|
||||
|
||||
D3DXVECTOR3 v3QuadPosition[4];
|
||||
D3DXVECTOR3 v3InsideVector[4];
|
||||
} TPlaneData;
|
||||
|
||||
typedef struct SAABBData
|
||||
{
|
||||
D3DXVECTOR3 v3Min;
|
||||
D3DXVECTOR3 v3Max;
|
||||
|
||||
} TAABBData;
|
||||
|
||||
typedef struct SOBBData
|
||||
{
|
||||
D3DXVECTOR3 v3Min;
|
||||
D3DXVECTOR3 v3Max;
|
||||
D3DXMATRIX matRot;
|
||||
|
||||
} TOBBData;
|
||||
|
||||
typedef struct SCylinderData
|
||||
{
|
||||
D3DXVECTOR3 v3Position;
|
||||
float fRadius;
|
||||
float fHeight;
|
||||
} TCylinderData;
|
||||
|
||||
enum ECollisionType
|
||||
{
|
||||
COLLISION_TYPE_PLANE,
|
||||
COLLISION_TYPE_BOX,
|
||||
COLLISION_TYPE_SPHERE,
|
||||
COLLISION_TYPE_CYLINDER,
|
||||
COLLISION_TYPE_AABB,
|
||||
COLLISION_TYPE_OBB,
|
||||
};
|
||||
|
||||
struct CDynamicSphereInstance
|
||||
{
|
||||
D3DXVECTOR3 v3Position;
|
||||
D3DXVECTOR3 v3LastPosition;
|
||||
|
||||
float fRadius;
|
||||
};
|
||||
|
||||
class CStaticCollisionData
|
||||
{
|
||||
public:
|
||||
DWORD dwType;
|
||||
char szName[32+1];
|
||||
|
||||
D3DXVECTOR3 v3Position;
|
||||
float fDimensions[3];
|
||||
D3DXQUATERNION quatRotation;
|
||||
};
|
||||
|
||||
void DestroyCollisionInstanceSystem();
|
||||
|
||||
typedef std::vector<CStaticCollisionData> CStaticCollisionDataVector;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Base
|
||||
class CBaseCollisionInstance
|
||||
{
|
||||
public:
|
||||
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID) = 0;
|
||||
|
||||
bool MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
return OnMovementCollisionDynamicSphere(s);
|
||||
}
|
||||
bool CollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
return OnCollisionDynamicSphere(s);
|
||||
}
|
||||
|
||||
|
||||
D3DXVECTOR3 GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
return OnGetCollisionMovementAdjust(s);
|
||||
}
|
||||
|
||||
void Destroy();
|
||||
|
||||
static CBaseCollisionInstance * BuildCollisionInstance(const CStaticCollisionData * c_pCollisionData, const D3DXMATRIX * pMat);
|
||||
|
||||
protected:
|
||||
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const = 0;
|
||||
virtual bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const = 0;
|
||||
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const = 0;
|
||||
virtual void OnDestroy() = 0;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Sphere
|
||||
class CSphereCollisionInstance : public CBaseCollisionInstance
|
||||
{
|
||||
public:
|
||||
TSphereData & GetAttribute();
|
||||
const TSphereData & GetAttribute() const;
|
||||
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
|
||||
|
||||
protected:
|
||||
void OnDestroy();
|
||||
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
|
||||
|
||||
protected:
|
||||
TSphereData m_attribute;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Plane
|
||||
class CPlaneCollisionInstance : public CBaseCollisionInstance
|
||||
{
|
||||
public:
|
||||
TPlaneData & GetAttribute();
|
||||
const TPlaneData & GetAttribute() const;
|
||||
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
|
||||
|
||||
protected:
|
||||
void OnDestroy();
|
||||
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
|
||||
|
||||
protected:
|
||||
TPlaneData m_attribute;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// AABB (Aligned Axis Bounding Box)
|
||||
class CAABBCollisionInstance : public CBaseCollisionInstance
|
||||
{
|
||||
public:
|
||||
TAABBData & GetAttribute();
|
||||
const TAABBData & GetAttribute() const;
|
||||
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
|
||||
|
||||
protected:
|
||||
void OnDestroy();
|
||||
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
|
||||
|
||||
protected:
|
||||
TAABBData m_attribute;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// OBB
|
||||
class COBBCollisionInstance : public CBaseCollisionInstance
|
||||
{
|
||||
public:
|
||||
TOBBData & GetAttribute();
|
||||
const TOBBData & GetAttribute() const;
|
||||
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
|
||||
|
||||
protected:
|
||||
void OnDestroy();
|
||||
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
|
||||
|
||||
protected:
|
||||
TOBBData m_attribute;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Cylinder
|
||||
class CCylinderCollisionInstance : public CBaseCollisionInstance
|
||||
{
|
||||
public:
|
||||
TCylinderData & GetAttribute();
|
||||
const TCylinderData & GetAttribute() const;
|
||||
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
|
||||
|
||||
protected:
|
||||
void OnDestroy();
|
||||
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
|
||||
|
||||
bool CollideCylinderVSDynamicSphere(const TCylinderData & c_rattribute, const CDynamicSphereInstance & s) const;
|
||||
|
||||
protected:
|
||||
TCylinderData m_attribute;
|
||||
};
|
||||
|
||||
typedef std::vector<CSphereCollisionInstance> CSphereCollisionInstanceVector;
|
||||
typedef std::vector<CDynamicSphereInstance> CDynamicSphereInstanceVector;
|
||||
typedef std::vector<CBaseCollisionInstance*> CCollisionInstanceVector;
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ColorTransitionHelper.h"
|
||||
|
||||
void CColorTransitionHelper::Clear(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha)
|
||||
{
|
||||
|
||||
m_fSrcRed = c_rfRed;
|
||||
m_fSrcGreen = c_rfGreen;
|
||||
m_fSrcBlue = c_rfBlue;
|
||||
m_fSrcAlpha = c_rfAlpha;
|
||||
|
||||
m_fDstRed = c_rfRed;
|
||||
m_fDstGreen = c_rfGreen;
|
||||
m_fDstBlue = c_rfBlue;
|
||||
m_fDstAlpha = c_rfAlpha;
|
||||
|
||||
m_dwCurColor = 0x00000000;
|
||||
|
||||
m_dwStartTime = m_dwDuration = 0;
|
||||
}
|
||||
|
||||
void CColorTransitionHelper::SetSrcColor(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha)
|
||||
{
|
||||
m_fSrcRed = c_rfRed;
|
||||
m_fSrcGreen = c_rfGreen;
|
||||
m_fSrcBlue = c_rfBlue;
|
||||
m_fSrcAlpha = c_rfAlpha;
|
||||
}
|
||||
|
||||
void CColorTransitionHelper::SetTransition(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha,
|
||||
const DWORD & dwDuration)
|
||||
{
|
||||
m_fDstRed = c_rfRed;
|
||||
m_fDstGreen = c_rfGreen;
|
||||
m_fDstBlue = c_rfBlue;
|
||||
m_fDstAlpha = c_rfAlpha;
|
||||
|
||||
m_dwDuration = dwDuration;
|
||||
}
|
||||
|
||||
void CColorTransitionHelper::StartTransition()
|
||||
{
|
||||
m_bTransitionStarted = true;
|
||||
m_dwStartTime = GetCurrentTime();
|
||||
}
|
||||
|
||||
bool CColorTransitionHelper::Update()
|
||||
{
|
||||
// if (!m_bTransitionStarted)
|
||||
// return false;
|
||||
|
||||
DWORD dwCurTime = GetCurrentTime();
|
||||
DWORD dwElapsedTime = dwCurTime - m_dwStartTime;
|
||||
|
||||
float fpercent = (float)(dwElapsedTime) / (float)(m_dwDuration);
|
||||
if (fpercent <= 0.0f)
|
||||
fpercent = 0.0f;
|
||||
if (fpercent >= 1.0f)
|
||||
fpercent = 1.0f;
|
||||
float fCurRed, fCurGreen, fCurBlue, fCurAlpha;
|
||||
fCurRed = m_fSrcRed + (m_fDstRed - m_fSrcRed) * fpercent;
|
||||
fCurGreen = m_fSrcGreen + (m_fDstGreen - m_fSrcGreen) * fpercent;
|
||||
fCurBlue = m_fSrcBlue + (m_fDstBlue - m_fSrcBlue) * fpercent;
|
||||
fCurAlpha = m_fSrcAlpha + (m_fDstAlpha - m_fSrcAlpha) * fpercent;
|
||||
|
||||
// Tracef("%f, %f, %f, %f\n", fCurRed, fCurGreen, fCurBlue, fCurAlpha);
|
||||
|
||||
m_dwCurColor = (((DWORD)(fCurAlpha * 255.0f)&0xff)<< 24) |
|
||||
(((DWORD)(fCurRed * 255.0f)&0xff) << 16) |
|
||||
(((DWORD)(fCurGreen * 255.0f)&0xff) << 8) |
|
||||
((DWORD)(fCurBlue * 255.0f)&0xff);
|
||||
|
||||
if ( (1.0f == fpercent) && (fCurAlpha == m_fDstAlpha) && (fCurRed == m_fDstRed) && (fCurGreen == m_fDstGreen) && (fCurBlue == m_fDstBlue) )
|
||||
{
|
||||
m_bTransitionStarted = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const D3DCOLOR & CColorTransitionHelper::GetCurColor()
|
||||
{
|
||||
return m_dwCurColor;
|
||||
}
|
||||
|
||||
CColorTransitionHelper::CColorTransitionHelper():m_bTransitionStarted(false)
|
||||
{
|
||||
Clear(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
CColorTransitionHelper::~CColorTransitionHelper()
|
||||
{
|
||||
Clear(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
class CColorTransitionHelper
|
||||
{
|
||||
public:
|
||||
CColorTransitionHelper();
|
||||
~CColorTransitionHelper();
|
||||
|
||||
void Clear(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha);
|
||||
void SetSrcColor(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha);
|
||||
void SetTransition(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha,
|
||||
const DWORD & dwDuration);
|
||||
const D3DCOLOR & GetCurColor();// { return m_dwCurColor; }
|
||||
|
||||
void StartTransition();
|
||||
bool Update();
|
||||
|
||||
bool isTransitionStarted() { return m_bTransitionStarted; }
|
||||
|
||||
private:
|
||||
D3DCOLOR m_dwCurColor; // 현재 색
|
||||
|
||||
DWORD m_dwStartTime; // 바뀌기 시작하는 시간
|
||||
DWORD m_dwDuration; // 얼마 동안에 바뀌는가?
|
||||
|
||||
bool m_bTransitionStarted;
|
||||
|
||||
float m_fSrcRed, m_fSrcGreen, m_fSrcBlue, m_fSrcAlpha;
|
||||
float m_fDstRed, m_fDstGreen, m_fDstBlue, m_fDstAlpha;
|
||||
};
|
||||
@@ -0,0 +1,176 @@
|
||||
#include "StdAfx.h"
|
||||
#include "CullingManager.h"
|
||||
#include "GrpObjectInstance.h"
|
||||
|
||||
//#define COUNT_SHOWING_SPHERE
|
||||
|
||||
#ifdef COUNT_SHOWING_SPHERE
|
||||
int showingcount = 0;
|
||||
#endif
|
||||
|
||||
void CCullingManager::RayTraceCallback(const Vector3d &/*p1*/, // source pos of ray
|
||||
const Vector3d &/*dir*/, // dest pos of ray
|
||||
float distance,
|
||||
const Vector3d &/*sect*/,
|
||||
SpherePack *sphere)
|
||||
{
|
||||
//if (state!=VS_OUTSIDE)
|
||||
//{
|
||||
if (m_RayFarDistance<=0.0f || m_RayFarDistance>=distance)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (sphere->IS_SPHERE)
|
||||
puts("CCullingManager::RayTraceCallback");
|
||||
#endif
|
||||
m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData());
|
||||
}
|
||||
//f((CGraphicObjectInstance *)sphere->GetUserData());
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
void CCullingManager::VisibilityCallback(const Frustum &/*f*/,SpherePack *sphere,ViewState state)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (sphere->IS_SPHERE)
|
||||
puts("CCullingManager::VisibilityCallback");
|
||||
#endif
|
||||
|
||||
CGraphicObjectInstance * pInstance = (CGraphicObjectInstance*)sphere->GetUserData();
|
||||
/*if (state == VS_PARTIAL)
|
||||
{
|
||||
Vector3d v;
|
||||
float r;
|
||||
pInstance->GetBoundingSphere(v,r);
|
||||
state = f.ViewVolumeTest(v,r);
|
||||
}*/
|
||||
if (state == VS_OUTSIDE)
|
||||
{
|
||||
#ifdef COUNT_SHOWING_SPHERE
|
||||
if (pInstance->isShow())
|
||||
{
|
||||
Tracef("SH : %p ",sphere->GetUserData());
|
||||
showingcount--;
|
||||
Tracef("show size : %5d\n",showingcount);
|
||||
}
|
||||
|
||||
#endif
|
||||
pInstance->Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef COUNT_SHOWING_SPHERE
|
||||
if (!pInstance->isShow())
|
||||
{
|
||||
Tracef("HS : %p ",sphere->GetUserData());
|
||||
showingcount++;
|
||||
Tracef("show size : %5d\n",showingcount);
|
||||
}
|
||||
#endif
|
||||
pInstance->Show();
|
||||
}
|
||||
}
|
||||
|
||||
void CCullingManager::RangeTestCallback(const Vector3d &/*p*/,float /*distance*/,SpherePack *sphere,ViewState state)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (sphere->IS_SPHERE)
|
||||
puts("CCullingManager::RangeTestCallback");
|
||||
#endif
|
||||
if (state!=VS_OUTSIDE)
|
||||
{
|
||||
m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData());
|
||||
//f((CGraphicObjectInstance *)sphere->GetUserData());
|
||||
}
|
||||
//assert(false && "NOT REACHED");
|
||||
}
|
||||
|
||||
void CCullingManager::Reset()
|
||||
{
|
||||
m_Factory->Reset();
|
||||
}
|
||||
|
||||
void CCullingManager::Update()
|
||||
{
|
||||
// TODO : update each object
|
||||
// ÇÏÁö¸»°í °¢ÀÚ ÇÏ°Ô ÇØº¸ÀÚ
|
||||
|
||||
//DWORD time = ELTimer_GetMSec();
|
||||
//Reset();
|
||||
|
||||
m_Factory->Process();
|
||||
//Tracef("cull update : %3d ",ELTimer_GetMSec()-time);
|
||||
}
|
||||
|
||||
void CCullingManager::Process()
|
||||
{
|
||||
//DWORD time = ELTimer_GetMSec();
|
||||
//Frustum f;
|
||||
UpdateViewMatrix();
|
||||
UpdateProjMatrix();
|
||||
BuildViewFrustum();
|
||||
m_Factory->FrustumTest(GetFrustum(), this);
|
||||
//Tracef("cull process : %3d ",ELTimer_GetMSec()-time);
|
||||
}
|
||||
|
||||
CCullingManager::CullingHandle CCullingManager::Register(CGraphicObjectInstance * obj)
|
||||
{
|
||||
assert(obj);
|
||||
#ifdef COUNT_SHOWING_SPHERE
|
||||
Tracef("CR : %p ",obj);
|
||||
showingcount++;
|
||||
Tracef("show size : %5d\n",showingcount);
|
||||
#endif
|
||||
Vector3d center;
|
||||
float radius;
|
||||
obj->GetBoundingSphere(center,radius);
|
||||
return m_Factory->AddSphere_(center,radius,obj, false);
|
||||
}
|
||||
|
||||
void CCullingManager::Unregister(CullingHandle h)
|
||||
{
|
||||
#ifdef COUNT_SHOWING_SPHERE
|
||||
if (((CGraphicObjectInstance*)h->GetUserData())->isShow())
|
||||
{
|
||||
Tracef("DE : %p ",h->GetUserData());
|
||||
showingcount--;
|
||||
Tracef("show size : %5d\n",showingcount);
|
||||
}
|
||||
#endif
|
||||
m_Factory->Remove(h);
|
||||
}
|
||||
|
||||
CCullingManager::CCullingManager()
|
||||
{
|
||||
m_Factory = new SpherePackFactory(
|
||||
10000, // maximum count
|
||||
6400, // root radius
|
||||
1600, // leaf radius
|
||||
400 // extra radius
|
||||
);
|
||||
}
|
||||
|
||||
CCullingManager::~CCullingManager()
|
||||
{
|
||||
delete m_Factory;
|
||||
}
|
||||
|
||||
void CCullingManager::FindRange(const Vector3d &p, float radius)
|
||||
{
|
||||
m_list.clear();
|
||||
m_Factory->RangeTest(p, radius, this);
|
||||
}
|
||||
|
||||
void CCullingManager::FindRay(const Vector3d &p1, const Vector3d &dir)
|
||||
{
|
||||
m_RayFarDistance = -1;
|
||||
m_list.clear();
|
||||
m_Factory->RayTrace(p1,dir,this);
|
||||
}
|
||||
|
||||
void CCullingManager::FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance)
|
||||
{
|
||||
m_RayFarDistance = distance;
|
||||
m_list.clear();
|
||||
m_Factory->RayTrace(p1,dir,this);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpScreen.h"
|
||||
|
||||
#include "../EterBase/Singleton.h"
|
||||
#include "../SphereLib/spherepack.h"
|
||||
|
||||
class CGraphicObjectInstance;
|
||||
template <class T>
|
||||
struct RangeTester : public SpherePackCallback
|
||||
{
|
||||
T * f;
|
||||
float dist;
|
||||
RangeTester(T * fn, float distance=-1)
|
||||
: f(fn), dist(distance)
|
||||
{}
|
||||
|
||||
virtual ~RangeTester()
|
||||
{}
|
||||
|
||||
|
||||
virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray
|
||||
const Vector3d &dir, // dest pos of ray
|
||||
float distance,
|
||||
const Vector3d §,
|
||||
SpherePack *sphere)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (sphere->IS_SPHERE)
|
||||
puts("RangeTester::RayTraceCallback");
|
||||
#endif
|
||||
if (dist<=0.0f || dist>=distance)
|
||||
(*f)((CGraphicObjectInstance *)sphere->GetUserData());
|
||||
};
|
||||
|
||||
|
||||
virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state){};
|
||||
|
||||
virtual void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (sphere->IS_SPHERE)
|
||||
puts("RangeTester::RangeTestCallback");
|
||||
#endif
|
||||
if (state!=VS_OUTSIDE)
|
||||
(*f)((CGraphicObjectInstance *)sphere->GetUserData());
|
||||
}
|
||||
|
||||
virtual void PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
if (sphere->IS_SPHERE)
|
||||
puts("RangeTester::PointTest2dCallback");
|
||||
#endif
|
||||
if (state!=VS_OUTSIDE)
|
||||
{
|
||||
#ifdef SPHERELIB_STRICT
|
||||
puts("FIND!!");
|
||||
#endif
|
||||
(*f)((CGraphicObjectInstance *)sphere->GetUserData());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CCullingManager : public CSingleton<CCullingManager>, public SpherePackCallback, private CScreen
|
||||
{
|
||||
public:
|
||||
typedef SpherePack * CullingHandle;
|
||||
typedef std::vector<CGraphicObjectInstance *> TRangeList;
|
||||
|
||||
CCullingManager();
|
||||
virtual ~CCullingManager();
|
||||
|
||||
virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray
|
||||
const Vector3d &dir, // dest pos of ray
|
||||
float distance,
|
||||
const Vector3d §,
|
||||
SpherePack *sphere);
|
||||
|
||||
|
||||
virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state);
|
||||
|
||||
void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state);
|
||||
|
||||
void Reset();
|
||||
void Update();
|
||||
void Process();
|
||||
|
||||
void FindRange(const Vector3d &p, float radius);
|
||||
void FindRay(const Vector3d &p1, const Vector3d &dir);
|
||||
void FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance);
|
||||
|
||||
void RangeTest(const Vector3d& p, float radius, SpherePackCallback* callback)
|
||||
{
|
||||
m_Factory->RangeTest(p, radius, callback);
|
||||
}
|
||||
|
||||
void PointTest2d(const Vector3d& p, SpherePackCallback* callback)
|
||||
{
|
||||
m_Factory->PointTest2d(p, callback);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void ForInRange2d(const Vector3d& p, T* pFunc)
|
||||
{
|
||||
RangeTester<T> r(pFunc);
|
||||
m_Factory->PointTest2d(p, &r);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void ForInRange(const Vector3d &p, float radius, T* pFunc)
|
||||
{
|
||||
RangeTester<T> r(pFunc);
|
||||
m_Factory->RangeTest(p, radius, &r/*this*/);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void ForInRay(const Vector3d &p1, const Vector3d &dir, T* pFunc)
|
||||
{
|
||||
RangeTester<T> r(pFunc);
|
||||
/*Vector3d p2;
|
||||
//p2.Set(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f));
|
||||
p2.x = p.x+50000.0f*dir.x;
|
||||
p2.y = p.y+50000.0f*dir.y;
|
||||
p2.z = p.z+50000.0f*dir.z;
|
||||
// p + (50000.0f*dir);//(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f));*/
|
||||
m_Factory->RayTrace(p1, dir, &r/*this*/);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void ForInRayDistance(const Vector3d &p, const Vector3d &dir, float distance, T* pFunc)
|
||||
{
|
||||
RangeTester<T> r(pFunc, distance);
|
||||
m_Factory->RayTrace(p, dir, &r/*this*/);
|
||||
}
|
||||
|
||||
CullingHandle Register(CGraphicObjectInstance * ob);
|
||||
void Unregister(CullingHandle h);
|
||||
|
||||
TRangeList::iterator begin() { return m_list.begin(); }
|
||||
TRangeList::iterator end() { return m_list.end(); }
|
||||
|
||||
protected:
|
||||
TRangeList m_list;
|
||||
|
||||
float m_RayFarDistance;
|
||||
|
||||
SpherePackFactory * m_Factory;
|
||||
};
|
||||
@@ -0,0 +1,287 @@
|
||||
// Decal.cpp: implementation of the CDecal class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Decal.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CDecal
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CDecal::CDecal():m_cfDecalEpsilon(0.25f)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CDecal::~CDecal()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CDecal::Clear()
|
||||
{
|
||||
m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_v3Normal = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_v4LeftPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
m_v4RightPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
m_v4TopPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
m_v4BottomPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
m_v4FrontPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
m_v4BackPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_dwVertexCount = 0;
|
||||
m_dwPrimitiveCount = 0;
|
||||
|
||||
m_TriangleFanStructVector.clear();
|
||||
|
||||
memset(m_Vertices, 0, sizeof(m_Vertices));
|
||||
memset(m_Indices, 0, sizeof(m_Indices));
|
||||
}
|
||||
|
||||
void CDecal::ClipMesh(DWORD dwPrimitiveCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal)
|
||||
{
|
||||
D3DXVECTOR3 v3NewVertex[9];
|
||||
D3DXVECTOR3 v3NewNormal[9];
|
||||
|
||||
// Clip one triangle at a time
|
||||
for(DWORD dwi = 0; dwi < dwPrimitiveCount; ++dwi)
|
||||
{
|
||||
const D3DXVECTOR3 & v3_1 = c_pv3Vertex[3 * dwi];
|
||||
const D3DXVECTOR3 & v3_2 = c_pv3Vertex[3 * dwi + 1];
|
||||
const D3DXVECTOR3 & v3_3 = c_pv3Vertex[3 * dwi + 2];
|
||||
|
||||
D3DXVECTOR3 v3Cross;
|
||||
const auto vv_ = (v3_2 - v3_1);
|
||||
const auto vv_2 = (v3_3 - v3_1);
|
||||
D3DXVec3Cross(&v3Cross, &vv_, &vv_2);
|
||||
if (D3DXVec3Dot(&m_v3Normal, &v3Cross) > ( m_cfDecalEpsilon ) * D3DXVec3Length(&v3Cross))
|
||||
{
|
||||
v3NewVertex[0] = v3_1;
|
||||
v3NewVertex[1] = v3_2;
|
||||
v3NewVertex[2] = v3_3;
|
||||
|
||||
v3NewNormal[0] = c_pv3Normal[3 * dwi];
|
||||
v3NewNormal[1] = c_pv3Normal[3 * dwi + 1];
|
||||
v3NewNormal[2] = c_pv3Normal[3 * dwi + 2];
|
||||
|
||||
DWORD dwCount = ClipPolygon(3, v3NewVertex, v3NewNormal, v3NewVertex, v3NewNormal);
|
||||
if ((dwCount != 0) && (!AddPolygon(dwCount, v3NewVertex, v3NewNormal))) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CDecal::AddPolygon(DWORD dwAddCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 * /*c_pv3Normal */)
|
||||
{
|
||||
if (m_dwVertexCount + dwAddCount >= MAX_DECAL_VERTICES)
|
||||
return false;
|
||||
|
||||
TTRIANGLEFANSTRUCT aTriangleFanStruct;
|
||||
aTriangleFanStruct.m_wMinIndex = m_dwVertexCount;
|
||||
aTriangleFanStruct.m_dwVertexCount = dwAddCount;
|
||||
aTriangleFanStruct.m_dwPrimitiveCount = dwAddCount - 2;
|
||||
aTriangleFanStruct.m_dwVBOffset = m_dwVertexCount;
|
||||
|
||||
m_TriangleFanStructVector.push_back(aTriangleFanStruct);
|
||||
|
||||
DWORD dwCount = m_dwVertexCount;
|
||||
|
||||
// Add polygon as a triangle fan
|
||||
WORD * wIndex = m_Indices + dwCount;
|
||||
|
||||
m_dwPrimitiveCount += dwAddCount - 2;
|
||||
//float fOne_over_1MinusDecalEpsilon = 1.0f / (1.0f - m_cfDecalEpsilon);
|
||||
|
||||
// Assign vertex colors
|
||||
for (DWORD dwVertexNum = 0; dwVertexNum < dwAddCount; ++dwVertexNum)
|
||||
{
|
||||
*wIndex++ = (WORD) dwCount;
|
||||
m_Vertices[dwCount].position = c_pv3Vertex[dwVertexNum];
|
||||
//const D3DXVECTOR3 & v3Normal = c_pv3Normal[dwVertexNum];
|
||||
//float fAlpha = (D3DXVec3Dot(&m_v3Normal, &v3Normal) / D3DXVec3Length(&v3Normal) - m_cfDecalEpsilon) * fOne_over_1MinusDecalEpsilon;
|
||||
//m_Vertices[dwCount].diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, (fAlpha > 0.0f) ? fAlpha : 0.0f);
|
||||
m_Vertices[dwCount].diffuse = 0xFFFFFFFF;
|
||||
++dwCount;
|
||||
}
|
||||
|
||||
m_dwVertexCount = dwCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CDecal::ClipPolygon(DWORD dwVertexCount,
|
||||
const D3DXVECTOR3 *c_pv3Vertex,
|
||||
const D3DXVECTOR3 *c_pv3Normal,
|
||||
D3DXVECTOR3 *c_pv3NewVertex,
|
||||
D3DXVECTOR3 *c_pv3NewNormal) const
|
||||
{
|
||||
D3DXVECTOR3 v3TempVertex[9];
|
||||
D3DXVECTOR3 v3TempNormal[9];
|
||||
|
||||
// Clip against all six planes
|
||||
DWORD dwCount = ClipPolygonAgainstPlane(m_v4LeftPlane, dwVertexCount, c_pv3Vertex, c_pv3Normal, v3TempVertex, v3TempNormal);
|
||||
if (dwCount != 0)
|
||||
{
|
||||
dwCount = ClipPolygonAgainstPlane(m_v4RightPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal);
|
||||
if (dwCount != 0)
|
||||
{
|
||||
dwCount = ClipPolygonAgainstPlane(m_v4BottomPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal);
|
||||
if (dwCount != 0)
|
||||
{
|
||||
dwCount = ClipPolygonAgainstPlane(m_v4TopPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal);
|
||||
if (dwCount != 0)
|
||||
{
|
||||
dwCount = ClipPolygonAgainstPlane(m_v4BackPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal);
|
||||
if (dwCount != 0)
|
||||
{
|
||||
dwCount = ClipPolygonAgainstPlane(m_v4FrontPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dwCount;
|
||||
}
|
||||
|
||||
DWORD CDecal::ClipPolygonAgainstPlane(const D3DXPLANE& c_rv4Plane,
|
||||
DWORD dwVertexCount,
|
||||
const D3DXVECTOR3 *c_pv3Vertex,
|
||||
const D3DXVECTOR3 *c_pv3Normal,
|
||||
D3DXVECTOR3 *c_pv3NewVertex,
|
||||
D3DXVECTOR3 *c_pv3NewNormal)
|
||||
{
|
||||
bool bNegative[10];
|
||||
|
||||
// Classify vertices
|
||||
DWORD dwNegativeCount = 0;
|
||||
for (DWORD dwi = 0; dwi < dwVertexCount; ++dwi)
|
||||
{
|
||||
bool bNeg = (D3DXPlaneDotCoord(&c_rv4Plane, &c_pv3Vertex[dwi]) < 0.0F);
|
||||
bNegative[dwi] = bNeg;
|
||||
dwNegativeCount += bNeg;
|
||||
}
|
||||
|
||||
// Discard this polygon if it's completely culled
|
||||
if (dwNegativeCount == dwVertexCount)
|
||||
return 0;
|
||||
|
||||
DWORD dwCount = 0;
|
||||
for (DWORD dwCurIndex = 0; dwCurIndex < dwVertexCount; ++dwCurIndex)
|
||||
{
|
||||
// dwPrevIndex is the index of the previous vertex
|
||||
DWORD dwPrevIndex = (dwCurIndex != 0) ? dwCurIndex - 1 : dwVertexCount - 1;
|
||||
|
||||
if (bNegative[dwCurIndex])
|
||||
{
|
||||
if (!bNegative[dwPrevIndex])
|
||||
{
|
||||
// Current vertex is on negative side of plane,
|
||||
// but previous vertex is on positive side.
|
||||
const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwPrevIndex];
|
||||
const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwCurIndex];
|
||||
float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z));
|
||||
c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft;
|
||||
const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwPrevIndex];
|
||||
const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwCurIndex];
|
||||
c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft;
|
||||
++dwCount;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bNegative[dwPrevIndex])
|
||||
{
|
||||
// Current vertex is on positive side of plane,
|
||||
// but previous vertex is on negative side.
|
||||
const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwCurIndex];
|
||||
const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwPrevIndex];
|
||||
float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z));
|
||||
c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft;
|
||||
const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwCurIndex];
|
||||
const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwPrevIndex];
|
||||
c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft;
|
||||
++dwCount;
|
||||
}
|
||||
|
||||
// Include current vertex
|
||||
c_pv3NewVertex[dwCount] = c_pv3Vertex[dwCurIndex];
|
||||
c_pv3NewNormal[dwCount] = c_pv3Normal[dwCurIndex];
|
||||
++dwCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return number of vertices in clipped polygon
|
||||
return dwCount;
|
||||
}
|
||||
|
||||
/*
|
||||
void CDecal::Update()
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
void CDecal::Render()
|
||||
{
|
||||
D3DXMATRIX matWorld;
|
||||
D3DXMatrixIdentity(&matWorld);
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld);
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
|
||||
|
||||
for (DWORD dwi = 0; dwi < m_TriangleFanStructVector.size(); ++dwi)
|
||||
STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN,
|
||||
m_TriangleFanStructVector[dwi].m_wMinIndex,
|
||||
m_TriangleFanStructVector[dwi].m_dwVertexCount,
|
||||
m_TriangleFanStructVector[dwi].m_dwPrimitiveCount,
|
||||
m_Indices + m_TriangleFanStructVector[dwi].m_wMinIndex,
|
||||
D3DFMT_INDEX16,
|
||||
m_Vertices,
|
||||
sizeof(TPDTVertex));
|
||||
}
|
||||
|
||||
/*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CDecalManager
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CDecalManager aDecalManager;
|
||||
|
||||
CDecalManager::CDecalManager()
|
||||
{
|
||||
m_DecalPtrVector.clear();
|
||||
}
|
||||
|
||||
CDecalManager::~CDecalManager()
|
||||
{
|
||||
m_DecalPtrVector.clear();
|
||||
}
|
||||
|
||||
void CDecalManager::Add(CDecal * pDecal)
|
||||
{
|
||||
m_DecalPtrVector.push_back(pDecal);
|
||||
}
|
||||
|
||||
void CDecalManager::Remove(CDecal * pDecal)
|
||||
{
|
||||
std::vector<CDecal *>::iterator aIterator;
|
||||
for (aIterator = m_DecalPtrVector.begin(); aIterator != m_DecalPtrVector.end();)
|
||||
{
|
||||
if (*aIterator == pDecal)
|
||||
aIterator = m_DecalPtrVector.erase(aIterator);
|
||||
else
|
||||
++aIterator;
|
||||
}
|
||||
}
|
||||
|
||||
void CDecalManager::Update()
|
||||
{
|
||||
for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi)
|
||||
m_DecalPtrVector[dwi]->Update();
|
||||
}
|
||||
|
||||
void CDecalManager::Render()
|
||||
{
|
||||
for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi)
|
||||
m_DecalPtrVector[dwi]->Render();
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,103 @@
|
||||
// Decal.h: interface for the CDecal class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_)
|
||||
#define AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "GrpBase.h"
|
||||
|
||||
class CDecal
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_DECAL_VERTICES = 256,
|
||||
};
|
||||
|
||||
CDecal();
|
||||
virtual ~CDecal();
|
||||
|
||||
void Clear();
|
||||
|
||||
virtual void Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth) = 0;
|
||||
// virtual void Update();
|
||||
virtual void Render();
|
||||
|
||||
protected:
|
||||
//
|
||||
D3DXVECTOR3 m_v3Center;
|
||||
D3DXVECTOR3 m_v3Normal;
|
||||
|
||||
// Clip Plane
|
||||
D3DXPLANE m_v4LeftPlane;
|
||||
D3DXPLANE m_v4RightPlane;
|
||||
D3DXPLANE m_v4BottomPlane;
|
||||
D3DXPLANE m_v4TopPlane;
|
||||
D3DXPLANE m_v4FrontPlane;
|
||||
D3DXPLANE m_v4BackPlane;
|
||||
|
||||
// 개수
|
||||
DWORD m_dwVertexCount;
|
||||
DWORD m_dwPrimitiveCount;
|
||||
|
||||
// 버택스 버퍼와 인댁스 버퍼
|
||||
// CGraphicVertexBuffer m_GraphicVertexBuffer;
|
||||
// CGraphicIndexBuffer m_GraphicIndexBuffer;
|
||||
|
||||
// 버택스 버퍼와 인댁스 버퍼 대신에 배열 만들고 DrawIndexedPrimitiveUP로 그리자.
|
||||
typedef struct
|
||||
{
|
||||
WORD m_wMinIndex;
|
||||
DWORD m_dwVertexCount;
|
||||
DWORD m_dwPrimitiveCount;
|
||||
DWORD m_dwVBOffset;
|
||||
} TTRIANGLEFANSTRUCT;
|
||||
|
||||
std::vector<TTRIANGLEFANSTRUCT> m_TriangleFanStructVector;
|
||||
|
||||
TPDTVertex m_Vertices[MAX_DECAL_VERTICES];
|
||||
WORD m_Indices[MAX_DECAL_VERTICES];
|
||||
|
||||
const float m_cfDecalEpsilon;
|
||||
|
||||
protected:
|
||||
bool AddPolygon(DWORD dwAddCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal);
|
||||
void ClipMesh(DWORD dwPrimitiveCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal);
|
||||
DWORD ClipPolygon(DWORD dwVertexCount,
|
||||
const D3DXVECTOR3 *c_pv3Vertex,
|
||||
const D3DXVECTOR3 *c_pv3Normal,
|
||||
D3DXVECTOR3 *c_pv3NewVertex,
|
||||
D3DXVECTOR3 *c_pv3NewNormal) const;
|
||||
static DWORD ClipPolygonAgainstPlane(const D3DXPLANE& v4Plane,
|
||||
DWORD dwVertexCount,
|
||||
const D3DXVECTOR3 *c_pv3Vertex,
|
||||
const D3DXVECTOR3 *c_pv3Normal,
|
||||
D3DXVECTOR3 *c_pv3NewVertex,
|
||||
D3DXVECTOR3 *c_pv3NewNormal);
|
||||
};
|
||||
/*
|
||||
|
||||
class CDecalManager : public CSingleton<CDecalManager>
|
||||
{
|
||||
public:
|
||||
CDecalManager();
|
||||
~CDecalManager();
|
||||
|
||||
void Add(CDecal * pDecal);
|
||||
void Remove(CDecal * pDecal);
|
||||
void Update();
|
||||
void Render();
|
||||
|
||||
private:
|
||||
std::vector<CDecal *> m_DecalPtrVector;
|
||||
|
||||
};
|
||||
|
||||
*/
|
||||
#endif // !defined(AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_)
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpDIB.h"
|
||||
|
||||
class CBlockTexture;
|
||||
|
||||
class CDibBar
|
||||
{
|
||||
public:
|
||||
CDibBar();
|
||||
virtual ~CDibBar();
|
||||
|
||||
bool Create(HDC hdc, DWORD dwWidth, DWORD dwHeight);
|
||||
void Invalidate();
|
||||
void SetClipRect(const RECT & c_rRect);
|
||||
void ClearBar();
|
||||
void Render(int ix, int iy);
|
||||
|
||||
protected:
|
||||
DWORD __NearTextureSize(DWORD dwSize);
|
||||
void __DivideTextureSize(DWORD dwSize, DWORD dwMax, DWORD * pdwxStep, DWORD * pdwxCount, DWORD * pdwxRest);
|
||||
CBlockTexture * __BuildTextureBlock(DWORD dwxPos, DWORD dwyPos, DWORD dwImageWidth, DWORD dwImageHeight, DWORD dwTextureWidth, DWORD dwTextureHeight);
|
||||
void __BuildTextureBlockList(DWORD dwWidth, DWORD dwHeight, DWORD dwMax=256);
|
||||
|
||||
virtual void OnCreate(){}
|
||||
|
||||
protected:
|
||||
CGraphicDib m_dib;
|
||||
std::vector<CBlockTexture *> m_kVec_pkBlockTexture;
|
||||
|
||||
DWORD m_dwWidth;
|
||||
DWORD m_dwHeight;
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__
|
||||
#define __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__
|
||||
|
||||
#include <deque>
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
#include "../EterBase/MappedFile.h"
|
||||
|
||||
class CFileLoaderThread
|
||||
{
|
||||
public:
|
||||
typedef struct SData
|
||||
{
|
||||
std::string stFileName;
|
||||
|
||||
CMappedFile File;
|
||||
LPVOID pvBuf;
|
||||
DWORD dwSize;
|
||||
} TData;
|
||||
|
||||
public:
|
||||
CFileLoaderThread();
|
||||
~CFileLoaderThread();
|
||||
|
||||
int Create(void * arg);
|
||||
|
||||
public:
|
||||
void Request(std::string & c_rstFileName);
|
||||
bool Fetch(TData ** ppData);
|
||||
void Shutdown();
|
||||
|
||||
protected:
|
||||
static UINT CALLBACK EntryPoint(void * pThis);
|
||||
UINT Run(void * arg);
|
||||
|
||||
void * Arg() const { return m_pArg; }
|
||||
void Arg(void * arg) { m_pArg = arg; }
|
||||
|
||||
HANDLE m_hThread;
|
||||
|
||||
private:
|
||||
void * m_pArg;
|
||||
unsigned m_uThreadID;
|
||||
|
||||
protected:
|
||||
UINT Setup();
|
||||
UINT Execute(void * pvArg);
|
||||
void Destroy();
|
||||
void Process();
|
||||
|
||||
private:
|
||||
std::deque<TData *> m_pRequestDeque;
|
||||
Mutex m_RequestMutex;
|
||||
|
||||
std::deque<TData *> m_pCompleteDeque;
|
||||
Mutex m_CompleteMutex;
|
||||
|
||||
HANDLE m_hSemaphore;
|
||||
int m_iRestSemCount;
|
||||
bool m_bShutdowned;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
template<typename T>
|
||||
class CFuncObject
|
||||
{
|
||||
public:
|
||||
CFuncObject()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
virtual ~CFuncObject()
|
||||
{
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_pSelfObject = NULL;
|
||||
m_pFuncObject = NULL;
|
||||
}
|
||||
|
||||
void Set(T* pSelfObject, void (T::*pFuncObject)())
|
||||
{
|
||||
m_pSelfObject = pSelfObject;
|
||||
m_pFuncObject = pFuncObject;
|
||||
}
|
||||
|
||||
bool IsEmpty()
|
||||
{
|
||||
if (m_pSelfObject != NULL)
|
||||
return false;
|
||||
|
||||
if (m_pFuncObject != NULL)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Run()
|
||||
{
|
||||
if (m_pSelfObject)
|
||||
if (m_pFuncObject)
|
||||
(m_pSelfObject->*m_pFuncObject)();
|
||||
}
|
||||
|
||||
protected:
|
||||
T * m_pSelfObject;
|
||||
void (T::*m_pFuncObject) ();
|
||||
};
|
||||
@@ -0,0 +1,522 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterBase/Utils.h"
|
||||
#include "../EterBase/Timer.h"
|
||||
#include "GrpBase.h"
|
||||
#include "Camera.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
void PixelPositionToD3DXVECTOR3(const D3DXVECTOR3& c_rkPPosSrc, D3DXVECTOR3* pv3Dst)
|
||||
{
|
||||
pv3Dst->x=+c_rkPPosSrc.x;
|
||||
pv3Dst->y=-c_rkPPosSrc.y;
|
||||
pv3Dst->z=+c_rkPPosSrc.z;
|
||||
}
|
||||
|
||||
void D3DXVECTOR3ToPixelPosition(const D3DXVECTOR3& c_rv3Src, D3DXVECTOR3* pv3Dst)
|
||||
{
|
||||
pv3Dst->x=+c_rv3Src.x;
|
||||
pv3Dst->y=-c_rv3Src.y;
|
||||
pv3Dst->z=+c_rv3Src.z;
|
||||
}
|
||||
|
||||
UINT CGraphicBase::ms_iD3DAdapterInfo=0;
|
||||
UINT CGraphicBase::ms_iD3DDevInfo=0;
|
||||
UINT CGraphicBase::ms_iD3DModeInfo=0;
|
||||
D3D_CDisplayModeAutoDetector CGraphicBase::ms_kD3DDetector;
|
||||
|
||||
HWND CGraphicBase::ms_hWnd;
|
||||
HDC CGraphicBase::ms_hDC;
|
||||
|
||||
LPDIRECT3D8 CGraphicBase::ms_lpd3d = NULL;
|
||||
LPDIRECT3DDEVICE8 CGraphicBase::ms_lpd3dDevice = NULL;
|
||||
ID3DXMatrixStack * CGraphicBase::ms_lpd3dMatStack = NULL;
|
||||
D3DPRESENT_PARAMETERS CGraphicBase::ms_d3dPresentParameter;
|
||||
D3DVIEWPORT8 CGraphicBase::ms_Viewport;
|
||||
|
||||
HRESULT CGraphicBase::ms_hLastResult = NULL;
|
||||
|
||||
int CGraphicBase::ms_iWidth;
|
||||
int CGraphicBase::ms_iHeight;
|
||||
|
||||
DWORD CGraphicBase::ms_faceCount = 0;
|
||||
|
||||
D3DCAPS8 CGraphicBase::ms_d3dCaps;
|
||||
|
||||
DWORD CGraphicBase::ms_dwD3DBehavior = 0;
|
||||
|
||||
DWORD CGraphicBase::ms_ptVS = 0;
|
||||
DWORD CGraphicBase::ms_pntVS = 0;
|
||||
DWORD CGraphicBase::ms_pnt2VS = 0;
|
||||
|
||||
D3DXMATRIX CGraphicBase::ms_matIdentity;
|
||||
|
||||
D3DXMATRIX CGraphicBase::ms_matView;
|
||||
D3DXMATRIX CGraphicBase::ms_matProj;
|
||||
D3DXMATRIX CGraphicBase::ms_matInverseView;
|
||||
D3DXMATRIX CGraphicBase::ms_matInverseViewYAxis;
|
||||
|
||||
D3DXMATRIX CGraphicBase::ms_matWorld;
|
||||
D3DXMATRIX CGraphicBase::ms_matWorldView;
|
||||
|
||||
D3DXMATRIX CGraphicBase::ms_matScreen0;
|
||||
D3DXMATRIX CGraphicBase::ms_matScreen1;
|
||||
D3DXMATRIX CGraphicBase::ms_matScreen2;
|
||||
|
||||
D3DXVECTOR3 CGraphicBase::ms_vtPickRayOrig;
|
||||
D3DXVECTOR3 CGraphicBase::ms_vtPickRayDir;
|
||||
|
||||
float CGraphicBase::ms_fFieldOfView;
|
||||
float CGraphicBase::ms_fNearY;
|
||||
float CGraphicBase::ms_fFarY;
|
||||
float CGraphicBase::ms_fAspect;
|
||||
|
||||
DWORD CGraphicBase::ms_dwWavingEndTime;
|
||||
int CGraphicBase::ms_iWavingPower;
|
||||
DWORD CGraphicBase::ms_dwFlashingEndTime;
|
||||
D3DXCOLOR CGraphicBase::ms_FlashingColor;
|
||||
|
||||
// Terrain picking용 Ray... CCamera 이용하는 버전.. 기존의 Ray와 통합 필요...
|
||||
CRay CGraphicBase::ms_Ray;
|
||||
bool CGraphicBase::ms_bSupportDXT = true;
|
||||
bool CGraphicBase::ms_isLowTextureMemory = false;
|
||||
bool CGraphicBase::ms_isHighTextureMemory = false;
|
||||
|
||||
// 2004.11.18.myevan.DynamicVertexBuffer로 교체
|
||||
/*
|
||||
std::vector<TIndex> CGraphicBase::ms_lineIdxVector;
|
||||
std::vector<TIndex> CGraphicBase::ms_lineTriIdxVector;
|
||||
std::vector<TIndex> CGraphicBase::ms_lineRectIdxVector;
|
||||
std::vector<TIndex> CGraphicBase::ms_lineCubeIdxVector;
|
||||
|
||||
std::vector<TIndex> CGraphicBase::ms_fillTriIdxVector;
|
||||
std::vector<TIndex> CGraphicBase::ms_fillRectIdxVector;
|
||||
std::vector<TIndex> CGraphicBase::ms_fillCubeIdxVector;
|
||||
*/
|
||||
|
||||
LPD3DXMESH CGraphicBase::ms_lpSphereMesh = NULL;
|
||||
LPD3DXMESH CGraphicBase::ms_lpCylinderMesh = NULL;
|
||||
|
||||
LPDIRECT3DVERTEXBUFFER8 CGraphicBase::ms_alpd3dPDTVB[PDT_VERTEXBUFFER_NUM];
|
||||
|
||||
LPDIRECT3DINDEXBUFFER8 CGraphicBase::ms_alpd3dDefIB[DEFAULT_IB_NUM];
|
||||
|
||||
bool CGraphicBase::IsLowTextureMemory()
|
||||
{
|
||||
return ms_isLowTextureMemory;
|
||||
}
|
||||
|
||||
bool CGraphicBase::IsHighTextureMemory()
|
||||
{
|
||||
return ms_isHighTextureMemory;
|
||||
}
|
||||
|
||||
bool CGraphicBase::IsFastTNL()
|
||||
{
|
||||
if (ms_dwD3DBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ||
|
||||
ms_dwD3DBehavior & D3DCREATE_MIXED_VERTEXPROCESSING)
|
||||
{
|
||||
if (ms_d3dCaps.VertexShaderVersion>D3DVS_VERSION(1,0))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicBase::IsTLVertexClipping()
|
||||
{
|
||||
if (ms_d3dCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGraphicBase::GetBackBufferSize(UINT* puWidth, UINT* puHeight)
|
||||
{
|
||||
*puWidth=ms_d3dPresentParameter.BackBufferWidth;
|
||||
*puHeight=ms_d3dPresentParameter.BackBufferHeight;
|
||||
}
|
||||
|
||||
void CGraphicBase::SetBackBufferSize(UINT uWidth, UINT uHeight)
|
||||
{
|
||||
ms_d3dPresentParameter.BackBufferWidth = uWidth;
|
||||
ms_d3dPresentParameter.BackBufferHeight = uHeight;
|
||||
ms_iWidth = uWidth;
|
||||
ms_iHeight = uHeight;
|
||||
ms_Viewport.Width = uWidth;
|
||||
ms_Viewport.Height = uHeight;
|
||||
}
|
||||
|
||||
void CGraphicBase::SetDefaultIndexBuffer(UINT eDefIB)
|
||||
{
|
||||
if (eDefIB>=DEFAULT_IB_NUM)
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetIndices(ms_alpd3dDefIB[eDefIB], 0);
|
||||
}
|
||||
|
||||
bool CGraphicBase::SetPDTStream(SPDTVertex* pVertices, UINT uVtxCount)
|
||||
{
|
||||
return SetPDTStream((SPDTVertexRaw*)pVertices, uVtxCount);
|
||||
}
|
||||
|
||||
bool CGraphicBase::SetPDTStream(SPDTVertexRaw* pSrcVertices, UINT uVtxCount)
|
||||
{
|
||||
if (!uVtxCount)
|
||||
return false;
|
||||
|
||||
static DWORD s_dwVBPos=0;
|
||||
|
||||
if (s_dwVBPos>=PDT_VERTEXBUFFER_NUM)
|
||||
s_dwVBPos=0;
|
||||
|
||||
IDirect3DVertexBuffer8* plpd3dFillRectVB=ms_alpd3dPDTVB[s_dwVBPos];
|
||||
++s_dwVBPos;
|
||||
|
||||
assert(PDT_VERTEX_NUM>=uVtxCount);
|
||||
if (uVtxCount >= PDT_VERTEX_NUM)
|
||||
return false;
|
||||
|
||||
TPDTVertex* pDstVertices;
|
||||
if (FAILED(
|
||||
plpd3dFillRectVB->Lock(0, sizeof(TPDTVertex)*uVtxCount, (BYTE**)&pDstVertices, D3DLOCK_DISCARD)
|
||||
))
|
||||
{
|
||||
STATEMANAGER.SetStreamSource(0, NULL, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
memcpy(pDstVertices, pSrcVertices, sizeof(TPDTVertex)*uVtxCount);
|
||||
|
||||
plpd3dFillRectVB->Unlock();
|
||||
|
||||
STATEMANAGER.SetStreamSource(0, plpd3dFillRectVB, sizeof(TPDTVertex));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CGraphicBase::GetAvailableTextureMemory()
|
||||
{
|
||||
assert(ms_lpd3dDevice!=NULL && "CGraphicBase::GetAvailableTextureMemory - D3DDevice is EMPTY");
|
||||
|
||||
static DWORD s_dwNextUpdateTime=0;
|
||||
static DWORD s_dwTexMemSize=0;//ms_lpd3dDevice->GetAvailableTextureMem();
|
||||
|
||||
DWORD dwCurTime=ELTimer_GetMSec();
|
||||
if (s_dwNextUpdateTime<dwCurTime)
|
||||
{
|
||||
s_dwNextUpdateTime=dwCurTime+5000;
|
||||
s_dwTexMemSize=ms_lpd3dDevice->GetAvailableTextureMem();
|
||||
}
|
||||
|
||||
return s_dwTexMemSize;
|
||||
}
|
||||
|
||||
const D3DXMATRIX& CGraphicBase::GetViewMatrix()
|
||||
{
|
||||
return ms_matView;
|
||||
}
|
||||
|
||||
const D3DXMATRIX & CGraphicBase::GetIdentityMatrix()
|
||||
{
|
||||
return ms_matIdentity;
|
||||
}
|
||||
|
||||
void CGraphicBase::SetEyeCamera(float xEye, float yEye, float zEye,
|
||||
float xCenter, float yCenter, float zCenter,
|
||||
float xUp, float yUp, float zUp)
|
||||
{
|
||||
D3DXVECTOR3 vectorEye(xEye, yEye, zEye);
|
||||
D3DXVECTOR3 vectorCenter(xCenter, yCenter, zCenter);
|
||||
D3DXVECTOR3 vectorUp(xUp, yUp, zUp);
|
||||
|
||||
// CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
|
||||
CCameraManager::Instance().GetCurrentCamera()->SetViewParams(vectorEye, vectorCenter, vectorUp);
|
||||
UpdateViewMatrix();
|
||||
}
|
||||
|
||||
void CGraphicBase::SetSimpleCamera(float x, float y, float z, float pitch, float roll)
|
||||
{
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
D3DXVECTOR3 vectorEye(x, y, z);
|
||||
|
||||
pCamera->SetViewParams(D3DXVECTOR3(0.0f, y, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f));
|
||||
pCamera->RotateEyeAroundTarget(pitch, roll);
|
||||
pCamera->Move(vectorEye);
|
||||
|
||||
UpdateViewMatrix();
|
||||
|
||||
// This is levites's virtual(?) code which you should not trust.
|
||||
ms_lpd3dDevice->GetTransform(D3DTS_WORLD, &ms_matWorld);
|
||||
D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView);
|
||||
}
|
||||
|
||||
void CGraphicBase::SetAroundCamera(float distance, float pitch, float roll, float lookAtZ)
|
||||
{
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
pCamera->SetViewParams(D3DXVECTOR3(0.0f, -distance, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f));
|
||||
pCamera->RotateEyeAroundTarget(pitch, roll);
|
||||
D3DXVECTOR3 v3Target = pCamera->GetTarget();
|
||||
v3Target.z = lookAtZ;
|
||||
pCamera->SetTarget(v3Target);
|
||||
// pCamera->Move(v3Target);
|
||||
|
||||
UpdateViewMatrix();
|
||||
|
||||
// This is levites's virtual(?) code which you should not trust.
|
||||
ms_lpd3dDevice->GetTransform(D3DTS_WORLD, &ms_matWorld);
|
||||
D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView);
|
||||
}
|
||||
|
||||
void CGraphicBase::SetPositionCamera(float fx, float fy, float fz, float distance, float pitch, float roll)
|
||||
{
|
||||
// I wanna downward this code to the game control level. - [levites]
|
||||
if (ms_dwWavingEndTime > CTimer::Instance().GetCurrentMillisecond())
|
||||
{
|
||||
if (ms_iWavingPower>0)
|
||||
{
|
||||
fx += float(rand() % ms_iWavingPower) / 10.0f;
|
||||
fy += float(rand() % ms_iWavingPower) / 10.0f;
|
||||
fz += float(rand() % ms_iWavingPower) / 10.0f;
|
||||
}
|
||||
}
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
pCamera->SetViewParams(D3DXVECTOR3(0.0f, -distance, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f));
|
||||
pitch = fMIN(80.0f, fMAX(-80.0f, pitch) );
|
||||
// Tracef("SetPosition Camera : %f, %f\n", pitch, roll);
|
||||
pCamera->RotateEyeAroundTarget(pitch, roll);
|
||||
pCamera->Move(D3DXVECTOR3(fx, fy, fz));
|
||||
|
||||
UpdateViewMatrix();
|
||||
|
||||
// This is levites's virtual(?) code which you should not trust.
|
||||
STATEMANAGER.GetTransform(D3DTS_WORLD, &ms_matWorld);
|
||||
D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView);
|
||||
}
|
||||
|
||||
void CGraphicBase::SetOrtho2D(float hres, float vres, float zres)
|
||||
{
|
||||
//CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_ORTHO_CAMERA);
|
||||
D3DXMatrixOrthoOffCenterRH(&ms_matProj, 0, hres, vres, 0, 0, zres);
|
||||
//UpdatePipeLineMatrix();
|
||||
UpdateProjMatrix();
|
||||
}
|
||||
|
||||
void CGraphicBase::SetOrtho3D(float hres, float vres, float zmin, float zmax)
|
||||
{
|
||||
//CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
|
||||
D3DXMatrixOrthoRH(&ms_matProj, hres, vres, zmin, zmax);
|
||||
//UpdatePipeLineMatrix();
|
||||
UpdateProjMatrix();
|
||||
}
|
||||
|
||||
void CGraphicBase::SetPerspective(float fov, float aspect, float nearz, float farz)
|
||||
{
|
||||
ms_fFieldOfView = fov;
|
||||
|
||||
|
||||
//if (ms_d3dPresentParameter.BackBufferWidth>0 && ms_d3dPresentParameter.BackBufferHeight>0)
|
||||
// ms_fAspect = float(ms_d3dPresentParameter.BackBufferWidth)/float(ms_d3dPresentParameter.BackBufferHeight);
|
||||
//else
|
||||
ms_fAspect = aspect;
|
||||
|
||||
ms_fNearY = nearz;
|
||||
ms_fFarY = farz;
|
||||
|
||||
//CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
|
||||
D3DXMatrixPerspectiveFovRH(&ms_matProj, D3DXToRadian(fov), ms_fAspect, nearz, farz);
|
||||
//UpdatePipeLineMatrix();
|
||||
UpdateProjMatrix();
|
||||
}
|
||||
|
||||
void CGraphicBase::UpdateProjMatrix()
|
||||
{
|
||||
STATEMANAGER.SetTransform(D3DTS_PROJECTION, &ms_matProj);
|
||||
}
|
||||
|
||||
void CGraphicBase::UpdateViewMatrix()
|
||||
{
|
||||
CCamera* pkCamera=CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pkCamera)
|
||||
return;
|
||||
|
||||
ms_matView = pkCamera->GetViewMatrix();
|
||||
STATEMANAGER.SetTransform(D3DTS_VIEW, &ms_matView);
|
||||
|
||||
D3DXMatrixInverse(&ms_matInverseView, NULL, &ms_matView);
|
||||
ms_matInverseViewYAxis._11 = ms_matInverseView._11;
|
||||
ms_matInverseViewYAxis._12 = ms_matInverseView._12;
|
||||
ms_matInverseViewYAxis._21 = ms_matInverseView._21;
|
||||
ms_matInverseViewYAxis._22 = ms_matInverseView._22;
|
||||
}
|
||||
|
||||
void CGraphicBase::UpdatePipeLineMatrix()
|
||||
{
|
||||
UpdateProjMatrix();
|
||||
UpdateViewMatrix();
|
||||
}
|
||||
|
||||
void CGraphicBase::SetViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight, float fMinZ, float fMaxZ)
|
||||
{
|
||||
ms_Viewport.X = dwX;
|
||||
ms_Viewport.Y = dwY;
|
||||
ms_Viewport.Width = dwWidth;
|
||||
ms_Viewport.Height = dwHeight;
|
||||
ms_Viewport.MinZ = fMinZ;
|
||||
ms_Viewport.MaxZ = fMaxZ;
|
||||
}
|
||||
|
||||
void CGraphicBase::GetTargetPosition(float * px, float * py, float * pz)
|
||||
{
|
||||
*px = CCameraManager::Instance().GetCurrentCamera()->GetTarget().x;
|
||||
*py = CCameraManager::Instance().GetCurrentCamera()->GetTarget().y;
|
||||
*pz = CCameraManager::Instance().GetCurrentCamera()->GetTarget().z;
|
||||
}
|
||||
|
||||
void CGraphicBase::GetCameraPosition(float * px, float * py, float * pz)
|
||||
{
|
||||
*px = CCameraManager::Instance().GetCurrentCamera()->GetEye().x;
|
||||
*py = CCameraManager::Instance().GetCurrentCamera()->GetEye().y;
|
||||
*pz = CCameraManager::Instance().GetCurrentCamera()->GetEye().z;
|
||||
}
|
||||
|
||||
void CGraphicBase::GetMatrix(D3DXMATRIX* pRetMatrix) const
|
||||
{
|
||||
assert(ms_lpd3dMatStack != NULL);
|
||||
*pRetMatrix = *ms_lpd3dMatStack->GetTop();
|
||||
}
|
||||
|
||||
const D3DXMATRIX* CGraphicBase::GetMatrixPointer() const
|
||||
{
|
||||
assert(ms_lpd3dMatStack!=NULL);
|
||||
return ms_lpd3dMatStack->GetTop();
|
||||
}
|
||||
|
||||
void CGraphicBase::GetSphereMatrix(D3DXMATRIX * pMatrix, float fValue)
|
||||
{
|
||||
D3DXMatrixIdentity(pMatrix);
|
||||
pMatrix->_11 = fValue * ms_matWorldView._11;
|
||||
pMatrix->_21 = fValue * ms_matWorldView._21;
|
||||
pMatrix->_31 = fValue * ms_matWorldView._31;
|
||||
pMatrix->_41 = fValue;
|
||||
pMatrix->_12 = -fValue * ms_matWorldView._12;
|
||||
pMatrix->_22 = -fValue * ms_matWorldView._22;
|
||||
pMatrix->_32 = -fValue * ms_matWorldView._32;
|
||||
pMatrix->_42 = -fValue;
|
||||
}
|
||||
|
||||
float CGraphicBase::GetFOV()
|
||||
{
|
||||
return ms_fFieldOfView;
|
||||
}
|
||||
|
||||
void CGraphicBase::PushMatrix()
|
||||
{
|
||||
ms_lpd3dMatStack->Push();
|
||||
}
|
||||
|
||||
void CGraphicBase::Scale(float x, float y, float z)
|
||||
{
|
||||
ms_lpd3dMatStack->Scale(x, y, z);
|
||||
}
|
||||
|
||||
void CGraphicBase::Rotate(float degree, float x, float y, float z)
|
||||
{
|
||||
D3DXVECTOR3 vec(x, y, z);
|
||||
ms_lpd3dMatStack->RotateAxis(&vec, D3DXToRadian(degree));
|
||||
}
|
||||
|
||||
void CGraphicBase::RotateLocal(float degree, float x, float y, float z)
|
||||
{
|
||||
D3DXVECTOR3 vec(x, y, z);
|
||||
ms_lpd3dMatStack->RotateAxisLocal(&vec, D3DXToRadian(degree));
|
||||
}
|
||||
|
||||
void CGraphicBase::MultMatrix( const D3DXMATRIX* pMat)
|
||||
{
|
||||
ms_lpd3dMatStack->MultMatrix(pMat);
|
||||
}
|
||||
|
||||
void CGraphicBase::MultMatrixLocal( const D3DXMATRIX* pMat)
|
||||
{
|
||||
ms_lpd3dMatStack->MultMatrixLocal(pMat);
|
||||
}
|
||||
|
||||
void CGraphicBase::RotateYawPitchRollLocal(float fYaw, float fPitch, float fRoll)
|
||||
{
|
||||
ms_lpd3dMatStack->RotateYawPitchRollLocal(D3DXToRadian(fYaw), D3DXToRadian(fPitch), D3DXToRadian(fRoll));
|
||||
}
|
||||
|
||||
void CGraphicBase::Translate(float x, float y, float z)
|
||||
{
|
||||
ms_lpd3dMatStack->Translate(x, y, z);
|
||||
}
|
||||
|
||||
void CGraphicBase::LoadMatrix(const D3DXMATRIX& c_rSrcMatrix)
|
||||
{
|
||||
ms_lpd3dMatStack->LoadMatrix(&c_rSrcMatrix);
|
||||
}
|
||||
|
||||
void CGraphicBase::PopMatrix()
|
||||
{
|
||||
ms_lpd3dMatStack->Pop();
|
||||
}
|
||||
|
||||
DWORD CGraphicBase::GetColor(float r, float g, float b, float a)
|
||||
{
|
||||
BYTE argb[4] =
|
||||
{
|
||||
(BYTE) (255.0f * b),
|
||||
(BYTE) (255.0f * g),
|
||||
(BYTE) (255.0f * r),
|
||||
(BYTE) (255.0f * a)
|
||||
};
|
||||
|
||||
return *((DWORD *) argb);
|
||||
}
|
||||
|
||||
void CGraphicBase::InitScreenEffect()
|
||||
{
|
||||
ms_dwWavingEndTime = 0;
|
||||
ms_dwFlashingEndTime = 0;
|
||||
ms_iWavingPower = 0;
|
||||
ms_FlashingColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void CGraphicBase::SetScreenEffectWaving(float fDuringTime, int iPower)
|
||||
{
|
||||
ms_dwWavingEndTime = CTimer::Instance().GetCurrentMillisecond() + long(fDuringTime * 1000.0f);
|
||||
ms_iWavingPower = iPower;
|
||||
}
|
||||
|
||||
void CGraphicBase::SetScreenEffectFlashing(float fDuringTime, const D3DXCOLOR & c_rColor)
|
||||
{
|
||||
ms_dwFlashingEndTime = CTimer::Instance().GetCurrentMillisecond() + long(fDuringTime * 1000.0f);
|
||||
ms_FlashingColor = c_rColor;
|
||||
}
|
||||
|
||||
DWORD CGraphicBase::GetFaceCount()
|
||||
{
|
||||
return ms_faceCount;
|
||||
}
|
||||
|
||||
void CGraphicBase::ResetFaceCount()
|
||||
{
|
||||
ms_faceCount = 0;
|
||||
}
|
||||
|
||||
HRESULT CGraphicBase::GetLastResult()
|
||||
{
|
||||
return ms_hLastResult;
|
||||
}
|
||||
|
||||
CGraphicBase::CGraphicBase()
|
||||
{
|
||||
}
|
||||
|
||||
CGraphicBase::~CGraphicBase()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpDetector.h"
|
||||
#include "Ray.h"
|
||||
#include <vector>
|
||||
|
||||
void PixelPositionToD3DXVECTOR3(const D3DXVECTOR3& c_rkPPosSrc, D3DXVECTOR3* pv3Dst);
|
||||
void D3DXVECTOR3ToPixelPosition(const D3DXVECTOR3& c_rv3Src, D3DXVECTOR3* pv3Dst);
|
||||
|
||||
class CGraphicTexture;
|
||||
|
||||
typedef WORD TIndex;
|
||||
|
||||
typedef struct SFace
|
||||
{
|
||||
TIndex indices[3];
|
||||
} TFace;
|
||||
|
||||
typedef D3DXVECTOR3 TPosition;
|
||||
|
||||
typedef D3DXVECTOR3 TNormal;
|
||||
|
||||
typedef D3DXVECTOR2 TTextureCoordinate;
|
||||
|
||||
typedef DWORD TDiffuse;
|
||||
typedef DWORD TAmbient;
|
||||
typedef DWORD TSpecular;
|
||||
|
||||
typedef union UDepth
|
||||
{
|
||||
float f;
|
||||
long l;
|
||||
DWORD dw;
|
||||
} TDepth;
|
||||
|
||||
typedef struct SVertex
|
||||
{
|
||||
float x, y, z;
|
||||
DWORD color;
|
||||
float u, v;
|
||||
} TVertex;
|
||||
|
||||
struct STVertex
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
};
|
||||
|
||||
struct SPVertex
|
||||
{
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
typedef struct SPDVertex
|
||||
{
|
||||
float x, y, z;
|
||||
DWORD color;
|
||||
} TPDVertex;
|
||||
|
||||
struct SPDTVertexRaw
|
||||
{
|
||||
float px, py, pz;
|
||||
DWORD diffuse;
|
||||
float u, v;
|
||||
};
|
||||
|
||||
typedef struct SPTVertex
|
||||
{
|
||||
TPosition position;
|
||||
TTextureCoordinate texCoord;
|
||||
} TPTVertex;
|
||||
|
||||
typedef struct SPDTVertex
|
||||
{
|
||||
TPosition position;
|
||||
TDiffuse diffuse;
|
||||
TTextureCoordinate texCoord;
|
||||
} TPDTVertex;
|
||||
|
||||
typedef struct SPNTVertex
|
||||
{
|
||||
TPosition position;
|
||||
TNormal normal;
|
||||
TTextureCoordinate texCoord;
|
||||
} TPNTVertex;
|
||||
|
||||
typedef struct SPNT2Vertex
|
||||
{
|
||||
TPosition position;
|
||||
TNormal normal;
|
||||
TTextureCoordinate texCoord;
|
||||
TTextureCoordinate texCoord2;
|
||||
} TPNT2Vertex;
|
||||
|
||||
typedef struct SPDT2Vertex
|
||||
{
|
||||
TPosition position;
|
||||
DWORD diffuse;
|
||||
TTextureCoordinate texCoord;
|
||||
TTextureCoordinate texCoord2;
|
||||
} TPDT2Vertex;
|
||||
|
||||
typedef struct SNameInfo
|
||||
{
|
||||
DWORD name;
|
||||
TDepth depth;
|
||||
} TNameInfo;
|
||||
|
||||
typedef struct SBoundBox
|
||||
{
|
||||
float sx, sy, sz;
|
||||
float ex, ey, ez;
|
||||
int meshIndex;
|
||||
int boneIndex;
|
||||
} TBoundBox;
|
||||
|
||||
const WORD c_FillRectIndices[6] = { 0, 2, 1, 2, 3, 1 };
|
||||
|
||||
/*
|
||||
enum EIndexCount
|
||||
{
|
||||
LINE_INDEX_COUNT = 2,
|
||||
TRIANGLE_INDEX_COUNT = 2*3,
|
||||
RECTANGLE_INDEX_COUNT = 2*4,
|
||||
CUBE_INDEX_COUNT = 2*4*3,
|
||||
FILLED_TRIANGLE_INDEX_COUNT = 3,
|
||||
FILLED_RECTANGLE_INDEX_COUNT = 3*2,
|
||||
FILLED_CUBE_INDEX_COUNT = 3*2*6,
|
||||
};
|
||||
*/
|
||||
|
||||
class CGraphicBase
|
||||
{
|
||||
public:
|
||||
static DWORD GetAvailableTextureMemory();
|
||||
static const D3DXMATRIX& GetViewMatrix();
|
||||
static const D3DXMATRIX & GetIdentityMatrix();
|
||||
|
||||
enum
|
||||
{
|
||||
DEFAULT_IB_LINE,
|
||||
DEFAULT_IB_LINE_TRI,
|
||||
DEFAULT_IB_LINE_RECT,
|
||||
DEFAULT_IB_LINE_CUBE,
|
||||
DEFAULT_IB_FILL_TRI,
|
||||
DEFAULT_IB_FILL_RECT,
|
||||
DEFAULT_IB_FILL_CUBE,
|
||||
DEFAULT_IB_NUM,
|
||||
};
|
||||
|
||||
public:
|
||||
CGraphicBase();
|
||||
virtual ~CGraphicBase();
|
||||
|
||||
void SetSimpleCamera(float x, float y, float z, float pitch, float roll);
|
||||
void SetEyeCamera(float xEye, float yEye, float zEye, float xCenter, float yCenter, float zCenter, float xUp, float yUp, float zUp);
|
||||
void SetAroundCamera(float distance, float pitch, float roll, float lookAtZ = 0.0f);
|
||||
void SetPositionCamera(float fx, float fy, float fz, float fDistance, float fPitch, float fRotation);
|
||||
void MoveCamera(float fdeltax, float fdeltay, float fdeltaz);
|
||||
|
||||
void GetTargetPosition(float * px, float * py, float * pz);
|
||||
void GetCameraPosition(float * px, float * py, float * pz);
|
||||
void SetOrtho2D(float hres, float vres, float zres);
|
||||
void SetOrtho3D(float hres, float vres, float zmin, float zmax);
|
||||
void SetPerspective(float fov, float aspect, float nearz, float farz);
|
||||
float GetFOV();
|
||||
void GetClipPlane(float * fNearY, float * fFarY)
|
||||
{
|
||||
*fNearY = ms_fNearY;
|
||||
*fFarY = ms_fFarY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void PushMatrix();
|
||||
|
||||
void MultMatrix( const D3DXMATRIX* pMat );
|
||||
void MultMatrixLocal( const D3DXMATRIX* pMat );
|
||||
|
||||
void Translate(float x, float y, float z);
|
||||
void Rotate(float degree, float x, float y, float z);
|
||||
void RotateLocal(float degree, float x, float y, float z);
|
||||
void RotateYawPitchRollLocal(float fYaw, float fPitch, float fRoll);
|
||||
void Scale(float x, float y, float z);
|
||||
void PopMatrix();
|
||||
void LoadMatrix(const D3DXMATRIX & c_rSrcMatrix);
|
||||
void GetMatrix(D3DXMATRIX * pRetMatrix) const;
|
||||
const D3DXMATRIX * GetMatrixPointer() const;
|
||||
|
||||
// Special Routine
|
||||
void GetSphereMatrix(D3DXMATRIX * pMatrix, float fValue = 0.1f);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void InitScreenEffect();
|
||||
void SetScreenEffectWaving(float fDuringTime, int iPower);
|
||||
void SetScreenEffectFlashing(float fDuringTime, const D3DXCOLOR & c_rColor);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
DWORD GetColor(float r, float g, float b, float a = 1.0f);
|
||||
|
||||
DWORD GetFaceCount();
|
||||
void ResetFaceCount();
|
||||
HRESULT GetLastResult();
|
||||
|
||||
void UpdateProjMatrix();
|
||||
void UpdateViewMatrix();
|
||||
|
||||
void SetViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight, float fMinZ, float fMaxZ);
|
||||
static void GetBackBufferSize(UINT* puWidth, UINT* puHeight);
|
||||
static void SetBackBufferSize(UINT uWidth, UINT uHeight);
|
||||
static bool IsTLVertexClipping();
|
||||
static bool IsFastTNL();
|
||||
static bool IsLowTextureMemory();
|
||||
static bool IsHighTextureMemory();
|
||||
|
||||
static void SetDefaultIndexBuffer(UINT eDefIB);
|
||||
static bool SetPDTStream(SPDTVertexRaw* pVertices, UINT uVtxCount);
|
||||
static bool SetPDTStream(SPDTVertex* pVertices, UINT uVtxCount);
|
||||
|
||||
protected:
|
||||
static D3DXMATRIX ms_matIdentity;
|
||||
|
||||
static D3DXMATRIX ms_matView;
|
||||
static D3DXMATRIX ms_matProj;
|
||||
static D3DXMATRIX ms_matInverseView;
|
||||
static D3DXMATRIX ms_matInverseViewYAxis;
|
||||
|
||||
static D3DXMATRIX ms_matWorld;
|
||||
static D3DXMATRIX ms_matWorldView;
|
||||
|
||||
protected:
|
||||
//void UpdatePrePipeLineMatrix();
|
||||
void UpdatePipeLineMatrix();
|
||||
|
||||
protected:
|
||||
// 각종 D3DX Mesh 들 (컬루젼 데이터 등을 표시활 때 쓴다)
|
||||
static LPD3DXMESH ms_lpSphereMesh;
|
||||
static LPD3DXMESH ms_lpCylinderMesh;
|
||||
|
||||
protected:
|
||||
static HRESULT ms_hLastResult;
|
||||
|
||||
static int ms_iWidth;
|
||||
static int ms_iHeight;
|
||||
|
||||
static UINT ms_iD3DAdapterInfo;
|
||||
static UINT ms_iD3DDevInfo;
|
||||
static UINT ms_iD3DModeInfo;
|
||||
static D3D_CDisplayModeAutoDetector ms_kD3DDetector;
|
||||
|
||||
static HWND ms_hWnd;
|
||||
static HDC ms_hDC;
|
||||
static LPDIRECT3D8 ms_lpd3d;
|
||||
static LPDIRECT3DDEVICE8 ms_lpd3dDevice;
|
||||
static ID3DXMatrixStack* ms_lpd3dMatStack;
|
||||
static D3DVIEWPORT8 ms_Viewport;
|
||||
|
||||
static DWORD ms_faceCount;
|
||||
static D3DCAPS8 ms_d3dCaps;
|
||||
static D3DPRESENT_PARAMETERS ms_d3dPresentParameter;
|
||||
|
||||
static DWORD ms_dwD3DBehavior;
|
||||
static DWORD ms_ptVS;
|
||||
static DWORD ms_pntVS;
|
||||
static DWORD ms_pnt2VS;
|
||||
|
||||
static D3DXMATRIX ms_matScreen0;
|
||||
static D3DXMATRIX ms_matScreen1;
|
||||
static D3DXMATRIX ms_matScreen2;
|
||||
//static D3DXMATRIX ms_matPrePipeLine;
|
||||
|
||||
static D3DXVECTOR3 ms_vtPickRayOrig;
|
||||
static D3DXVECTOR3 ms_vtPickRayDir;
|
||||
|
||||
static float ms_fFieldOfView;
|
||||
static float ms_fAspect;
|
||||
static float ms_fNearY;
|
||||
static float ms_fFarY;
|
||||
|
||||
// 2004.11.18.myevan.DynamicVertexBuffer로 교체
|
||||
/*
|
||||
static std::vector<TIndex> ms_lineIdxVector;
|
||||
static std::vector<TIndex> ms_lineTriIdxVector;
|
||||
static std::vector<TIndex> ms_lineRectIdxVector;
|
||||
static std::vector<TIndex> ms_lineCubeIdxVector;
|
||||
|
||||
static std::vector<TIndex> ms_fillTriIdxVector;
|
||||
static std::vector<TIndex> ms_fillRectIdxVector;
|
||||
static std::vector<TIndex> ms_fillCubeIdxVector;
|
||||
*/
|
||||
|
||||
// Screen Effect - Waving, Flashing and so on..
|
||||
static DWORD ms_dwWavingEndTime;
|
||||
static int ms_iWavingPower;
|
||||
static DWORD ms_dwFlashingEndTime;
|
||||
static D3DXCOLOR ms_FlashingColor;
|
||||
|
||||
// Terrain picking용 Ray... CCamera 이용하는 버전.. 기존의 Ray와 통합 필요...
|
||||
static CRay ms_Ray;
|
||||
|
||||
//
|
||||
static bool ms_bSupportDXT;
|
||||
static bool ms_isLowTextureMemory;
|
||||
static bool ms_isHighTextureMemory;
|
||||
|
||||
enum
|
||||
{
|
||||
PDT_VERTEX_NUM = 16,
|
||||
PDT_VERTEXBUFFER_NUM = 100,
|
||||
};
|
||||
|
||||
|
||||
static LPDIRECT3DVERTEXBUFFER8 ms_alpd3dPDTVB[PDT_VERTEXBUFFER_NUM];
|
||||
static LPDIRECT3DINDEXBUFFER8 ms_alpd3dDefIB[DEFAULT_IB_NUM];
|
||||
};
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "StdAfx.h"
|
||||
#include "GrpCollisionObject.h"
|
||||
|
||||
bool CGraphicCollisionObject::IntersectBoundBox(const D3DXMATRIX* c_pmatWorld, const TBoundBox& c_rboundBox, float* pu, float* pv, float* pt)
|
||||
{
|
||||
return IntersectCube(c_pmatWorld, c_rboundBox.sx, c_rboundBox.sy, c_rboundBox.sz, c_rboundBox.ex, c_rboundBox.ey, c_rboundBox.ez, ms_vtPickRayOrig, ms_vtPickRayDir, pu, pv, pt);
|
||||
}
|
||||
|
||||
bool CGraphicCollisionObject::IntersectCube(const D3DXMATRIX* c_pmatWorld, float sx, float sy, float sz, float ex, float ey, float ez,
|
||||
D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt)
|
||||
{
|
||||
TPosition posVertices[8];
|
||||
|
||||
posVertices[0] = TPosition(sx, sy, sz);
|
||||
posVertices[1] = TPosition(ex, sy, sz);
|
||||
posVertices[2] = TPosition(sx, ey, sz);
|
||||
posVertices[3] = TPosition(ex, ey, sz);
|
||||
posVertices[4] = TPosition(sx, sy, ez);
|
||||
posVertices[5] = TPosition(ex, sy, ez);
|
||||
posVertices[6] = TPosition(sx, ey, ez);
|
||||
posVertices[7] = TPosition(ex, ey, ez);
|
||||
|
||||
static const WORD c_awFillCubeIndices[36] = {
|
||||
0, 1, 2, 1, 3, 2,
|
||||
2, 0, 6, 0, 4, 6,
|
||||
0, 1, 4, 1, 5, 4,
|
||||
1, 3, 5, 3, 7, 5,
|
||||
3, 2, 7, 2, 6, 7,
|
||||
4, 5, 6, 5, 7, 6,
|
||||
};
|
||||
|
||||
return IntersectIndexedMesh(
|
||||
c_pmatWorld,
|
||||
posVertices,
|
||||
sizeof(TPosition),
|
||||
8,
|
||||
c_awFillCubeIndices,
|
||||
36,
|
||||
RayOriginal,
|
||||
RayDirection,
|
||||
pu,
|
||||
pv,
|
||||
pt
|
||||
);
|
||||
}
|
||||
|
||||
const int c_iLimitVertexCount = 1024;
|
||||
|
||||
bool CGraphicCollisionObject::IntersectIndexedMesh(const D3DXMATRIX* c_pmatWorld, const void* vertices, int step, int vtxCount, const void* indices, int idxCount,
|
||||
D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt)
|
||||
{
|
||||
static D3DXVECTOR3 s_v3PositionArray[c_iLimitVertexCount];
|
||||
static DWORD s_dwPositionCount;
|
||||
|
||||
if (vtxCount > c_iLimitVertexCount)
|
||||
{
|
||||
Tracef("The vertex count of mesh which is worked collision detection is too much : %d / %d", vtxCount, c_iLimitVertexCount);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_dwPositionCount = 0;
|
||||
|
||||
char* pcurVtx = (char*)vertices;
|
||||
|
||||
while (vtxCount--)
|
||||
{
|
||||
float* pos = (float*)pcurVtx;
|
||||
|
||||
D3DXVec3TransformCoord(&s_v3PositionArray[s_dwPositionCount++], (D3DXVECTOR3*)pos, c_pmatWorld);
|
||||
|
||||
pcurVtx += step;
|
||||
}
|
||||
|
||||
WORD* pcurIdx = (WORD*)indices;
|
||||
|
||||
int triCount = idxCount / 3;
|
||||
while (triCount--)
|
||||
{
|
||||
if (IntersectTriangle(RayOriginal, RayDirection,
|
||||
s_v3PositionArray[pcurIdx[0]],
|
||||
s_v3PositionArray[pcurIdx[1]],
|
||||
s_v3PositionArray[pcurIdx[2]],
|
||||
pu, pv, pt))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
pcurIdx += 3;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicCollisionObject::IntersectMesh(const D3DXMATRIX * c_pmatWorld, const void * vertices, DWORD dwStep, DWORD dwvtxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt)
|
||||
{
|
||||
char * pcurVtx = (char *) vertices;
|
||||
|
||||
D3DXVECTOR3 v3Vertex[3];
|
||||
|
||||
for (DWORD i = 0; i < dwvtxCount; i += 3)
|
||||
{
|
||||
D3DXVec3TransformCoord(&v3Vertex[0], (D3DXVECTOR3*)pcurVtx, c_pmatWorld);
|
||||
pcurVtx += dwStep;
|
||||
|
||||
D3DXVec3TransformCoord(&v3Vertex[1], (D3DXVECTOR3*)pcurVtx, c_pmatWorld);
|
||||
pcurVtx += dwStep;
|
||||
|
||||
D3DXVec3TransformCoord(&v3Vertex[2], (D3DXVECTOR3*)pcurVtx, c_pmatWorld);
|
||||
pcurVtx += dwStep;
|
||||
|
||||
if (IntersectTriangle(RayOriginal, RayDirection,
|
||||
v3Vertex[0], v3Vertex[1], v3Vertex[2],
|
||||
pu, pv, pt))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicCollisionObject::IntersectTriangle(const D3DXVECTOR3& c_orig,
|
||||
const D3DXVECTOR3& c_dir,
|
||||
const D3DXVECTOR3& c_v0,
|
||||
const D3DXVECTOR3& c_v1,
|
||||
const D3DXVECTOR3& c_v2,
|
||||
float * pu,
|
||||
float * pv,
|
||||
float * pt)
|
||||
{
|
||||
D3DXVECTOR3 edge1 = c_v1 - c_v0;
|
||||
D3DXVECTOR3 edge2 = c_v2 - c_v0;
|
||||
D3DXVECTOR3 pvec;
|
||||
D3DXVec3Cross(&pvec, &c_dir, &edge2);
|
||||
|
||||
FLOAT det = D3DXVec3Dot(&edge1, &pvec);
|
||||
D3DXVECTOR3 tvec;
|
||||
|
||||
if (det > 0)
|
||||
{
|
||||
tvec = c_orig - c_v0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tvec = c_v0 - c_orig;
|
||||
det = -det;
|
||||
}
|
||||
|
||||
if (det < 0.0001f)
|
||||
return false;
|
||||
|
||||
float u, v, t;
|
||||
u = D3DXVec3Dot(&tvec, &pvec);
|
||||
if (u < 0.0f || u > det)
|
||||
return false;
|
||||
|
||||
D3DXVECTOR3 qvec;
|
||||
D3DXVec3Cross(&qvec, &tvec, &edge1);
|
||||
|
||||
v = D3DXVec3Dot(&c_dir, &qvec);
|
||||
if (v < 0.0f || u + v > det)
|
||||
return false;
|
||||
|
||||
t = D3DXVec3Dot(&edge2, &qvec);
|
||||
FLOAT fInvDet = 1.0f / det;
|
||||
t *= fInvDet;
|
||||
u *= fInvDet;
|
||||
v *= fInvDet;
|
||||
|
||||
D3DXVECTOR3 spot = edge1 * u + edge2 * v;
|
||||
spot += c_v0;
|
||||
|
||||
*pu = spot.x;
|
||||
*pv = spot.y;
|
||||
*pt = t;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicCollisionObject::IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection)
|
||||
{
|
||||
D3DXVECTOR3 v3RayOriginal = c_rv3RayOriginal - c_rv3Position;
|
||||
|
||||
float a = D3DXVec3Dot(&c_rv3RayDirection, &c_rv3RayDirection);
|
||||
float b = 2 * D3DXVec3Dot(&v3RayOriginal, &c_rv3RayDirection);
|
||||
float c = D3DXVec3Dot(&v3RayOriginal, &v3RayOriginal) - fRadius * fRadius;
|
||||
|
||||
float D = b * b - 4 * a * c;
|
||||
|
||||
if (D >= 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicCollisionObject::IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection)
|
||||
{
|
||||
D3DXVECTOR3 v3RayOriginal = c_rv3RayOriginal - c_rv3Position;
|
||||
|
||||
float a = c_rv3RayDirection.x * c_rv3RayDirection.x + c_rv3RayDirection.y * c_rv3RayDirection.y;
|
||||
float b = 2 * (v3RayOriginal.x * c_rv3RayDirection.x + v3RayOriginal.y * c_rv3RayDirection.y);
|
||||
float c = v3RayOriginal.x * v3RayOriginal.x + v3RayOriginal.y * v3RayOriginal.y - fRadius*fRadius;
|
||||
|
||||
float D = b * b - 4 * a * c;
|
||||
if (D > 0)
|
||||
if (0.0f != a)
|
||||
{
|
||||
float tPlus = (-b + sqrtf(D)) / (2 * a);
|
||||
float tMinus = (-b - sqrtf(D)) / (2 * a);
|
||||
float fzPlus = v3RayOriginal.z + tPlus * c_rv3RayDirection.z;
|
||||
float fzMinus = v3RayOriginal.z + tMinus * c_rv3RayDirection.z;
|
||||
|
||||
if (fzPlus > 0.0f && fzPlus <= fHeight)
|
||||
return true;
|
||||
if (fzMinus > 0.0f && fzMinus <= fHeight)
|
||||
return true;
|
||||
if (fzMinus * fzPlus < 0.0f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicCollisionObject::IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius)
|
||||
{
|
||||
return CGraphicCollisionObject::IntersectSphere(c_rv3Position, fRadius, ms_vtPickRayOrig, ms_vtPickRayDir);
|
||||
}
|
||||
|
||||
bool CGraphicCollisionObject::IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight)
|
||||
{
|
||||
return CGraphicCollisionObject::IntersectCylinder(c_rv3Position, fRadius, fHeight, ms_vtPickRayOrig, ms_vtPickRayDir);
|
||||
}
|
||||
|
||||
CGraphicCollisionObject::CGraphicCollisionObject()
|
||||
{
|
||||
}
|
||||
|
||||
CGraphicCollisionObject::~CGraphicCollisionObject()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpBase.h"
|
||||
|
||||
class CGraphicCollisionObject : public CGraphicBase
|
||||
{
|
||||
public:
|
||||
CGraphicCollisionObject();
|
||||
virtual ~CGraphicCollisionObject();
|
||||
|
||||
protected:
|
||||
bool IntersectTriangle(const D3DXVECTOR3& c_orig, const D3DXVECTOR3& c_dir, const D3DXVECTOR3& c_v0, const D3DXVECTOR3& c_v1, const D3DXVECTOR3& c_v2, float* pu, float* pv, float* pt);
|
||||
bool IntersectBoundBox(const D3DXMATRIX* c_pmatWorld, const TBoundBox& c_rboundBox, float* pu, float* pv, float* pt);
|
||||
bool IntersectCube(const D3DXMATRIX* c_pmatWorld, float sx, float sy, float sz, float ex, float ey, float ez, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt);
|
||||
bool IntersectIndexedMesh(const D3DXMATRIX* c_pmatWorld, const void* vertices, int step, int vtxCount, const void* indices, int idxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt);
|
||||
bool IntersectMesh(const D3DXMATRIX * c_pmatWorld, const void * vertices, DWORD dwStep, DWORD dwvtxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt);
|
||||
|
||||
bool IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection);
|
||||
bool IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection);
|
||||
|
||||
// NOTE : ms_vtPickRayOrig와 ms_vtPickRayDir를 CGraphicBGase가 가지고 있는데
|
||||
// 굳이 인자로 넣어줘야 하는 이유가 있는가? Customize를 위해서? - [levites]
|
||||
bool IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius);
|
||||
bool IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight);
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
class CGraphicColor
|
||||
{
|
||||
public:
|
||||
CGraphicColor(const CGraphicColor& c_rSrcColor);
|
||||
CGraphicColor(float r, float g, float b, float a);
|
||||
CGraphicColor(DWORD color);
|
||||
|
||||
CGraphicColor();
|
||||
~CGraphicColor();
|
||||
|
||||
void Clear();
|
||||
|
||||
void Set(float r, float g, float b, float a);
|
||||
void Set(const CGraphicColor& c_rSrcColor);
|
||||
void Set(DWORD color);
|
||||
|
||||
void Blend(float p, const CGraphicColor& c_rSrcColor, const CGraphicColor& c_rDstColor);
|
||||
|
||||
DWORD GetPackValue() const;
|
||||
|
||||
protected:
|
||||
float m_r;
|
||||
float m_g;
|
||||
float m_b;
|
||||
float m_a;
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpColor.h"
|
||||
#include "Pool.h"
|
||||
|
||||
class CGraphicColorInstance
|
||||
{
|
||||
public:
|
||||
CGraphicColorInstance();
|
||||
virtual ~CGraphicColorInstance();
|
||||
|
||||
void Clear();
|
||||
|
||||
void SetColorReference(const CGraphicColor& c_rSrcColor);
|
||||
void BlendColorReference(DWORD blendTime, const CGraphicColor& c_rDstColor);
|
||||
|
||||
void Update();
|
||||
|
||||
const CGraphicColor& GetCurrentColorReference() const;
|
||||
|
||||
protected:
|
||||
DWORD GetCurrentTime();
|
||||
|
||||
protected:
|
||||
CGraphicColor m_srcColor;
|
||||
CGraphicColor m_dstColor;
|
||||
CGraphicColor m_curColor;
|
||||
|
||||
DWORD m_baseTime;
|
||||
DWORD m_blendTime;
|
||||
};
|
||||
|
||||
typedef CDynamicPool<CGraphicColorInstance> TGraphicColorInstancePool;
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
class CGraphicDib
|
||||
{
|
||||
public:
|
||||
CGraphicDib();
|
||||
virtual ~CGraphicDib();
|
||||
|
||||
void Destroy();
|
||||
bool Create(HDC hDC, int width, int height);
|
||||
|
||||
void SetBkMode(int iBkMode);
|
||||
void TextOut(int ix, int iy, const char * c_szText);
|
||||
void Put(HDC hDC, int x, int y);
|
||||
|
||||
int GetWidth();
|
||||
int GetHeight();
|
||||
|
||||
void* GetPointer();
|
||||
|
||||
HDC GetDCHandle();
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
HDC m_hDC;
|
||||
HBITMAP m_hBmp;
|
||||
BITMAPINFO m_bmi;
|
||||
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
void * m_pvBuf;
|
||||
};
|
||||
@@ -0,0 +1,166 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d8.h>
|
||||
#include <string>
|
||||
typedef BOOL (*PFNCONFIRMDEVICE) (D3DCAPS8& rkD3DCaps, UINT uBehavior, D3DFORMAT eD3DFmt);
|
||||
|
||||
enum
|
||||
{
|
||||
D3DDEVICETYPE_HAL,
|
||||
D3DDEVICETYPE_REF,
|
||||
D3DDEVICETYPE_NUM,
|
||||
};
|
||||
|
||||
struct D3D_SModeInfo
|
||||
{
|
||||
UINT m_uScrWidth;
|
||||
UINT m_uScrHeight;
|
||||
UINT m_uScrDepthBit;
|
||||
UINT m_dwD3DBehavior;
|
||||
D3DFORMAT m_eD3DFmtPixel;
|
||||
D3DFORMAT m_eD3DFmtDepthStencil;
|
||||
|
||||
VOID GetString(std::string* pstEnumList);
|
||||
};
|
||||
|
||||
class D3D_CAdapterDisplayModeList
|
||||
{
|
||||
public:
|
||||
D3D_CAdapterDisplayModeList() {}
|
||||
~D3D_CAdapterDisplayModeList() {}
|
||||
VOID Build(IDirect3D8& rkD3D, D3DFORMAT eD3DFmtDefault, UINT iAdapter);
|
||||
|
||||
UINT GetDisplayModeNum();
|
||||
UINT GetPixelFormatNum();
|
||||
|
||||
const D3DDISPLAYMODE& GetDisplayModer(UINT iD3DDM);
|
||||
const D3DFORMAT& GetPixelFormatr(UINT iD3DFmt);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
D3DDISPLAYMODE_MAX = 100,
|
||||
D3DFORMAT_MAX = 20,
|
||||
|
||||
FILTEROUT_LOWRESOLUTION_WIDTH = 640,
|
||||
FILTEROUT_LOWRESOLUTION_HEIGHT = 480,
|
||||
};
|
||||
|
||||
protected:
|
||||
D3DDISPLAYMODE m_akD3DDM[D3DDISPLAYMODE_MAX];
|
||||
D3DFORMAT m_aeD3DFmt[D3DFORMAT_MAX];
|
||||
|
||||
UINT m_uD3DDMNum;
|
||||
UINT m_uD3DFmtNum;
|
||||
|
||||
};
|
||||
|
||||
class D3D_CDeviceInfo
|
||||
{
|
||||
public:
|
||||
D3D_CDeviceInfo() {}
|
||||
~D3D_CDeviceInfo() {}
|
||||
BOOL Build(IDirect3D8& rkD3D, UINT iAdapter, UINT iDevType, D3D_CAdapterDisplayModeList& rkD3DADMList, PFNCONFIRMDEVICE pfnConfirmDevice);
|
||||
BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo);
|
||||
|
||||
UINT GetD3DModeInfoNum();
|
||||
|
||||
VOID GetString(std::string* pstEnumList);
|
||||
|
||||
BOOL FindDepthStencilFormat(IDirect3D8& rkD3D, UINT iAdapter, D3DDEVTYPE DeviceType, D3DFORMAT TargetFormat, D3DFORMAT* pDepthStencilFormat);
|
||||
|
||||
D3D_SModeInfo& GetD3DModeInfor(UINT iD3DModeInfo);
|
||||
D3D_SModeInfo* GetD3DModeInfop(UINT iD3DModeInfo);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
D3DMODEINFO_NUM = 150,
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
const TCHAR* m_szDevDesc;
|
||||
|
||||
D3DDEVTYPE m_eD3DDevType;
|
||||
D3DCAPS8 m_kD3DCaps;
|
||||
BOOL m_canDoWindowed;
|
||||
|
||||
UINT m_iCurD3DModeInfo;
|
||||
UINT m_uD3DModeInfoNum;
|
||||
D3D_SModeInfo m_akD3DModeInfo[D3DMODEINFO_NUM];
|
||||
|
||||
|
||||
BOOL m_isWindowed;
|
||||
|
||||
D3DMULTISAMPLE_TYPE m_eD3DMSTWindowed;
|
||||
D3DMULTISAMPLE_TYPE m_eD3DMSTFullscreen;
|
||||
|
||||
|
||||
protected:
|
||||
static const CHAR* msc_aszD3DDevDesc[D3DDEVICETYPE_NUM];
|
||||
static const D3DDEVTYPE msc_aeD3DDevType[D3DDEVICETYPE_NUM];
|
||||
};
|
||||
|
||||
class D3D_CAdapterInfo
|
||||
{
|
||||
public:
|
||||
D3D_CAdapterInfo() {}
|
||||
~D3D_CAdapterInfo() {}
|
||||
BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo);
|
||||
|
||||
BOOL Build(IDirect3D8& rkD3D, UINT iAdapter, PFNCONFIRMDEVICE pfnConfirmDevice);
|
||||
VOID GetString(std::string* pstEnumList);
|
||||
|
||||
D3DADAPTER_IDENTIFIER8& GetIdentifier()
|
||||
{
|
||||
return m_kD3DAdapterIdentifier;
|
||||
}
|
||||
|
||||
D3DDISPLAYMODE& GetDesktopD3DDisplayModer();
|
||||
D3DDISPLAYMODE* GetDesktopD3DDisplayModep();
|
||||
|
||||
D3D_CDeviceInfo* GetD3DDeviceInfop(UINT iD3DDevInfo);
|
||||
D3D_SModeInfo* GetD3DModeInfop(UINT iD3DDevInfo, UINT iD3DModeInfo);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
D3DDEVICEINFO_NUM = 5,
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
D3DADAPTER_IDENTIFIER8 m_kD3DAdapterIdentifier;
|
||||
D3DDISPLAYMODE m_kD3DDMDesktop;
|
||||
|
||||
UINT m_iCurD3DDevInfo;
|
||||
UINT m_uD3DDevInfoNum;
|
||||
D3D_CDeviceInfo m_akD3DDevInfo[D3DDEVICEINFO_NUM];
|
||||
|
||||
};
|
||||
|
||||
class D3D_CDisplayModeAutoDetector
|
||||
{
|
||||
public:
|
||||
D3D_CDisplayModeAutoDetector();
|
||||
~D3D_CDisplayModeAutoDetector();
|
||||
|
||||
BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo, UINT* piD3DAdapterInfo);
|
||||
BOOL Build(IDirect3D8& rkD3D, PFNCONFIRMDEVICE pfnConfirmDevice);
|
||||
|
||||
D3D_CAdapterInfo* GetD3DAdapterInfop(UINT iD3DAdapterInfo);
|
||||
D3D_SModeInfo* GetD3DModeInfop(UINT iD3DAdapterInfo, UINT iD3DDevInfo, UINT iD3DModeInfo);
|
||||
|
||||
VOID GetString(std::string* pstEnumList);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
D3DADAPTERINFO_NUM = 10,
|
||||
};
|
||||
|
||||
protected:
|
||||
D3D_CAdapterInfo m_akD3DAdapterInfo[D3DADAPTERINFO_NUM];
|
||||
UINT m_uD3DAdapterInfoCount;
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpBase.h"
|
||||
#include "GrpDetector.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
class CGraphicDevice : public CGraphicBase
|
||||
{
|
||||
public:
|
||||
enum EDeviceState
|
||||
{
|
||||
DEVICESTATE_OK,
|
||||
DEVICESTATE_BROKEN,
|
||||
DEVICESTATE_NEEDS_RESET,
|
||||
DEVICESTATE_NULL
|
||||
};
|
||||
|
||||
enum ECreateReturnValues
|
||||
{
|
||||
CREATE_OK = (1 << 0),
|
||||
CREATE_NO_DIRECTX = (1 << 1),
|
||||
CREATE_GET_DEVICE_CAPS = (1 << 2),
|
||||
CREATE_GET_DEVICE_CAPS2 = (1 << 3),
|
||||
CREATE_DEVICE = (1 << 4),
|
||||
CREATE_REFRESHRATE = (1 << 5),
|
||||
CREATE_ENUM = (1 << 6), // 2003. 01. 09. myevan 모드 리스트 얻기 실패
|
||||
CREATE_DETECT = (1 << 7), // 2003. 01. 09. myevan 모드 선택 실패
|
||||
CREATE_NO_TNL = (1 << 8),
|
||||
CREATE_BAD_DRIVER = (1 << 9),
|
||||
CREATE_FORMAT = (1 << 10),
|
||||
};
|
||||
|
||||
CGraphicDevice();
|
||||
virtual ~CGraphicDevice();
|
||||
|
||||
void InitBackBufferCount(UINT uBackBufferCount);
|
||||
|
||||
void Destroy();
|
||||
int Create(HWND hWnd, int hres, int vres, bool Windowed = true, int bit = 32, int ReflashRate = 0);
|
||||
|
||||
EDeviceState GetDeviceState();
|
||||
bool Reset();
|
||||
|
||||
void EnableWebBrowserMode(const RECT& c_rcWebPage);
|
||||
void DisableWebBrowserMode();
|
||||
void MoveWebBrowserRect(const RECT& c_rcWebPage);
|
||||
|
||||
bool ResizeBackBuffer(UINT uWidth, UINT uHeight);
|
||||
void RegisterWarningString(UINT uiMsg, const char * c_szString);
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
bool __IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo);
|
||||
void __WarningMessage(HWND hWnd, UINT uiMsg);
|
||||
|
||||
void __InitializeDefaultIndexBufferList();
|
||||
void __DestroyDefaultIndexBufferList();
|
||||
bool __CreateDefaultIndexBufferList();
|
||||
bool __CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices);
|
||||
|
||||
void __InitializePDTVertexBufferList();
|
||||
void __DestroyPDTVertexBufferList();
|
||||
bool __CreatePDTVertexBufferList();
|
||||
|
||||
DWORD CreatePTStreamVertexShader();
|
||||
DWORD CreatePNTStreamVertexShader();
|
||||
DWORD CreatePNT2StreamVertexShader();
|
||||
DWORD CreateDoublePNTStreamVertexShader();
|
||||
|
||||
protected:
|
||||
DWORD m_uBackBufferCount;
|
||||
std::map<UINT, std::string> m_kMap_strWarningMessage;
|
||||
CStateManager* m_pStateManager;
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpImageInstance.h"
|
||||
|
||||
class CGraphicExpandedImageInstance : public CGraphicImageInstance
|
||||
{
|
||||
public:
|
||||
static DWORD Type();
|
||||
static void DeleteExpandedImageInstance(CGraphicExpandedImageInstance * pkInstance)
|
||||
{
|
||||
pkInstance->Destroy();
|
||||
ms_kPool.Free(pkInstance);
|
||||
}
|
||||
|
||||
enum ERenderingMode
|
||||
{
|
||||
RENDERING_MODE_NORMAL,
|
||||
RENDERING_MODE_SCREEN,
|
||||
RENDERING_MODE_COLOR_DODGE,
|
||||
RENDERING_MODE_MODULATE,
|
||||
};
|
||||
|
||||
public:
|
||||
CGraphicExpandedImageInstance();
|
||||
virtual ~CGraphicExpandedImageInstance();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void SetDepth(float fDepth);
|
||||
void SetOrigin();
|
||||
void SetOrigin(float fx, float fy);
|
||||
void SetRotation(float fRotation);
|
||||
void SetScale(float fx, float fy);
|
||||
void SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom);
|
||||
void SetRenderingMode(int iMode);
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
void OnRender();
|
||||
void OnSetImagePointer();
|
||||
|
||||
BOOL OnIsType(DWORD dwType);
|
||||
|
||||
protected:
|
||||
float m_fDepth;
|
||||
D3DXVECTOR2 m_v2Origin;
|
||||
D3DXVECTOR2 m_v2Scale;
|
||||
float m_fRotation;
|
||||
RECT m_RenderingRect;
|
||||
int m_iRenderingMode;
|
||||
|
||||
public:
|
||||
static void CreateSystem(UINT uCapacity);
|
||||
static void DestroySystem();
|
||||
|
||||
static CGraphicExpandedImageInstance* New();
|
||||
static void Delete(CGraphicExpandedImageInstance* pkImgInst);
|
||||
|
||||
static CDynamicPool<CGraphicExpandedImageInstance> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpTexture.h"
|
||||
#include "GrpImageTexture.h"
|
||||
#include "GrpDIB.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class CGraphicFontTexture : public CGraphicTexture
|
||||
{
|
||||
public:
|
||||
typedef std::pair<WORD,wchar_t> TCharacterKey;
|
||||
|
||||
typedef struct SCharacterInfomation
|
||||
{
|
||||
short index;
|
||||
short width;
|
||||
short height;
|
||||
float left;
|
||||
float top;
|
||||
float right;
|
||||
float bottom;
|
||||
float advance;
|
||||
} TCharacterInfomation;
|
||||
|
||||
typedef std::vector<TCharacterInfomation*> TPCharacterInfomationVector;
|
||||
|
||||
public:
|
||||
CGraphicFontTexture();
|
||||
virtual ~CGraphicFontTexture();
|
||||
|
||||
void Destroy();
|
||||
bool Create(const char* c_szFontName, int fontSize, bool bItalic);
|
||||
|
||||
bool CreateDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
bool CheckTextureIndex(DWORD dwTexture);
|
||||
void SelectTexture(DWORD dwTexture);
|
||||
|
||||
bool UpdateTexture();
|
||||
|
||||
TCharacterInfomation* GetCharacterInfomation(WORD codePage, wchar_t keyValue);
|
||||
TCharacterInfomation* UpdateCharacterInfomation(TCharacterKey code);
|
||||
|
||||
bool IsEmpty() const;
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
bool AppendTexture();
|
||||
|
||||
HFONT GetFont(WORD codePage);
|
||||
|
||||
protected:
|
||||
typedef std::vector<CGraphicImageTexture*> TGraphicImageTexturePointerVector;
|
||||
typedef std::map<TCharacterKey, TCharacterInfomation> TCharacterInfomationMap;
|
||||
typedef std::map<WORD, HFONT> TFontMap;
|
||||
|
||||
protected:
|
||||
CGraphicDib m_dib;
|
||||
|
||||
HFONT m_hFontOld;
|
||||
HFONT m_hFont;
|
||||
|
||||
TGraphicImageTexturePointerVector m_pFontTextureVector;
|
||||
|
||||
TCharacterInfomationMap m_charInfoMap;
|
||||
|
||||
TFontMap m_fontMap;
|
||||
|
||||
int m_x;
|
||||
int m_y;
|
||||
int m_step;
|
||||
bool m_isDirty;
|
||||
|
||||
TCHAR m_fontName[LF_FACESIZE];
|
||||
LONG m_fontSize;
|
||||
bool m_bItalic;
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef __INC_GRPIMAGE_H__
|
||||
#define __INC_GRPIMAGE_H__
|
||||
|
||||
#include "Ref.h"
|
||||
#include "Resource.h"
|
||||
#include "GrpImageTexture.h"
|
||||
|
||||
class CGraphicImage : public CResource
|
||||
{
|
||||
public:
|
||||
typedef CRef<CGraphicImage> TRef;
|
||||
|
||||
public:
|
||||
static TType Type();
|
||||
|
||||
public:
|
||||
CGraphicImage(const char* c_szFileName, DWORD dwFilter = D3DX_FILTER_LINEAR);
|
||||
virtual ~CGraphicImage();
|
||||
|
||||
virtual bool CreateDeviceObjects();
|
||||
virtual void DestroyDeviceObjects();
|
||||
|
||||
int GetWidth() const;
|
||||
int GetHeight() const;
|
||||
|
||||
const RECT & GetRectReference() const;
|
||||
|
||||
const CGraphicTexture & GetTextureReference() const;
|
||||
CGraphicTexture * GetTexturePointer();
|
||||
|
||||
protected:
|
||||
bool OnLoad(int iSize, const void * c_pvBuf);
|
||||
|
||||
void OnClear();
|
||||
bool OnIsEmpty() const;
|
||||
bool OnIsType(TType type);
|
||||
|
||||
protected:
|
||||
CGraphicImageTexture m_imageTexture;
|
||||
RECT m_rect;
|
||||
DWORD m_dwFilter;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpImage.h"
|
||||
#include "GrpIndexBuffer.h"
|
||||
#include "GrpVertexBufferDynamic.h"
|
||||
#include "Pool.h"
|
||||
|
||||
class CGraphicImageInstance
|
||||
{
|
||||
public:
|
||||
static DWORD Type();
|
||||
BOOL IsType(DWORD dwType);
|
||||
|
||||
public:
|
||||
CGraphicImageInstance();
|
||||
virtual ~CGraphicImageInstance();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void Render();
|
||||
|
||||
void SetDiffuseColor(float fr, float fg, float fb, float fa);
|
||||
void SetPosition(float fx, float fy);
|
||||
|
||||
void SetImagePointer(CGraphicImage* pImage);
|
||||
void ReloadImagePointer(CGraphicImage* pImage);
|
||||
bool IsEmpty() const;
|
||||
|
||||
int GetWidth();
|
||||
int GetHeight();
|
||||
|
||||
CGraphicTexture * GetTexturePointer();
|
||||
const CGraphicTexture & GetTextureReference() const;
|
||||
CGraphicImage * GetGraphicImagePointer();
|
||||
|
||||
bool operator == (const CGraphicImageInstance & rhs) const;
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
virtual void OnRender();
|
||||
virtual void OnSetImagePointer();
|
||||
|
||||
virtual BOOL OnIsType(DWORD dwType);
|
||||
|
||||
protected:
|
||||
D3DXCOLOR m_DiffuseColor;
|
||||
D3DXVECTOR2 m_v2Position;
|
||||
|
||||
CGraphicImage::TRef m_roImage;
|
||||
|
||||
public:
|
||||
static void CreateSystem(UINT uCapacity);
|
||||
static void DestroySystem();
|
||||
|
||||
static CGraphicImageInstance* New();
|
||||
static void Delete(CGraphicImageInstance* pkImgInst);
|
||||
|
||||
static CDynamicPool<CGraphicImageInstance> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpTexture.h"
|
||||
#include "../EterImageLib/DXTCImage.h"
|
||||
|
||||
class CGraphicImageTexture : public CGraphicTexture
|
||||
{
|
||||
public:
|
||||
CGraphicImageTexture();
|
||||
virtual ~CGraphicImageTexture();
|
||||
|
||||
void Destroy();
|
||||
|
||||
bool Create(UINT width, UINT height, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR);
|
||||
bool CreateDeviceObjects();
|
||||
|
||||
void CreateFromTexturePointer(const CGraphicTexture* c_pSrcTexture);
|
||||
bool CreateFromDiskFile(const char* c_szFileName, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR);
|
||||
bool CreateFromMemoryFile(UINT bufSize, const void* c_pvBuf, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR);
|
||||
bool CreateDDSTexture(CDXTCImage & image, const BYTE * c_pbBuf);
|
||||
|
||||
void SetFileName(const char * c_szFileName);
|
||||
|
||||
bool Lock(int* pRetPitch, void** ppRetPixels, int level=0);
|
||||
void Unlock(int level=0);
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
D3DFORMAT m_d3dFmt;
|
||||
DWORD m_dwFilter;
|
||||
|
||||
std::string m_stFileName;
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpBase.h"
|
||||
|
||||
class CGraphicIndexBuffer : public CGraphicBase
|
||||
{
|
||||
public:
|
||||
CGraphicIndexBuffer();
|
||||
virtual ~CGraphicIndexBuffer();
|
||||
|
||||
void Destroy();
|
||||
bool Create(int idxCount, D3DFORMAT d3dFmt);
|
||||
bool Create(int faceCount, TFace* faces);
|
||||
|
||||
bool CreateDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
bool Copy(int bufSize, const void* srcIndices);
|
||||
|
||||
bool Lock(void** pretIndices) const;
|
||||
void Unlock() const;
|
||||
|
||||
bool Lock(void** pretIndices);
|
||||
void Unlock();
|
||||
|
||||
void SetIndices(int startIndex=0) const;
|
||||
|
||||
LPDIRECT3DINDEXBUFFER8 GetD3DIndexBuffer() const;
|
||||
|
||||
int GetIndexCount() const {return m_iidxCount;}
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
LPDIRECT3DINDEXBUFFER8 m_lpd3dIdxBuf;
|
||||
DWORD m_dwBufferSize;
|
||||
D3DFORMAT m_d3dFmt;
|
||||
int m_iidxCount;
|
||||
};
|
||||
@@ -0,0 +1,345 @@
|
||||
#include "StdAfx.h"
|
||||
#include <algorithm>
|
||||
#include "../EterBase/Timer.h"
|
||||
|
||||
#include "GrpLightManager.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
float CLightBase::ms_fCurTime = 0.0f;
|
||||
|
||||
CLightManager::CLightManager()
|
||||
{
|
||||
m_v3CenterPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_dwLimitLightCount = LIGHT_LIMIT_DEFAULT;
|
||||
}
|
||||
|
||||
CLightManager::~CLightManager()
|
||||
{
|
||||
}
|
||||
|
||||
void CLightManager::Destroy()
|
||||
{
|
||||
m_LightPool.Destroy();
|
||||
}
|
||||
|
||||
void CLightManager::Initialize()
|
||||
{
|
||||
SetSkipIndex(1);
|
||||
|
||||
m_NonUsingLightIDDeque.clear();
|
||||
|
||||
m_LightMap.clear();
|
||||
m_LightPool.FreeAll();
|
||||
}
|
||||
|
||||
void CLightManager::RegisterLight(ELightType /*LightType*/, TLightID * poutLightID, D3DLIGHT8 & LightData)
|
||||
{
|
||||
CLight * pLight = m_LightPool.Alloc();
|
||||
TLightID ID = NewLightID();
|
||||
pLight->SetParameter(ID, LightData);
|
||||
m_LightMap[ID] = pLight;
|
||||
*poutLightID = ID;
|
||||
}
|
||||
|
||||
void CLightManager::DeleteLight(TLightID LightID)
|
||||
{
|
||||
TLightMap::iterator itor = m_LightMap.find(LightID);
|
||||
|
||||
if (m_LightMap.end() == itor)
|
||||
{
|
||||
assert(!"CLightManager::DeleteLight - Failed to find light ID!");
|
||||
return;
|
||||
}
|
||||
|
||||
CLight * pLight = itor->second;
|
||||
|
||||
pLight->Clear();
|
||||
m_LightPool.Free(pLight);
|
||||
|
||||
m_LightMap.erase(itor);
|
||||
|
||||
ReleaseLightID(LightID);
|
||||
}
|
||||
|
||||
CLight * CLightManager::GetLight(TLightID LightID)
|
||||
{
|
||||
TLightMap::iterator itor = m_LightMap.find(LightID);
|
||||
|
||||
if (m_LightMap.end() == itor)
|
||||
{
|
||||
assert(!"CLightManager::SetLightData - Failed to find light ID!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
void CLightManager::SetCenterPosition(const D3DXVECTOR3 & c_rv3Position)
|
||||
{
|
||||
m_v3CenterPosition = c_rv3Position;
|
||||
}
|
||||
|
||||
void CLightManager::SetLimitLightCount(DWORD dwLightCount)
|
||||
{
|
||||
m_dwLimitLightCount = dwLightCount;
|
||||
}
|
||||
|
||||
void CLightManager::SetSkipIndex(DWORD dwSkipIndex)
|
||||
{
|
||||
m_dwSkipIndex = dwSkipIndex;
|
||||
}
|
||||
|
||||
struct LightComp
|
||||
{
|
||||
bool operator () (const CLight * l, const CLight * r) const
|
||||
{
|
||||
return l->GetDistance() < r->GetDistance();
|
||||
}
|
||||
};
|
||||
|
||||
// NOTE : FlushLight후 렌더링
|
||||
// 그 후 반드시 RestoreLight를 해줘야만 한다.
|
||||
void CLightManager::FlushLight()
|
||||
{
|
||||
Update();
|
||||
|
||||
m_LightSortVector.clear();
|
||||
|
||||
// NOTE: Dynamic과 Static을 분리 시키고 CenterPosition이 바뀔때마다 Static만
|
||||
// 다시 Flush 하는 식으로 최적화 할 수 있다. - [levites]
|
||||
|
||||
// light들의 거리를 추출해 정렬한다.
|
||||
TLightMap::iterator itor = m_LightMap.begin();
|
||||
|
||||
for (; itor != m_LightMap.end(); ++itor)
|
||||
{
|
||||
CLight * pLight = itor->second;
|
||||
|
||||
D3DXVECTOR3 v3LightPos(pLight->GetPosition());
|
||||
D3DXVECTOR3 v3Distance(v3LightPos - m_v3CenterPosition);
|
||||
pLight->SetDistance(D3DXVec3Length(&v3Distance));
|
||||
m_LightSortVector.push_back(pLight);
|
||||
}
|
||||
|
||||
// quick sort lights
|
||||
std::sort(m_LightSortVector.begin(), m_LightSortVector.end(), LightComp());
|
||||
|
||||
// NOTE - 거리로 정렬된 라이트를 Limit 갯수 만큼 제한해서 켜준다.
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE);
|
||||
|
||||
for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k)
|
||||
{
|
||||
m_LightSortVector[k]->Update();
|
||||
m_LightSortVector[k]->SetDeviceLight(TRUE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CLightManager::RestoreLight()
|
||||
{
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
|
||||
|
||||
for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k)
|
||||
m_LightSortVector[k]->SetDeviceLight(FALSE);
|
||||
}
|
||||
|
||||
TLightID CLightManager::NewLightID()
|
||||
{
|
||||
if (!m_NonUsingLightIDDeque.empty())
|
||||
{
|
||||
TLightID id = m_NonUsingLightIDDeque.back();
|
||||
m_NonUsingLightIDDeque.pop_back();
|
||||
return (id);
|
||||
}
|
||||
|
||||
return m_dwSkipIndex + m_LightMap.size();
|
||||
}
|
||||
|
||||
void CLightManager::ReleaseLightID(TLightID LightID)
|
||||
{
|
||||
m_NonUsingLightIDDeque.push_back(LightID);
|
||||
}
|
||||
|
||||
void CLightManager::Update()
|
||||
{
|
||||
//static DWORD s_dwStartTime = ELTimer_GetMSec();
|
||||
//ms_fCurTime = float(ELTimer_GetMSec() - s_dwStartTime) / 1000.0f;
|
||||
ms_fCurTime = CTimer::Instance().GetCurrentSecond();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CLight::CLight()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CLight::~CLight()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CLight::Initialize()
|
||||
{
|
||||
m_LightID = 0;
|
||||
m_isEdited = TRUE;
|
||||
m_fDistance = 0.0f;
|
||||
|
||||
memset(&m_d3dLight, 0, sizeof(m_d3dLight));
|
||||
|
||||
m_d3dLight.Type = D3DLIGHT_POINT;
|
||||
m_d3dLight.Attenuation0 = 0.0f;
|
||||
m_d3dLight.Attenuation1 = 1.0f;
|
||||
m_d3dLight.Attenuation2 = 0.0f;
|
||||
}
|
||||
|
||||
void CLight::Clear()
|
||||
{
|
||||
if (m_LightID)
|
||||
SetDeviceLight(FALSE);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void CLight::SetDeviceLight(BOOL bActive)
|
||||
{
|
||||
if (bActive && m_isEdited)
|
||||
{
|
||||
if (ms_lpd3dDevice)
|
||||
ms_lpd3dDevice->SetLight(m_LightID, &m_d3dLight);
|
||||
}
|
||||
if (ms_lpd3dDevice)
|
||||
{
|
||||
ms_lpd3dDevice->LightEnable(m_LightID, bActive);
|
||||
}
|
||||
}
|
||||
|
||||
void CLight::SetParameter(TLightID id, const D3DLIGHT8 & c_rLight)
|
||||
{
|
||||
m_LightID = id;
|
||||
m_d3dLight = c_rLight;
|
||||
}
|
||||
|
||||
void CLight::SetDiffuseColor(float fr, float fg, float fb, float fa)
|
||||
{
|
||||
if (m_d3dLight.Diffuse.r == fr
|
||||
&& m_d3dLight.Diffuse.g == fg
|
||||
&& m_d3dLight.Diffuse.b == fb
|
||||
&& m_d3dLight.Diffuse.a == fa
|
||||
)
|
||||
return;
|
||||
m_d3dLight.Diffuse.r = fr;
|
||||
m_d3dLight.Diffuse.g = fg;
|
||||
m_d3dLight.Diffuse.b = fb;
|
||||
m_d3dLight.Diffuse.a = fa;
|
||||
m_isEdited = TRUE;
|
||||
}
|
||||
|
||||
void CLight::SetAmbientColor(float fr, float fg, float fb, float fa)
|
||||
{
|
||||
if (m_d3dLight.Ambient.r == fr
|
||||
&& m_d3dLight.Ambient.g == fg
|
||||
&& m_d3dLight.Ambient.b == fb
|
||||
&& m_d3dLight.Ambient.a == fa
|
||||
)
|
||||
return;
|
||||
m_d3dLight.Ambient.r = fr;
|
||||
m_d3dLight.Ambient.g = fg;
|
||||
m_d3dLight.Ambient.b = fb;
|
||||
m_d3dLight.Ambient.a = fa;
|
||||
m_isEdited = TRUE;
|
||||
}
|
||||
|
||||
void CLight::SetRange(float fRange)
|
||||
{
|
||||
if (m_d3dLight.Range == fRange)
|
||||
return;
|
||||
|
||||
m_d3dLight.Range = fRange;
|
||||
m_isEdited = TRUE;
|
||||
}
|
||||
|
||||
const D3DVECTOR & CLight::GetPosition() const
|
||||
{
|
||||
return m_d3dLight.Position;
|
||||
}
|
||||
|
||||
void CLight::SetPosition(float fx, float fy, float fz)
|
||||
{
|
||||
if (m_d3dLight.Position.x == fx && m_d3dLight.Position.y == fy && m_d3dLight.Position.z == fz)
|
||||
return;
|
||||
|
||||
m_d3dLight.Position.x = fx;
|
||||
m_d3dLight.Position.y = fy;
|
||||
m_d3dLight.Position.z = fz;
|
||||
m_isEdited = TRUE;
|
||||
}
|
||||
|
||||
void CLight::SetDistance(float fDistance)
|
||||
{
|
||||
m_fDistance = fDistance;
|
||||
}
|
||||
|
||||
void CLight::BlendDiffuseColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime)
|
||||
{
|
||||
D3DXCOLOR Color(m_d3dLight.Diffuse);
|
||||
m_DiffuseColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime);
|
||||
}
|
||||
|
||||
void CLight::BlendAmbientColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime)
|
||||
{
|
||||
D3DXCOLOR Color(m_d3dLight.Ambient);
|
||||
m_AmbientColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime);
|
||||
}
|
||||
|
||||
void CLight::BlendRange(float fRange, float fBlendTime, float fDelayTime)
|
||||
{
|
||||
m_RangeTransitor.SetTransition(m_d3dLight.Range, fRange, ms_fCurTime + fDelayTime, fBlendTime);
|
||||
}
|
||||
|
||||
void CLight::Update()
|
||||
{
|
||||
if (m_AmbientColorTransitor.isActiveTime(ms_fCurTime))
|
||||
{
|
||||
if (!m_AmbientColorTransitor.isActive())
|
||||
{
|
||||
m_AmbientColorTransitor.SetActive();
|
||||
m_AmbientColorTransitor.SetSourceValue(m_d3dLight.Ambient);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DXCOLOR Color;
|
||||
|
||||
m_AmbientColorTransitor.GetValue(ms_fCurTime, &Color);
|
||||
SetAmbientColor(Color.r, Color.g, Color.b, Color.a);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_DiffuseColorTransitor.isActiveTime(ms_fCurTime))
|
||||
{
|
||||
if (!m_DiffuseColorTransitor.isActive())
|
||||
{
|
||||
m_DiffuseColorTransitor.SetActive();
|
||||
m_DiffuseColorTransitor.SetSourceValue(m_d3dLight.Diffuse);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DXCOLOR Color;
|
||||
m_DiffuseColorTransitor.GetValue(ms_fCurTime, &Color);
|
||||
SetDiffuseColor(Color.r, Color.g, Color.b, Color.a);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_RangeTransitor.isActiveTime(ms_fCurTime))
|
||||
{
|
||||
if (!m_RangeTransitor.isActive())
|
||||
{
|
||||
m_RangeTransitor.SetActive();
|
||||
m_RangeTransitor.SetSourceValue(m_d3dLight.Range);
|
||||
}
|
||||
else
|
||||
{
|
||||
float fRange;
|
||||
m_RangeTransitor.GetValue(ms_fCurTime, &fRange);
|
||||
SetRange(fRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EterBase/Singleton.h"
|
||||
|
||||
#include "GrpBase.h"
|
||||
#include "Util.h"
|
||||
#include "Pool.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
typedef DWORD TLightID;
|
||||
|
||||
enum ELightType
|
||||
{
|
||||
LIGHT_TYPE_STATIC, // Continuously turning on light
|
||||
LIGHT_TYPE_DYNAMIC, // Immediately turning off light
|
||||
};
|
||||
|
||||
class CLightBase
|
||||
{
|
||||
public:
|
||||
CLightBase() {};
|
||||
virtual ~CLightBase() {};
|
||||
|
||||
void SetCurrentTime();
|
||||
|
||||
protected:
|
||||
static float ms_fCurTime;
|
||||
};
|
||||
|
||||
class CLight : public CGraphicBase, public CLightBase
|
||||
{
|
||||
public:
|
||||
CLight();
|
||||
virtual ~CLight();
|
||||
|
||||
void Initialize();
|
||||
void Clear();
|
||||
|
||||
void Update();
|
||||
|
||||
void SetParameter(TLightID id, const D3DLIGHT8 & c_rLight);
|
||||
|
||||
void SetDistance(float fDistance);
|
||||
float GetDistance() const { return m_fDistance; }
|
||||
|
||||
TLightID GetLightID() { return m_LightID; }
|
||||
|
||||
BOOL isEdited() { return m_isEdited; }
|
||||
void SetDeviceLight(BOOL bActive);
|
||||
|
||||
void SetDiffuseColor(float fr, float fg, float fb, float fa = 1.0f);
|
||||
void SetAmbientColor(float fr, float fg, float fb, float fa = 1.0f);
|
||||
void SetRange(float fRange);
|
||||
void SetPosition(float fx, float fy, float fz);
|
||||
|
||||
const D3DVECTOR & GetPosition() const;
|
||||
|
||||
void BlendDiffuseColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime = 0.0f);
|
||||
void BlendAmbientColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime = 0.0f);
|
||||
void BlendRange(float fRange, float fBlendTime, float fDelayTime = 0.0f);
|
||||
|
||||
private:
|
||||
TLightID m_LightID; // Light ID. equal to D3D light index
|
||||
|
||||
D3DLIGHT8 m_d3dLight;
|
||||
BOOL m_isEdited;
|
||||
float m_fDistance;
|
||||
|
||||
TTransitorColor m_DiffuseColorTransitor;
|
||||
TTransitorColor m_AmbientColorTransitor;
|
||||
TTransitorFloat m_RangeTransitor;
|
||||
};
|
||||
|
||||
class CLightManager : public CGraphicBase, public CLightBase, public CSingleton<CLightManager>
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
LIGHT_LIMIT_DEFAULT = 3,
|
||||
// LIGHT_MAX_NUM = 32,
|
||||
};
|
||||
|
||||
typedef std::deque<TLightID> TLightIDDeque;
|
||||
typedef std::map<TLightID, CLight *> TLightMap;
|
||||
typedef std::vector<CLight *> TLightSortVector;
|
||||
|
||||
public:
|
||||
CLightManager();
|
||||
virtual ~CLightManager();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void Initialize();
|
||||
|
||||
// NOTE : FlushLight후 렌더링
|
||||
// 그 후 반드시 RestoreLight를 해줘야만 한다.
|
||||
void Update();
|
||||
void FlushLight();
|
||||
void RestoreLight();
|
||||
|
||||
/////
|
||||
void RegisterLight(ELightType LightType, TLightID * poutLightID, D3DLIGHT8 & LightData);
|
||||
CLight * GetLight(TLightID LightID);
|
||||
void DeleteLight(TLightID LightID);
|
||||
/////
|
||||
|
||||
void SetCenterPosition(const D3DXVECTOR3 & c_rv3Position);
|
||||
void SetLimitLightCount(DWORD dwLightCount);
|
||||
void SetSkipIndex(DWORD dwSkipIndex);
|
||||
|
||||
protected:
|
||||
TLightIDDeque m_NonUsingLightIDDeque;
|
||||
|
||||
TLightMap m_LightMap;
|
||||
TLightSortVector m_LightSortVector;
|
||||
|
||||
D3DXVECTOR3 m_v3CenterPosition;
|
||||
DWORD m_dwLimitLightCount;
|
||||
DWORD m_dwSkipIndex;
|
||||
|
||||
protected:
|
||||
TLightID NewLightID();
|
||||
void ReleaseLightID(TLightID LightID);
|
||||
|
||||
CDynamicPool<CLight> m_LightPool;
|
||||
};
|
||||
@@ -0,0 +1,256 @@
|
||||
#include "StdAfx.h"
|
||||
#include "GrpMarkInstance.h"
|
||||
#include "StateManager.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
#include "../EterBase/CRC32.h"
|
||||
|
||||
CDynamicPool<CGraphicMarkInstance> CGraphicMarkInstance::ms_kPool;
|
||||
|
||||
void CGraphicMarkInstance::SetImageFileName(const char* c_szFileName)
|
||||
{
|
||||
m_stImageFileName = c_szFileName;
|
||||
}
|
||||
|
||||
const std::string& CGraphicMarkInstance::GetImageFileName()
|
||||
{
|
||||
return m_stImageFileName;
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::CreateSystem(UINT uCapacity)
|
||||
{
|
||||
ms_kPool.Create(uCapacity);
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
}
|
||||
|
||||
CGraphicMarkInstance* CGraphicMarkInstance::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::Delete(CGraphicMarkInstance* pkImgInst)
|
||||
{
|
||||
pkImgInst->Destroy();
|
||||
ms_kPool.Free(pkImgInst);
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::Render()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
assert(!IsEmpty());
|
||||
|
||||
OnRender();
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::OnRender()
|
||||
{
|
||||
CGraphicImage * pImage = m_roImage.GetPointer();
|
||||
CGraphicTexture * pTexture = pImage->GetTexturePointer();
|
||||
|
||||
UINT uColCount = pImage->GetWidth() / MARK_WIDTH;
|
||||
|
||||
if (uColCount == 0)
|
||||
return;
|
||||
|
||||
UINT uCol = m_uIndex % uColCount;
|
||||
UINT uRow = m_uIndex / uColCount;
|
||||
|
||||
RECT kRect;
|
||||
kRect.left=uCol*MARK_WIDTH;
|
||||
kRect.top=uRow*MARK_HEIGHT;
|
||||
kRect.right=kRect.left+MARK_WIDTH;
|
||||
kRect.bottom=kRect.top+MARK_HEIGHT;
|
||||
|
||||
float texReverseWidth = 1.0f / float(pTexture->GetWidth());
|
||||
float texReverseHeight = 1.0f / float(pTexture->GetHeight());
|
||||
float su = kRect.left * texReverseWidth;
|
||||
float sv = kRect.top * texReverseHeight;
|
||||
float eu = kRect.right * texReverseWidth;
|
||||
float ev = kRect.bottom * texReverseHeight;
|
||||
|
||||
float fRenderWidth=static_cast<float>(MARK_WIDTH)*m_fScale;
|
||||
float fRenderHeight= static_cast<float>(MARK_HEIGHT)*m_fScale;
|
||||
|
||||
TPDTVertex vertices[4];
|
||||
vertices[0].position.x = m_v2Position.x-0.5f;
|
||||
vertices[0].position.y = m_v2Position.y-0.5f;
|
||||
vertices[0].position.z = 0.0f;
|
||||
vertices[0].texCoord = TTextureCoordinate(su, sv);
|
||||
vertices[0].diffuse = m_DiffuseColor;
|
||||
|
||||
vertices[1].position.x = m_v2Position.x + fRenderWidth -0.5f;
|
||||
vertices[1].position.y = m_v2Position.y-0.5f;
|
||||
vertices[1].position.z = 0.0f;
|
||||
vertices[1].texCoord = TTextureCoordinate(eu, sv);
|
||||
vertices[1].diffuse = m_DiffuseColor;
|
||||
|
||||
vertices[2].position.x = m_v2Position.x-0.5f;
|
||||
vertices[2].position.y = m_v2Position.y + fRenderHeight -0.5f;
|
||||
vertices[2].position.z = 0.0f;
|
||||
vertices[2].texCoord = TTextureCoordinate(su, ev);
|
||||
vertices[2].diffuse = m_DiffuseColor;
|
||||
|
||||
vertices[3].position.x = m_v2Position.x + fRenderWidth -0.5f;
|
||||
vertices[3].position.y = m_v2Position.y + fRenderHeight -0.5f;
|
||||
vertices[3].position.z = 0.0f;
|
||||
vertices[3].texCoord = TTextureCoordinate(eu, ev);
|
||||
vertices[3].diffuse = m_DiffuseColor;
|
||||
|
||||
if (CGraphicBase::SetPDTStream(vertices, 4))
|
||||
{
|
||||
CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT);
|
||||
|
||||
STATEMANAGER.SetTexture(0, pTexture->GetD3DTexture());
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
|
||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2);
|
||||
//OLD: STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex));
|
||||
}
|
||||
}
|
||||
|
||||
const CGraphicTexture & CGraphicMarkInstance::GetTextureReference() const
|
||||
{
|
||||
return m_roImage->GetTextureReference();
|
||||
}
|
||||
|
||||
CGraphicTexture * CGraphicMarkInstance::GetTexturePointer()
|
||||
{
|
||||
return m_roImage->GetTexturePointer();
|
||||
}
|
||||
|
||||
CGraphicImage * CGraphicMarkInstance::GetGraphicImagePointer()
|
||||
{
|
||||
return m_roImage.GetPointer();
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::SetScale(float fScale)
|
||||
{
|
||||
m_fScale=fScale;
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::SetIndex(UINT uIndex)
|
||||
{
|
||||
m_uIndex=uIndex;
|
||||
}
|
||||
|
||||
int CGraphicMarkInstance::GetWidth()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return 0;
|
||||
|
||||
//return m_roImage->GetWidth();
|
||||
return 16;
|
||||
}
|
||||
|
||||
int CGraphicMarkInstance::GetHeight()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return 0;
|
||||
|
||||
//return m_roImage->GetHeight();
|
||||
return 12;
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::SetDiffuseColor(float fr, float fg, float fb, float fa)
|
||||
{
|
||||
m_DiffuseColor.r = fr;
|
||||
m_DiffuseColor.g = fg;
|
||||
m_DiffuseColor.b = fb;
|
||||
m_DiffuseColor.a = fa;
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::SetPosition(float fx, float fy)
|
||||
{
|
||||
m_v2Position.x = fx;
|
||||
m_v2Position.y = fy;
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::Load()
|
||||
{
|
||||
if (GetImageFileName().empty())
|
||||
return;
|
||||
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer(GetImageFileName().c_str());
|
||||
|
||||
if (!pResource)
|
||||
{
|
||||
TraceError("CGraphicMarkinstance::Load - [%s] NOT EXIST", GetImageFileName().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pResource->IsType(CGraphicImage::Type()))
|
||||
SetImagePointer(static_cast<CGraphicImage*>(pResource));
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::SetImagePointer(CGraphicImage * pImage)
|
||||
{
|
||||
m_roImage.SetPointer(pImage);
|
||||
|
||||
OnSetImagePointer();
|
||||
}
|
||||
|
||||
bool CGraphicMarkInstance::IsEmpty() const
|
||||
{
|
||||
if (!m_roImage.IsNull() && !m_roImage->IsEmpty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicMarkInstance::operator == (const CGraphicMarkInstance & rhs) const
|
||||
{
|
||||
return (m_roImage.GetPointer() == rhs.m_roImage.GetPointer());
|
||||
}
|
||||
|
||||
DWORD CGraphicMarkInstance::Type()
|
||||
{
|
||||
static DWORD s_dwType = GetCRC32("CGraphicMarkInstance", strlen("CGraphicMarkInstance"));
|
||||
return (s_dwType);
|
||||
}
|
||||
|
||||
BOOL CGraphicMarkInstance::IsType(DWORD dwType)
|
||||
{
|
||||
return OnIsType(dwType);
|
||||
}
|
||||
|
||||
BOOL CGraphicMarkInstance::OnIsType(DWORD dwType)
|
||||
{
|
||||
if (CGraphicMarkInstance::Type() == dwType)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::OnSetImagePointer()
|
||||
{
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::Initialize()
|
||||
{
|
||||
m_DiffuseColor.r = m_DiffuseColor.g = m_DiffuseColor.b = m_DiffuseColor.a = 1.0f;
|
||||
m_v2Position.x = m_v2Position.y = 0.0f;
|
||||
m_uIndex = 0;
|
||||
m_fScale = 1.0f;
|
||||
}
|
||||
|
||||
void CGraphicMarkInstance::Destroy()
|
||||
{
|
||||
m_roImage.SetPointer(NULL); // CRef 에서 레퍼런스 카운트가 떨어져야 함.
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicMarkInstance::CGraphicMarkInstance()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicMarkInstance::~CGraphicMarkInstance()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpImage.h"
|
||||
#include "Pool.h"
|
||||
|
||||
class CGraphicMarkInstance
|
||||
{
|
||||
public:
|
||||
static DWORD Type();
|
||||
BOOL IsType(DWORD dwType);
|
||||
|
||||
void SetImageFileName(const char* c_szFileName);
|
||||
const std::string& GetImageFileName();
|
||||
|
||||
public:
|
||||
CGraphicMarkInstance();
|
||||
virtual ~CGraphicMarkInstance();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void Render();
|
||||
|
||||
void SetDepth(float fDepth);
|
||||
void SetDiffuseColor(float fr, float fg, float fb, float fa);
|
||||
void SetPosition(float fx, float fy);
|
||||
void SetIndex(UINT uIndex);
|
||||
void SetScale(float fScale);
|
||||
|
||||
void Load();
|
||||
bool IsEmpty() const;
|
||||
|
||||
int GetWidth();
|
||||
int GetHeight();
|
||||
|
||||
CGraphicTexture * GetTexturePointer();
|
||||
const CGraphicTexture & GetTextureReference() const;
|
||||
CGraphicImage * GetGraphicImagePointer();
|
||||
|
||||
bool operator == (const CGraphicMarkInstance & rhs) const;
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
MARK_WIDTH = 16,
|
||||
MARK_HEIGHT = 12,
|
||||
};
|
||||
|
||||
void Initialize();
|
||||
|
||||
virtual void OnRender();
|
||||
virtual void OnSetImagePointer();
|
||||
|
||||
virtual BOOL OnIsType(DWORD dwType);
|
||||
|
||||
void SetImagePointer(CGraphicImage * pImage);
|
||||
|
||||
protected:
|
||||
D3DXCOLOR m_DiffuseColor;
|
||||
D3DXVECTOR2 m_v2Position;
|
||||
|
||||
UINT m_uIndex;
|
||||
|
||||
FLOAT m_fScale;
|
||||
FLOAT m_fDepth;
|
||||
|
||||
CGraphicImage::TRef m_roImage;
|
||||
std::string m_stImageFileName;
|
||||
|
||||
public:
|
||||
static void CreateSystem(UINT uCapacity);
|
||||
static void DestroySystem();
|
||||
|
||||
static CGraphicMarkInstance* New();
|
||||
static void Delete(CGraphicMarkInstance* pkImgInst);
|
||||
|
||||
static CDynamicPool<CGraphicMarkInstance> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
float CrossProduct2D(float x1, float y1, float x2, float y2);
|
||||
|
||||
bool IsInTriangle2D(float ax, float ay, float bx, float by, float cx, float cy, float tx, float ty);
|
||||
|
||||
D3DXVECTOR3* D3DXVec3Rotation(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc, const D3DXQUATERNION* c_pqtRot);
|
||||
D3DXVECTOR3* D3DXVec3Translation(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc, const D3DXVECTOR3* c_pvtTrans);
|
||||
|
||||
void GetRotationFromMatrix(D3DXVECTOR3 * pRotation, const D3DXMATRIX * c_pMatrix);
|
||||
void GetPivotAndRotationFromMatrix(D3DXMATRIX * pMatrix, D3DXVECTOR3 * pPivot, D3DXVECTOR3 * pRotation);
|
||||
void ExtractMovement(D3DXMATRIX * pTargetMatrix, D3DXMATRIX * pSourceMatrix);
|
||||
|
||||
inline D3DXVECTOR3* D3DXVec3Blend(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc1, const D3DXVECTOR3* c_pvtSrc2, float d)
|
||||
{
|
||||
pvtOut->x=c_pvtSrc1->x+d*(c_pvtSrc2->x-c_pvtSrc1->x);
|
||||
pvtOut->y=c_pvtSrc1->y+d*(c_pvtSrc2->y-c_pvtSrc1->y);
|
||||
pvtOut->z=c_pvtSrc1->z+d*(c_pvtSrc2->z-c_pvtSrc1->z);
|
||||
|
||||
return pvtOut;
|
||||
}
|
||||
|
||||
inline D3DXQUATERNION* D3DXQuaternionBlend(D3DXQUATERNION* pqtOut, const D3DXQUATERNION* c_pqtSrc1, const D3DXQUATERNION* c_pqtSrc2, float d)
|
||||
{
|
||||
pqtOut->x=c_pqtSrc1->x+d*(c_pqtSrc2->x-c_pqtSrc1->x);
|
||||
pqtOut->y=c_pqtSrc1->y+d*(c_pqtSrc2->y-c_pqtSrc1->y);
|
||||
pqtOut->z=c_pqtSrc1->z+d*(c_pqtSrc2->z-c_pqtSrc1->z);
|
||||
pqtOut->w=c_pqtSrc1->w+d*(c_pqtSrc2->w-c_pqtSrc1->w);
|
||||
return pqtOut;
|
||||
}
|
||||
|
||||
inline float ClampDegree(float fDegree)
|
||||
{
|
||||
if (fDegree >= 360.0f)
|
||||
fDegree -= 360.0f;
|
||||
if (fDegree < 0.0f)
|
||||
fDegree += 360.0f;
|
||||
|
||||
return fDegree;
|
||||
}
|
||||
|
||||
inline float GetVector3Distance(const D3DXVECTOR3 & c_rv3Source, const D3DXVECTOR3 & c_rv3Target)
|
||||
{
|
||||
return (c_rv3Source.x-c_rv3Target.x)*(c_rv3Source.x-c_rv3Target.x) + (c_rv3Source.y-c_rv3Target.y)*(c_rv3Source.y-c_rv3Target.y);
|
||||
}
|
||||
|
||||
inline D3DXQUATERNION SafeRotationNormalizedArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo)
|
||||
{
|
||||
if (vFrom == vTo)
|
||||
return D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f);
|
||||
if (vFrom == -vTo)
|
||||
return D3DXQUATERNION(0.0f,0.0f,1.0f,0.0f);
|
||||
D3DXVECTOR3 c;
|
||||
D3DXVec3Cross(&c, &vFrom, &vTo);
|
||||
float d = D3DXVec3Dot(&vFrom, &vTo);
|
||||
float s = sqrtf((1+d)*2);
|
||||
|
||||
return D3DXQUATERNION(c.x/s,c.y/s,c.z/s,s*0.5f);
|
||||
}
|
||||
|
||||
inline D3DXQUATERNION RotationNormalizedArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo)
|
||||
|
||||
{
|
||||
D3DXVECTOR3 c;
|
||||
D3DXVec3Cross(&c, &vFrom, &vTo);
|
||||
float d = D3DXVec3Dot(&vFrom, &vTo);
|
||||
float s = sqrtf((1+d)*2);
|
||||
|
||||
return D3DXQUATERNION(c.x/s,c.y/s,c.z/s,s*0.5f);
|
||||
}
|
||||
|
||||
inline D3DXQUATERNION RotationArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo)
|
||||
{
|
||||
D3DXVECTOR3 vnFrom, vnTo;
|
||||
D3DXVec3Normalize(&vnFrom, &vFrom);
|
||||
D3DXVec3Normalize(&vnTo, &vTo);
|
||||
return RotationNormalizedArc(vnFrom, vnTo);
|
||||
}
|
||||
|
||||
inline float square_distance_between_linesegment_and_point(const D3DXVECTOR3& p1,const D3DXVECTOR3& p2,const D3DXVECTOR3& x)
|
||||
{
|
||||
const auto v1 = p2 - p1;
|
||||
float l = D3DXVec3LengthSq(&v1);
|
||||
const auto v2 = x - p1;
|
||||
const auto v3 = p2 - p1;
|
||||
float d = D3DXVec3Dot(&(v2),&(v3));
|
||||
if (d<=0.0f)
|
||||
{
|
||||
return D3DXVec3LengthSq(&(v2));
|
||||
}
|
||||
else if (d>=l)
|
||||
{
|
||||
const auto v4 = x - p2;
|
||||
return D3DXVec3LengthSq(&(v4));
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DXVECTOR3 c;
|
||||
return D3DXVec3LengthSq(D3DXVec3Cross(&c,&(v2),&(v3)))/l;
|
||||
}
|
||||
}
|
||||
|
||||
inline D3DXVECTOR3 * Vec3TransformQuaternionSafe(D3DXVECTOR3* pvout, const D3DXVECTOR3* pv, const D3DXQUATERNION* pq)
|
||||
{
|
||||
D3DXVECTOR3 v;
|
||||
D3DXVec3Cross(&v,pv,(D3DXVECTOR3*)pq);
|
||||
v *= -2*pq->w;
|
||||
v += (pq->w*pq->w - D3DXVec3LengthSq((D3DXVECTOR3*)pq))*(*pv);
|
||||
v += 2*D3DXVec3Dot((D3DXVECTOR3*)pq,pv)*(*(D3DXVECTOR3*)pq);
|
||||
*pvout = v;
|
||||
return pvout;
|
||||
}
|
||||
|
||||
inline D3DXVECTOR3 * Vec3TransformQuaternion(D3DXVECTOR3* pvout, const D3DXVECTOR3* pv, const D3DXQUATERNION* pq)
|
||||
{
|
||||
D3DXVec3Cross(pvout,pv,(D3DXVECTOR3*)pq);
|
||||
*pvout *= -2*pq->w;
|
||||
*pvout += (pq->w*pq->w - D3DXVec3LengthSq((D3DXVECTOR3*)pq))*(*pv);
|
||||
*pvout += 2*D3DXVec3Dot((D3DXVECTOR3*)pq,pv)*(*(D3DXVECTOR3*)pq);
|
||||
|
||||
return pvout;
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
#include "StdAfx.h"
|
||||
#include "GrpObjectInstance.h"
|
||||
#include "../EterBase/Timer.h"
|
||||
|
||||
void CGraphicObjectInstance::OnInitialize()
|
||||
{
|
||||
ZeroMemory(m_abyPortalID, sizeof(m_abyPortalID));
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::Clear()
|
||||
{
|
||||
if (m_CullingHandle)
|
||||
{
|
||||
CCullingManager::Instance().Unregister(m_CullingHandle);
|
||||
m_CullingHandle = NULL;
|
||||
}
|
||||
|
||||
ClearHeightInstance();
|
||||
|
||||
m_isVisible = TRUE;
|
||||
|
||||
m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f;
|
||||
m_v3Scale.x = m_v3Scale.y = m_v3Scale.z = 0.0f;
|
||||
//m_fRotation = 0.0f;
|
||||
m_fYaw = m_fPitch = m_fRoll = 0.0f;
|
||||
D3DXMatrixIdentity(&m_worldMatrix);
|
||||
|
||||
ZeroMemory(m_abyPortalID, sizeof(m_abyPortalID));
|
||||
|
||||
OnClear();
|
||||
}
|
||||
|
||||
bool CGraphicObjectInstance::Render()
|
||||
{
|
||||
/*
|
||||
if (m_CullingHandle)
|
||||
{
|
||||
SpherePack * ps = m_CullingHandle->GetParent();
|
||||
CScreen s;
|
||||
s.SetColorOperation();
|
||||
//s.SetDiffuseColor(1,isShow()?1:0,0);
|
||||
//s.RenderCircle2d(m_CullingHandle->GetCenter().x,m_CullingHandle->GetCenter().y,m_CullingHandle->GetCenter().z,m_CullingHandle->GetRadius());
|
||||
s.SetDiffuseColor(1,isShow()?1:0,ps->HasSpherePackFlag(SPF_PARTIAL)?1:0);
|
||||
s.RenderCircle2d(ps->GetCenter().x,ps->GetCenter().y,ps->GetCenter().z,ps->GetRadius());
|
||||
}
|
||||
//*/
|
||||
if (!isShow())
|
||||
return false;
|
||||
|
||||
OnRender();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::BlendRender()
|
||||
{
|
||||
if (!isShow())
|
||||
return;
|
||||
|
||||
OnBlendRender();
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::RenderToShadowMap()
|
||||
{
|
||||
if (!isShow())
|
||||
return;
|
||||
|
||||
OnRenderToShadowMap();
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::RenderShadow()
|
||||
{
|
||||
if (!isShow())
|
||||
return;
|
||||
|
||||
OnRenderShadow();
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::RenderPCBlocker()
|
||||
{
|
||||
if (!isShow())
|
||||
return;
|
||||
|
||||
OnRenderPCBlocker();
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::Update()
|
||||
{
|
||||
OnUpdate();
|
||||
|
||||
UpdateBoundingSphere();
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::Deform()
|
||||
{
|
||||
if (!isShow())
|
||||
return;
|
||||
|
||||
OnDeform();
|
||||
}
|
||||
|
||||
|
||||
void CGraphicObjectInstance::Transform()
|
||||
{
|
||||
m_worldMatrix = m_mRotation;
|
||||
|
||||
m_worldMatrix._41 += m_v3Position.x;
|
||||
m_worldMatrix._42 += m_v3Position.y;
|
||||
m_worldMatrix._43 += m_v3Position.z;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3 & CGraphicObjectInstance::GetPosition() const
|
||||
{
|
||||
return m_v3Position;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3 & CGraphicObjectInstance::GetScale() const
|
||||
{
|
||||
return m_v3Scale;
|
||||
}
|
||||
|
||||
float CGraphicObjectInstance::GetRotation()
|
||||
{
|
||||
return GetRoll();
|
||||
}
|
||||
|
||||
float CGraphicObjectInstance::GetYaw()
|
||||
{
|
||||
return m_fYaw;
|
||||
}
|
||||
|
||||
float CGraphicObjectInstance::GetPitch()
|
||||
{
|
||||
return m_fPitch;
|
||||
}
|
||||
|
||||
float CGraphicObjectInstance::GetRoll()
|
||||
{
|
||||
return m_fRoll;
|
||||
}
|
||||
|
||||
D3DXMATRIX & CGraphicObjectInstance::GetTransform()
|
||||
{
|
||||
return m_worldMatrix;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetRotationQuaternion(const D3DXQUATERNION &q)
|
||||
{
|
||||
D3DXMatrixRotationQuaternion(&m_mRotation, &q);
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetRotationMatrix(const D3DXMATRIX & m)
|
||||
{
|
||||
m_mRotation = m;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetRotation(float fRotation)
|
||||
{
|
||||
m_fYaw = 0;
|
||||
m_fPitch = 0;
|
||||
m_fRoll = fRotation;
|
||||
|
||||
D3DXMatrixRotationZ(&m_mRotation, D3DXToRadian(fRotation));
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetRotation(float fYaw, float fPitch, float fRoll)
|
||||
{
|
||||
//m_fRotation = fRotation;
|
||||
m_fYaw = fYaw;
|
||||
m_fPitch = fPitch;
|
||||
m_fRoll = fRoll;
|
||||
|
||||
D3DXMatrixRotationYawPitchRoll(&m_mRotation, D3DXToRadian(fYaw), D3DXToRadian(fPitch), D3DXToRadian(fRoll));
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetPosition(float x, float y, float z)
|
||||
{
|
||||
m_v3Position.x = x;
|
||||
m_v3Position.y = y;
|
||||
m_v3Position.z = z;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetPosition(const D3DXVECTOR3 & newposition)
|
||||
{
|
||||
m_v3Position = newposition;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetScale(float x, float y, float z)
|
||||
{
|
||||
m_v3Scale.x = x;
|
||||
m_v3Scale.y = y;
|
||||
m_v3Scale.z = z;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::Show()
|
||||
{
|
||||
m_isVisible = true;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::Hide()
|
||||
{
|
||||
m_isVisible = false;
|
||||
}
|
||||
bool CGraphicObjectInstance::isShow()
|
||||
{
|
||||
return m_isVisible;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
D3DXVECTOR4 & CGraphicObjectInstance::GetWTBBoxVertex(const unsigned char & c_rucNumTBBoxVertex)
|
||||
{
|
||||
return m_v4TBBox[c_rucNumTBBoxVertex];
|
||||
}
|
||||
|
||||
bool CGraphicObjectInstance::isIntersect(const CRay & c_rRay, float * pu, float * pv, float * pt)
|
||||
{
|
||||
D3DXVECTOR3 v3Start, v3Dir;
|
||||
float fRayRange;
|
||||
c_rRay.GetStartPoint(&v3Start);
|
||||
c_rRay.GetDirection(&v3Dir, &fRayRange);
|
||||
|
||||
TPosition posVertices[8];
|
||||
|
||||
posVertices[0] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMin.y, m_v3TBBoxMin.z);
|
||||
posVertices[1] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMin.y, m_v3TBBoxMin.z);
|
||||
posVertices[2] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMax.y, m_v3TBBoxMin.z);
|
||||
posVertices[3] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMax.y, m_v3TBBoxMin.z);
|
||||
posVertices[4] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMin.y, m_v3TBBoxMax.z);
|
||||
posVertices[5] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMin.y, m_v3TBBoxMax.z);
|
||||
posVertices[6] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMax.y, m_v3TBBoxMax.z);
|
||||
posVertices[7] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMax.y, m_v3TBBoxMax.z);
|
||||
|
||||
TIndex Indices[36] = {0, 1, 2, 1, 3, 2,
|
||||
2, 0, 6, 0, 4, 6,
|
||||
0, 1, 4, 1, 5, 4,
|
||||
1, 3, 5, 3, 7, 5,
|
||||
3, 2, 7, 2, 6, 7,
|
||||
4, 5, 6, 5, 7, 6};
|
||||
|
||||
int triCount = 12;
|
||||
WORD* pcurIdx = (WORD*)Indices;
|
||||
|
||||
while (triCount--)
|
||||
{
|
||||
if (IntersectTriangle(v3Start, v3Dir,
|
||||
posVertices[pcurIdx[0]],
|
||||
posVertices[pcurIdx[1]],
|
||||
posVertices[pcurIdx[2]],
|
||||
pu, pv, pt))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
pcurIdx += 3;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CGraphicObjectInstance::CGraphicObjectInstance()
|
||||
{
|
||||
m_CullingHandle = 0;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::Initialize()
|
||||
{
|
||||
if (m_CullingHandle)
|
||||
CCullingManager::Instance().Unregister(m_CullingHandle);
|
||||
m_CullingHandle = 0;
|
||||
|
||||
m_pHeightAttributeInstance = NULL;
|
||||
|
||||
m_isVisible = TRUE;
|
||||
|
||||
m_BlockCamera = false;
|
||||
|
||||
m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f;
|
||||
m_v3Scale.x = m_v3Scale.y = m_v3Scale.z = 0.0f;
|
||||
m_fYaw = m_fPitch = m_fRoll = 0.0f;
|
||||
|
||||
D3DXMatrixIdentity(&m_worldMatrix);
|
||||
D3DXMatrixIdentity(&m_mRotation);
|
||||
|
||||
OnInitialize();
|
||||
}
|
||||
|
||||
CGraphicObjectInstance::~CGraphicObjectInstance()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::UpdateBoundingSphere()
|
||||
{
|
||||
if (m_CullingHandle)
|
||||
{
|
||||
Vector3d center;
|
||||
float radius;
|
||||
GetBoundingSphere(center,radius);
|
||||
if (radius != m_CullingHandle->GetRadius())
|
||||
m_CullingHandle->NewPosRadius(center,radius);
|
||||
else
|
||||
m_CullingHandle->NewPos(center);
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::RegisterBoundingSphere()
|
||||
{
|
||||
if (m_CullingHandle)
|
||||
CCullingManager::Instance().Unregister(m_CullingHandle);
|
||||
|
||||
m_CullingHandle = CCullingManager::Instance().Register(this);
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::AddCollision(const CStaticCollisionData * pscd, const D3DXMATRIX* pMat)
|
||||
{
|
||||
m_StaticCollisionInstanceVector.push_back(CBaseCollisionInstance::BuildCollisionInstance(pscd, pMat));
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::ClearCollision()
|
||||
{
|
||||
CCollisionInstanceVector::iterator it;
|
||||
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
|
||||
{
|
||||
(*it)->Destroy();
|
||||
}
|
||||
m_StaticCollisionInstanceVector.clear();
|
||||
}
|
||||
|
||||
bool CGraphicObjectInstance::CollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
CCollisionInstanceVector::const_iterator it;
|
||||
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
|
||||
{
|
||||
if ((*it)->CollisionDynamicSphere(s))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicObjectInstance::MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
CCollisionInstanceVector::const_iterator it;
|
||||
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
|
||||
{
|
||||
if ((*it)->MovementCollisionDynamicSphere(s))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 CGraphicObjectInstance::GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
|
||||
{
|
||||
CCollisionInstanceVector::const_iterator it;
|
||||
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
|
||||
{
|
||||
if ((*it)->MovementCollisionDynamicSphere(s))
|
||||
return (*it)->GetCollisionMovementAdjust(s);
|
||||
}
|
||||
|
||||
return D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::UpdateCollisionData(const CStaticCollisionDataVector * pscdVector)
|
||||
{
|
||||
ClearCollision();
|
||||
OnUpdateCollisionData(pscdVector);
|
||||
}
|
||||
|
||||
DWORD CGraphicObjectInstance::GetCollisionInstanceCount()
|
||||
{
|
||||
return m_StaticCollisionInstanceVector.size();
|
||||
}
|
||||
|
||||
CBaseCollisionInstance * CGraphicObjectInstance::GetCollisionInstanceData(DWORD dwIndex)
|
||||
{
|
||||
if (dwIndex>m_StaticCollisionInstanceVector.size())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return m_StaticCollisionInstanceVector[dwIndex];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Height
|
||||
|
||||
void CGraphicObjectInstance::SetHeightInstance(CAttributeInstance * pAttributeInstance)
|
||||
{
|
||||
m_pHeightAttributeInstance = pAttributeInstance;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::ClearHeightInstance()
|
||||
{
|
||||
m_pHeightAttributeInstance = NULL;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::UpdateHeightInstance(CAttributeInstance * pAttributeInstance)
|
||||
{
|
||||
ClearHeightInstance();
|
||||
OnUpdateHeighInstance(pAttributeInstance);
|
||||
}
|
||||
|
||||
bool CGraphicObjectInstance::IsObjectHeight()
|
||||
{
|
||||
if (m_pHeightAttributeInstance)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicObjectInstance::GetObjectHeight(float fX, float fY, float * pfHeight)
|
||||
{
|
||||
if (!m_pHeightAttributeInstance)
|
||||
return false;
|
||||
|
||||
return OnGetObjectHeight(fX, fY, pfHeight);
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::SetPortal(DWORD dwIndex, int iID)
|
||||
{
|
||||
if (dwIndex >= PORTAL_ID_MAX_NUM)
|
||||
{
|
||||
assert(dwIndex < PORTAL_ID_MAX_NUM);
|
||||
return;
|
||||
}
|
||||
|
||||
m_abyPortalID[dwIndex] = iID;
|
||||
}
|
||||
|
||||
int CGraphicObjectInstance::GetPortal(DWORD dwIndex)
|
||||
{
|
||||
if (dwIndex >= PORTAL_ID_MAX_NUM)
|
||||
{
|
||||
assert(dwIndex < PORTAL_ID_MAX_NUM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_abyPortalID[dwIndex];
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpColorInstance.h"
|
||||
#include "GrpScreen.h"
|
||||
#include "CullingManager.h"
|
||||
#include "CollisionData.h"
|
||||
#include "AttributeInstance.h"
|
||||
|
||||
enum
|
||||
{
|
||||
THING_OBJECT = 0xadf21f13,
|
||||
TREE_OBJECT = 0x8ac9f7a6,
|
||||
ACTOR_OBJECT = 0x29a76c24,
|
||||
EFFECT_OBJECT = 0x1cfa97c6,
|
||||
DUNGEON_OBJECT = 0x18326035,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PORTAL_ID_MAX_NUM = 8,
|
||||
};
|
||||
|
||||
class CGraphicObjectInstance : public CGraphicCollisionObject
|
||||
{
|
||||
public:
|
||||
CGraphicObjectInstance();
|
||||
virtual ~CGraphicObjectInstance();
|
||||
virtual int GetType() const = 0;
|
||||
|
||||
public:
|
||||
const D3DXVECTOR3 & GetPosition() const;
|
||||
const D3DXVECTOR3 & GetScale() const;
|
||||
float GetRotation();
|
||||
float GetYaw();
|
||||
float GetPitch();
|
||||
float GetRoll();
|
||||
|
||||
void SetPosition(float x, float y, float z);
|
||||
void SetPosition(const D3DXVECTOR3 & newposition);
|
||||
void SetScale(float x, float y, float z);
|
||||
void SetRotation(float fRotation);
|
||||
void SetRotation(float fYaw, float fPitch, float fRoll);
|
||||
void SetRotationQuaternion(const D3DXQUATERNION &q);
|
||||
void SetRotationMatrix(const D3DXMATRIX & m);
|
||||
|
||||
void Clear();
|
||||
void Update();
|
||||
bool Render();
|
||||
void BlendRender();
|
||||
void RenderToShadowMap();
|
||||
void RenderShadow();
|
||||
void RenderPCBlocker();
|
||||
void Deform();
|
||||
void Transform();
|
||||
|
||||
void Show();
|
||||
void Hide();
|
||||
bool isShow();
|
||||
|
||||
// Camera Block
|
||||
void BlockCamera(bool bBlock) {m_BlockCamera = bBlock;}
|
||||
bool BlockCamera() { return m_BlockCamera; }
|
||||
|
||||
// Ray Test
|
||||
bool isIntersect(const CRay & c_rRay, float * pu, float * pv, float * pt);
|
||||
|
||||
// Bounding Box
|
||||
D3DXVECTOR4 & GetWTBBoxVertex(const unsigned char & c_rucNumTBBoxVertex);
|
||||
D3DXVECTOR3 & GetTBBoxMin() { return m_v3TBBoxMin; }
|
||||
D3DXVECTOR3 & GetTBBoxMax() { return m_v3TBBoxMax; }
|
||||
D3DXVECTOR3 & GetBBoxMin() { return m_v3BBoxMin; }
|
||||
D3DXVECTOR3 & GetBBoxMax() { return m_v3BBoxMax; }
|
||||
|
||||
// Matrix
|
||||
D3DXMATRIX & GetTransform();
|
||||
const D3DXMATRIX& GetWorldMatrix() { return m_worldMatrix; }
|
||||
|
||||
// Portal
|
||||
void SetPortal(DWORD dwIndex, int iID);
|
||||
int GetPortal(DWORD dwIndex);
|
||||
|
||||
// Initialize
|
||||
void Initialize();
|
||||
virtual void OnInitialize();
|
||||
|
||||
// Bounding Sphere
|
||||
public:
|
||||
void UpdateBoundingSphere();
|
||||
void RegisterBoundingSphere();
|
||||
virtual bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius) = 0;
|
||||
|
||||
virtual void OnRender() = 0;
|
||||
virtual void OnBlendRender() = 0;
|
||||
virtual void OnRenderToShadowMap() = 0;
|
||||
virtual void OnRenderShadow() = 0;
|
||||
virtual void OnRenderPCBlocker() = 0;
|
||||
virtual void OnClear(){}
|
||||
virtual void OnUpdate(){}
|
||||
virtual void OnDeform(){}
|
||||
|
||||
protected:
|
||||
D3DXVECTOR3 m_v3Position;
|
||||
D3DXVECTOR3 m_v3Scale;
|
||||
|
||||
float m_fYaw;
|
||||
float m_fPitch;
|
||||
float m_fRoll;
|
||||
|
||||
D3DXMATRIX m_mRotation;
|
||||
|
||||
bool m_isVisible;
|
||||
D3DXMATRIX m_worldMatrix;
|
||||
|
||||
// Camera Block
|
||||
bool m_BlockCamera;
|
||||
|
||||
// Bounding Box
|
||||
D3DXVECTOR4 m_v4TBBox[8];
|
||||
D3DXVECTOR3 m_v3TBBoxMin, m_v3TBBoxMax;
|
||||
D3DXVECTOR3 m_v3BBoxMin, m_v3BBoxMax;
|
||||
|
||||
// Portal
|
||||
BYTE m_abyPortalID[PORTAL_ID_MAX_NUM];
|
||||
|
||||
// Culling
|
||||
CCullingManager::CullingHandle m_CullingHandle;
|
||||
|
||||
// Static Collision Data
|
||||
public:
|
||||
void AddCollision(const CStaticCollisionData * pscd, const D3DXMATRIX * pMat);
|
||||
void ClearCollision();
|
||||
bool CollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
bool MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
|
||||
D3DXVECTOR3 GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
|
||||
|
||||
void UpdateCollisionData(const CStaticCollisionDataVector * pscdVector = 0);
|
||||
|
||||
protected:
|
||||
CCollisionInstanceVector m_StaticCollisionInstanceVector;
|
||||
virtual void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector) = 0;
|
||||
|
||||
// using in WorldEditor
|
||||
public:
|
||||
DWORD GetCollisionInstanceCount();
|
||||
CBaseCollisionInstance * GetCollisionInstanceData(DWORD dwIndex);
|
||||
|
||||
// Height Data
|
||||
public:
|
||||
void SetHeightInstance(CAttributeInstance * pAttributeInstance);
|
||||
void ClearHeightInstance();
|
||||
|
||||
void UpdateHeightInstance(CAttributeInstance * pAttributeInstance = 0);
|
||||
|
||||
bool IsObjectHeight();
|
||||
bool GetObjectHeight(float fX, float fY, float * pfHeight);
|
||||
|
||||
protected:
|
||||
CAttributeInstance * m_pHeightAttributeInstance;
|
||||
virtual void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) = 0;
|
||||
virtual bool OnGetObjectHeight(float fX, float fY, float * pfHeight) = 0;
|
||||
};
|
||||
@@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpCollisionObject.h"
|
||||
#include "../SphereLib/frustum.h"
|
||||
|
||||
|
||||
class CScreen : public CGraphicCollisionObject
|
||||
{
|
||||
public:
|
||||
CScreen();
|
||||
virtual ~CScreen();
|
||||
|
||||
void ClearDepthBuffer();
|
||||
void Clear();
|
||||
bool Begin();
|
||||
void End();
|
||||
void Show(HWND hWnd = NULL);
|
||||
void Show(RECT * pSrcRect);
|
||||
void Show(RECT * pSrcRect, HWND hWnd);
|
||||
|
||||
void RenderLine2d(float sx, float sy, float ex, float ey, float z=0.0f);
|
||||
void RenderBox2d(float sx, float sy, float ex, float ey, float z=0.0f);
|
||||
void RenderBar2d(float sx, float sy, float ex, float ey, float z=0.0f);
|
||||
void RenderGradationBar2d(float sx, float sy, float ex, float ey, DWORD dwStartColor, DWORD dwEndColor, float ez=0.0f);
|
||||
void RenderCircle2d(float fx, float fy, float fz, float fRadius, int iStep = 50);
|
||||
void RenderCircle3d(float fx, float fy, float fz, float fRadius, int iStep = 50);
|
||||
|
||||
void RenderLine3d(float sx, float sy, float sz, float ex, float ey, float ez);
|
||||
void RenderBox3d(float sx, float sy, float sz, float ex, float ey, float ez);
|
||||
void RenderBar3d(float sx, float sy, float sz, float ex, float ey, float ez);
|
||||
void RenderBar3d(const D3DXVECTOR3 * c_pv3Positions);
|
||||
void RenderGradationBar3d(float sx, float sy, float sz, float ex, float ey, float ez, DWORD dwStartColor, DWORD dwEndColor);
|
||||
|
||||
void RenderLineCube(float sx, float sy, float sz, float ex, float ey, float ez);
|
||||
void RenderCube(float sx, float sy, float sz, float ex, float ey, float ez);
|
||||
void RenderCube(float sx, float sy, float sz, float ex, float ey, float ez, D3DXMATRIX matRotation);
|
||||
void RenderTextureBox(float sx, float sy, float ex, float ey, float z=0.0f, float su=0.0f, float sv=0.0f, float eu=1.0f, float ev=1.0f);
|
||||
void RenderBillboard(D3DXVECTOR3 * Position, D3DXCOLOR & Color);
|
||||
|
||||
void DrawMinorGrid(float xMin, float yMin, float xMax, float yMax, float xminorStep, float yminorStep, float zPos=0);
|
||||
void DrawGrid(float xMin, float yMin, float xMax, float yMax, float xmajorStep, float ymajorStep, float xminorStep, float yminorStep, float zPos=0);
|
||||
|
||||
void RenderD3DXMesh(LPD3DXMESH lpMesh, const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode);
|
||||
void RenderSphere(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
|
||||
void RenderCylinder(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, float fLength, D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
|
||||
|
||||
void SetColorOperation();
|
||||
void SetDiffuseOperation();
|
||||
void SetBlendOperation();
|
||||
void SetOneColorOperation(D3DXCOLOR & rColor);
|
||||
void SetAddColorOperation(D3DXCOLOR & rColor);
|
||||
void SetDiffuseColor(DWORD diffuseColor);
|
||||
void SetDiffuseColor(float r, float g, float b, float a=1.0f);
|
||||
void SetClearColor(float r, float g, float b, float a=1.0f);
|
||||
void SetClearDepth(float depth);
|
||||
void SetClearStencil(DWORD stencil);
|
||||
|
||||
void SetCursorPosition(int x, int y, int hres, int vres); // creates picking ray
|
||||
bool GetCursorPosition(float* px, float* py, float* pz);
|
||||
bool GetCursorXYPosition(float* px, float* py);
|
||||
bool GetCursorZPosition(float* pz);
|
||||
void GetPickingPosition(float t, float* x, float* y, float* z);
|
||||
void ProjectPosition(float x, float y, float z, float * pfX, float * pfY);
|
||||
void ProjectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ);
|
||||
void UnprojectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ);
|
||||
|
||||
BOOL IsLostDevice();
|
||||
BOOL RestoreDevice();
|
||||
|
||||
void BuildViewFrustum();
|
||||
|
||||
static void Identity();
|
||||
static Frustum & GetFrustum() { return ms_frustum; }
|
||||
|
||||
protected:
|
||||
static DWORD ms_diffuseColor;
|
||||
static DWORD ms_clearColor;
|
||||
static DWORD ms_clearStencil;
|
||||
static float ms_clearDepth;
|
||||
|
||||
static Frustum ms_frustum;
|
||||
};
|
||||
@@ -0,0 +1,191 @@
|
||||
#include "StdAfx.h"
|
||||
#include "GrpShadowTexture.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CGraphicShadowTexture::Destroy()
|
||||
{
|
||||
CGraphicTexture::Destroy();
|
||||
|
||||
if (m_lpd3dShadowSurface)
|
||||
{
|
||||
m_lpd3dShadowSurface->Release();
|
||||
m_lpd3dShadowSurface = NULL;
|
||||
}
|
||||
|
||||
if (m_lpd3dDepthSurface)
|
||||
{
|
||||
m_lpd3dDepthSurface->Release();
|
||||
m_lpd3dDepthSurface = NULL;
|
||||
}
|
||||
|
||||
if (m_lpd3dShadowTexture)
|
||||
{
|
||||
m_lpd3dShadowTexture->Release();
|
||||
m_lpd3dShadowTexture = NULL;
|
||||
}
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
bool CGraphicShadowTexture::Create(int width, int height)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_lpd3dShadowTexture)))
|
||||
return false;
|
||||
|
||||
if (FAILED(m_lpd3dShadowTexture->GetSurfaceLevel(0, &m_lpd3dShadowSurface)))
|
||||
return false;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_width, m_height, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpd3dDepthSurface)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicShadowTexture::Set(int stage) const
|
||||
{
|
||||
STATEMANAGER.SetTexture(stage, m_lpd3dShadowTexture);
|
||||
}
|
||||
|
||||
const D3DXMATRIX& CGraphicShadowTexture::GetLightVPMatrixReference() const
|
||||
{
|
||||
return m_d3dLightVPMatrix;
|
||||
}
|
||||
|
||||
LPDIRECT3DTEXTURE8 CGraphicShadowTexture::GetD3DTexture() const
|
||||
{
|
||||
return m_lpd3dShadowTexture;
|
||||
}
|
||||
|
||||
void CGraphicShadowTexture::Begin()
|
||||
{
|
||||
D3DXMatrixMultiply(&m_d3dLightVPMatrix, &ms_matView, &ms_matProj);
|
||||
|
||||
ms_lpd3dDevice->GetRenderTarget(&m_lpd3dOldBackBufferSurface);
|
||||
ms_lpd3dDevice->GetDepthStencilSurface(&m_lpd3dOldDepthBufferSurface);
|
||||
ms_lpd3dDevice->GetViewport(&m_d3dOldViewport);
|
||||
|
||||
ms_lpd3dDevice->SetRenderTarget(m_lpd3dShadowSurface, m_lpd3dDepthSurface);
|
||||
|
||||
D3DVIEWPORT8 d3dViewport;
|
||||
d3dViewport.MinZ = 0.0f;
|
||||
d3dViewport.MaxZ = 1.0f;
|
||||
d3dViewport.X = 0;
|
||||
d3dViewport.Y = 0;
|
||||
d3dViewport.Width = m_width;
|
||||
d3dViewport.Height = m_height;
|
||||
|
||||
ms_lpd3dDevice->SetViewport(&d3dViewport);
|
||||
ms_lpd3dDevice->BeginScene();
|
||||
|
||||
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, true);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, true);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xbb000000);
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
|
||||
void CGraphicShadowTexture::End()
|
||||
{
|
||||
assert(m_lpd3dOldBackBufferSurface != NULL);
|
||||
assert(m_lpd3dOldDepthBufferSurface != NULL);
|
||||
|
||||
ms_lpd3dDevice->EndScene();
|
||||
|
||||
ms_lpd3dDevice->SetRenderTarget(m_lpd3dOldBackBufferSurface, m_lpd3dOldDepthBufferSurface);
|
||||
ms_lpd3dDevice->SetViewport(&m_d3dOldViewport);
|
||||
|
||||
m_lpd3dOldBackBufferSurface->Release();
|
||||
m_lpd3dOldDepthBufferSurface->Release();
|
||||
|
||||
m_lpd3dOldBackBufferSurface = NULL;
|
||||
m_lpd3dOldDepthBufferSurface = NULL;
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG2);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLOROP);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG2);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAOP);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MINFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MAGFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MIPFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
}
|
||||
|
||||
void CGraphicShadowTexture::Initialize()
|
||||
{
|
||||
CGraphicTexture::Initialize();
|
||||
|
||||
m_lpd3dShadowSurface = NULL;
|
||||
m_lpd3dDepthSurface = NULL;
|
||||
m_lpd3dOldBackBufferSurface = NULL;
|
||||
m_lpd3dOldDepthBufferSurface = NULL;
|
||||
m_lpd3dShadowTexture = NULL;
|
||||
}
|
||||
|
||||
CGraphicShadowTexture::CGraphicShadowTexture()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicShadowTexture::~CGraphicShadowTexture()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpTexture.h"
|
||||
|
||||
class CGraphicShadowTexture : public CGraphicTexture
|
||||
{
|
||||
public:
|
||||
CGraphicShadowTexture();
|
||||
virtual ~CGraphicShadowTexture();
|
||||
|
||||
void Destroy();
|
||||
|
||||
bool Create(int width, int height);
|
||||
|
||||
void Begin();
|
||||
void End();
|
||||
void Set(int stage = 0) const;
|
||||
|
||||
const D3DXMATRIX& GetLightVPMatrixReference() const;
|
||||
LPDIRECT3DTEXTURE8 GetD3DTexture() const;
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
D3DXMATRIX m_d3dLightVPMatrix;
|
||||
D3DVIEWPORT8 m_d3dOldViewport;
|
||||
|
||||
LPDIRECT3DTEXTURE8 m_lpd3dShadowTexture;
|
||||
LPDIRECT3DSURFACE8 m_lpd3dShadowSurface;
|
||||
LPDIRECT3DSURFACE8 m_lpd3dDepthSurface;
|
||||
|
||||
LPDIRECT3DSURFACE8 m_lpd3dOldBackBufferSurface;
|
||||
LPDIRECT3DSURFACE8 m_lpd3dOldDepthBufferSurface;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpImage.h"
|
||||
|
||||
class CGraphicSubImage : public CGraphicImage
|
||||
{
|
||||
public:
|
||||
typedef CRef<CGraphicImage> TRef;
|
||||
|
||||
public:
|
||||
static TType Type();
|
||||
static char m_SearchPath[256];
|
||||
|
||||
public:
|
||||
CGraphicSubImage(const char* c_szFileName);
|
||||
virtual ~CGraphicSubImage();
|
||||
|
||||
bool CreateDeviceObjects();
|
||||
|
||||
bool SetImageFileName(const char* c_szFileName);
|
||||
|
||||
void SetRectPosition(int left, int top, int right, int bottom);
|
||||
|
||||
void SetRectReference(const RECT& c_rRect);
|
||||
|
||||
static void SetSearchPath(const char * c_szFileName);
|
||||
|
||||
protected:
|
||||
void SetImagePointer(CGraphicImage* pImage);
|
||||
|
||||
bool OnLoad(int iSize, const void* c_pvBuf);
|
||||
void OnClear();
|
||||
bool OnIsEmpty() const;
|
||||
bool OnIsType(TType type);
|
||||
|
||||
protected:
|
||||
CGraphicImage::TRef m_roImage;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Ref.h"
|
||||
#include "GrpFontTexture.h"
|
||||
|
||||
class CGraphicText : public CResource
|
||||
{
|
||||
public:
|
||||
typedef CRef<CGraphicText> TRef;
|
||||
|
||||
public:
|
||||
static TType Type();
|
||||
|
||||
public:
|
||||
CGraphicText(const char* c_szFileName);
|
||||
virtual ~CGraphicText();
|
||||
|
||||
virtual bool CreateDeviceObjects();
|
||||
virtual void DestroyDeviceObjects();
|
||||
|
||||
CGraphicFontTexture * GetFontTexturePointer();
|
||||
|
||||
protected:
|
||||
bool OnLoad(int iSize, const void * c_pvBuf);
|
||||
void OnClear();
|
||||
bool OnIsEmpty() const;
|
||||
bool OnIsType(TType type);
|
||||
|
||||
protected:
|
||||
CGraphicFontTexture m_fontTexture;
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
#ifndef __INC_ETERLIB_GRPTEXTINSTANCE_H__
|
||||
#define __INC_ETERLIB_GRPTEXTINSTANCE_H__
|
||||
|
||||
#include "Pool.h"
|
||||
#include "GrpText.h"
|
||||
|
||||
class CGraphicTextInstance
|
||||
{
|
||||
public:
|
||||
typedef CDynamicPool<CGraphicTextInstance> TPool;
|
||||
|
||||
public:
|
||||
enum EHorizontalAlign
|
||||
{
|
||||
HORIZONTAL_ALIGN_LEFT = 0x01,
|
||||
HORIZONTAL_ALIGN_CENTER = 0x02,
|
||||
HORIZONTAL_ALIGN_RIGHT = 0x03,
|
||||
};
|
||||
enum EVerticalAlign
|
||||
{
|
||||
VERTICAL_ALIGN_TOP = 0x10,
|
||||
VERTICAL_ALIGN_CENTER = 0x20,
|
||||
VERTICAL_ALIGN_BOTTOM = 0x30
|
||||
};
|
||||
|
||||
public:
|
||||
static void Hyperlink_UpdateMousePos(int x, int y);
|
||||
static int Hyperlink_GetText(char* buf, int len);
|
||||
|
||||
public:
|
||||
CGraphicTextInstance();
|
||||
virtual ~CGraphicTextInstance();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void Update();
|
||||
void Render(RECT * pClipRect = NULL);
|
||||
|
||||
void ShowCursor();
|
||||
void HideCursor();
|
||||
|
||||
void ShowOutLine();
|
||||
void HideOutLine();
|
||||
|
||||
void SetColor(DWORD color);
|
||||
void SetColor(float r, float g, float b, float a = 1.0f);
|
||||
|
||||
void SetOutLineColor(DWORD color);
|
||||
void SetOutLineColor(float r, float g, float b, float a = 1.0f);
|
||||
|
||||
void SetHorizonalAlign(int hAlign);
|
||||
void SetVerticalAlign(int vAlign);
|
||||
void SetMax(int iMax);
|
||||
void SetTextPointer(CGraphicText* pText);
|
||||
void SetValueString(const std::string& c_stValue);
|
||||
void SetValue(const char* c_szValue, size_t len = -1);
|
||||
void SetPosition(float fx, float fy, float fz = 0.0f);
|
||||
void SetSecret(bool Value);
|
||||
void SetOutline(bool Value);
|
||||
void SetFeather(bool Value);
|
||||
void SetMultiLine(bool Value);
|
||||
void SetLimitWidth(float fWidth);
|
||||
|
||||
void GetTextSize(int* pRetWidth, int* pRetHeight);
|
||||
const std::string& GetValueStringReference();
|
||||
WORD GetTextLineCount();
|
||||
|
||||
int PixelPositionToCharacterPosition(int iPixelPosition);
|
||||
int GetHorizontalAlign();
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
int __DrawCharacter(CGraphicFontTexture * pFontTexture, WORD codePage, wchar_t text, DWORD dwColor);
|
||||
void __GetTextPos(DWORD index, float* x, float* y);
|
||||
int __GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo);
|
||||
|
||||
protected:
|
||||
struct SHyperlink
|
||||
{
|
||||
short sx;
|
||||
short ex;
|
||||
std::wstring text;
|
||||
|
||||
SHyperlink() : sx(0), ex(0) { }
|
||||
};
|
||||
|
||||
protected:
|
||||
DWORD m_dwTextColor;
|
||||
DWORD m_dwOutLineColor;
|
||||
|
||||
WORD m_textWidth;
|
||||
WORD m_textHeight;
|
||||
|
||||
BYTE m_hAlign;
|
||||
BYTE m_vAlign;
|
||||
|
||||
WORD m_iMax;
|
||||
float m_fLimitWidth;
|
||||
|
||||
bool m_isCursor;
|
||||
bool m_isSecret;
|
||||
bool m_isMultiLine;
|
||||
|
||||
bool m_isOutline;
|
||||
float m_fFontFeather;
|
||||
|
||||
/////
|
||||
|
||||
std::string m_stText;
|
||||
D3DXVECTOR3 m_v3Position;
|
||||
|
||||
private:
|
||||
bool m_isUpdate;
|
||||
bool m_isUpdateFontTexture;
|
||||
|
||||
CGraphicText::TRef m_roText;
|
||||
CGraphicFontTexture::TPCharacterInfomationVector m_pCharInfoVector;
|
||||
std::vector<DWORD> m_dwColorInfoVector;
|
||||
std::vector<SHyperlink> m_hyperlinkVector;
|
||||
|
||||
public:
|
||||
static void CreateSystem(UINT uCapacity);
|
||||
static void DestroySystem();
|
||||
|
||||
static CGraphicTextInstance* New();
|
||||
static void Delete(CGraphicTextInstance* pkInst);
|
||||
|
||||
static CDynamicPool<CGraphicTextInstance> ms_kPool;
|
||||
};
|
||||
|
||||
extern const char* FindToken(const char* begin, const char* end);
|
||||
extern int ReadToken(const char* token);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpBase.h"
|
||||
|
||||
class CGraphicTexture : public CGraphicBase
|
||||
{
|
||||
public:
|
||||
virtual bool IsEmpty() const;
|
||||
|
||||
int GetWidth() const;
|
||||
int GetHeight() const;
|
||||
|
||||
void SetTextureStage(int stage) const;
|
||||
LPDIRECT3DTEXTURE8 GetD3DTexture() const;
|
||||
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
protected:
|
||||
CGraphicTexture();
|
||||
virtual ~CGraphicTexture();
|
||||
|
||||
void Destroy();
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
bool m_bEmpty;
|
||||
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
LPDIRECT3DTEXTURE8 m_lpd3dTexture;
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpBase.h"
|
||||
|
||||
class CGraphicVertexBuffer : public CGraphicBase
|
||||
{
|
||||
public:
|
||||
CGraphicVertexBuffer();
|
||||
virtual ~CGraphicVertexBuffer();
|
||||
|
||||
void Destroy();
|
||||
virtual bool Create(int vtxCount, DWORD fvf, DWORD usage, D3DPOOL d3dPool);
|
||||
|
||||
bool CreateDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
bool Copy(int bufSize, const void* srcVertices);
|
||||
|
||||
bool LockRange(unsigned count, void** pretVertices) const;
|
||||
bool Lock(void** pretVertices) const;
|
||||
bool Unlock() const;
|
||||
|
||||
bool LockDynamic(void** pretVertices);
|
||||
virtual bool Lock(void** pretVertices);
|
||||
bool Unlock();
|
||||
|
||||
void SetStream(int stride, int layer=0) const;
|
||||
|
||||
int GetVertexCount() const;
|
||||
int GetVertexStride() const;
|
||||
DWORD GetFlexibleVertexFormat() const;
|
||||
|
||||
inline LPDIRECT3DVERTEXBUFFER8 GetD3DVertexBuffer() const { return m_lpd3dVB; }
|
||||
inline DWORD GetBufferSize() const { return m_dwBufferSize; }
|
||||
|
||||
bool IsEmpty() const;
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
LPDIRECT3DVERTEXBUFFER8 m_lpd3dVB;
|
||||
|
||||
DWORD m_dwBufferSize;
|
||||
DWORD m_dwFVF;
|
||||
DWORD m_dwUsage;
|
||||
D3DPOOL m_d3dPool;
|
||||
int m_vtxCount;
|
||||
DWORD m_dwLockFlag;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpVertexBuffer.h"
|
||||
|
||||
class CDynamicVertexBuffer : public CGraphicVertexBuffer
|
||||
{
|
||||
public:
|
||||
CDynamicVertexBuffer();
|
||||
virtual ~CDynamicVertexBuffer();
|
||||
|
||||
bool Create(int vtxCount, int fvf);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
int m_vtxCount;
|
||||
int m_fvf;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
#pragma once
|
||||
|
||||
#include <imm.h>
|
||||
|
||||
#pragma comment(lib, "imm32.lib")
|
||||
|
||||
#include "Dimm.h"
|
||||
|
||||
class IIMEEventSink
|
||||
{
|
||||
public:
|
||||
virtual bool OnWM_CHAR( WPARAM wParam, LPARAM lParam ) = 0;
|
||||
virtual void OnUpdate() = 0;
|
||||
|
||||
virtual void OnChangeCodePage() = 0;
|
||||
|
||||
virtual void OnOpenCandidateList() = 0;
|
||||
virtual void OnCloseCandidateList() = 0;
|
||||
|
||||
virtual void OnOpenReadingWnd() = 0;
|
||||
virtual void OnCloseReadingWnd() = 0;
|
||||
};
|
||||
|
||||
class CIME
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
IMEREADING_MAXLEN = 128,
|
||||
IMESTR_MAXLEN = 1024,
|
||||
IMECANDIDATE_MAXLEN = 32768,
|
||||
MAX_CANDLIST = 10,
|
||||
MAX_CANDIDATE_LENGTH = 256
|
||||
};
|
||||
|
||||
public:
|
||||
CIME();
|
||||
virtual ~CIME();
|
||||
|
||||
bool Initialize(HWND hWnd);
|
||||
void Uninitialize(void);
|
||||
|
||||
static void Clear();
|
||||
|
||||
void SetMax(int iMax);
|
||||
void SetUserMax(int iMax);
|
||||
void SetText(const char* c_szText, int len);
|
||||
int GetText(std::string & rstrText, bool addCodePage=false);
|
||||
const char* GetCodePageText();
|
||||
int GetCodePage();
|
||||
|
||||
// Candidate List
|
||||
int GetCandidateCount();
|
||||
int GetCandidatePageCount();
|
||||
int GetCandidate(DWORD index, std::string & rstrText);
|
||||
int GetCandidateSelection();
|
||||
|
||||
// Reading Information
|
||||
int GetReading(std::string & rstrText);
|
||||
int GetReadingError();
|
||||
|
||||
void SetInputMode(DWORD dwMode);
|
||||
DWORD GetInputMode();
|
||||
|
||||
bool IsIMEEnabled();
|
||||
void EnableIME(bool bEnable=true);
|
||||
void DisableIME();
|
||||
|
||||
void EnableCaptureInput();
|
||||
void DisableCaptureInput();
|
||||
bool IsCaptureEnabled();
|
||||
|
||||
void SetNumberMode();
|
||||
void SetStringMode();
|
||||
bool __IsWritable(wchar_t key);
|
||||
void AddExceptKey(wchar_t key);
|
||||
void ClearExceptKey();
|
||||
|
||||
void PasteTextFromClipBoard();
|
||||
void EnablePaste(bool bFlag);
|
||||
void PasteString(const char * str);
|
||||
static void FinalizeString(bool bSend = false);
|
||||
|
||||
void UseDefaultIME();
|
||||
|
||||
static int GetCurPos();
|
||||
static int GetCompLen();
|
||||
static int GetULBegin();
|
||||
static int GetULEnd();
|
||||
|
||||
static void CloseCandidateList();
|
||||
static void CloseReadingInformation();
|
||||
static void ChangeInputLanguage();
|
||||
static void ChangeInputLanguageWorker();
|
||||
|
||||
LRESULT WMInputLanguage(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT WMStartComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT WMComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT WMEndComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT WMNotify(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT WMChar(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
void IncCurPos();
|
||||
void DecCurPos();
|
||||
void SetCurPos(int offset);
|
||||
void DelCurPos();
|
||||
|
||||
protected:
|
||||
static void CheckInputLocale();
|
||||
static void CheckToggleState();
|
||||
static void SetSupportLevel( DWORD dwImeLevel );
|
||||
|
||||
void InsertString(wchar_t* szString, int iSize);
|
||||
|
||||
void OnChar(wchar_t c);
|
||||
|
||||
UINT GetCodePageFromLang( LANGID langid );
|
||||
void ResultProcess(HIMC hImc);
|
||||
void CompositionProcessBuilding(HIMC hImc);
|
||||
void CompositionProcess(HIMC hImc);
|
||||
void AttributeProcess(HIMC hImc);
|
||||
void CandidateProcess(HIMC hImc);
|
||||
void ReadingProcess(HIMC hImc);
|
||||
|
||||
bool IsMax(const wchar_t* wInput, int len);
|
||||
|
||||
DWORD GetImeId(UINT uIndex = 0);
|
||||
bool GetReadingWindowOrientation();
|
||||
static void SetupImeApi();
|
||||
|
||||
static INPUTCONTEXT* (WINAPI * _ImmLockIMC)( HIMC );
|
||||
static BOOL (WINAPI * _ImmUnlockIMC)( HIMC );
|
||||
static LPVOID (WINAPI * _ImmLockIMCC)( HIMCC );
|
||||
static BOOL (WINAPI * _ImmUnlockIMCC)( HIMCC );
|
||||
|
||||
static UINT (WINAPI * _GetReadingString)( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT );
|
||||
static BOOL (WINAPI * _ShowReadingWindow)( HIMC, BOOL );
|
||||
|
||||
protected:
|
||||
HIMC m_hOrgIMC;
|
||||
int m_max;
|
||||
int m_userMax;
|
||||
|
||||
BOOL m_bOnlyNumberMode;
|
||||
|
||||
std::vector<wchar_t> m_exceptKey;
|
||||
|
||||
bool m_bEnablePaste;
|
||||
bool m_bUseDefaultIME;
|
||||
|
||||
|
||||
public:
|
||||
static bool ms_bInitialized;
|
||||
static bool ms_bDisableIMECompletely;
|
||||
static bool ms_bUILessMode;
|
||||
static bool ms_bImeEnabled;
|
||||
static bool ms_bCaptureInput;
|
||||
static bool ms_bChineseIME;
|
||||
static bool ms_bUseIMMCandidate;
|
||||
|
||||
static HWND ms_hWnd;
|
||||
static HKL ms_hklCurrent;
|
||||
static char ms_szKeyboardLayout[KL_NAMELENGTH+1];
|
||||
static OSVERSIONINFOA ms_stOSVI;
|
||||
|
||||
static HINSTANCE ms_hImm32Dll;
|
||||
static HINSTANCE ms_hCurrentImeDll;
|
||||
static DWORD ms_dwImeState;
|
||||
|
||||
static DWORD ms_adwId[2];
|
||||
|
||||
// IME Level
|
||||
static DWORD ms_dwIMELevel;
|
||||
static DWORD ms_dwIMELevelSaved;
|
||||
|
||||
// Candidate List
|
||||
static bool ms_bCandidateList;
|
||||
static DWORD ms_dwCandidateCount;
|
||||
static bool ms_bVerticalCandidate;
|
||||
static int ms_iCandListIndexBase;
|
||||
static WCHAR ms_wszCandidate[CIME::MAX_CANDLIST][MAX_CANDIDATE_LENGTH];
|
||||
static DWORD ms_dwCandidateSelection;
|
||||
static DWORD ms_dwCandidatePageSize;
|
||||
|
||||
// Reading Information
|
||||
static bool ms_bReadingInformation;
|
||||
static int ms_iReadingError;
|
||||
static bool ms_bHorizontalReading;
|
||||
static std::vector<wchar_t> ms_wstrReading;
|
||||
|
||||
// Indicator
|
||||
static wchar_t* ms_wszCurrentIndicator;
|
||||
|
||||
static IIMEEventSink* ms_pEvent;
|
||||
|
||||
wchar_t m_wszComposition[IMESTR_MAXLEN];
|
||||
static wchar_t m_wText[IMESTR_MAXLEN];
|
||||
|
||||
static int ms_compLen;
|
||||
static int ms_curpos;
|
||||
static int ms_lastpos;
|
||||
static int ms_ulbegin;
|
||||
static int ms_ulend;
|
||||
|
||||
static UINT ms_uOutputCodePage;
|
||||
static UINT ms_uInputCodePage;
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
class CInputDevice
|
||||
{
|
||||
public:
|
||||
CInputDevice();
|
||||
virtual ~CInputDevice();
|
||||
|
||||
HRESULT CreateDevice(HWND hWnd);
|
||||
|
||||
protected:
|
||||
static LPDIRECTINPUT8 ms_lpDI;
|
||||
};
|
||||
|
||||
class CInputKeyboard : public CInputDevice
|
||||
{
|
||||
public:
|
||||
CInputKeyboard();
|
||||
virtual ~CInputKeyboard();
|
||||
|
||||
bool InitializeKeyboard(HWND hWnd);
|
||||
void UpdateKeyboard();
|
||||
void ResetKeyboard();
|
||||
|
||||
bool IsPressed(int iIndex);
|
||||
void KeyDown(int iIndex);
|
||||
void KeyUp(int iIndex);
|
||||
|
||||
protected:
|
||||
virtual void OnKeyDown(int iIndex) = 0;
|
||||
virtual void OnKeyUp(int iIndex) = 0;
|
||||
|
||||
protected:
|
||||
static LPDIRECTINPUTDEVICE8 ms_lpKeyboard;
|
||||
static bool ms_bPressedKey[256];
|
||||
static char ms_diks[256];
|
||||
};
|
||||
@@ -0,0 +1,599 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare Class
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
//
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Preprocessor
|
||||
#include "StdAfx.h"
|
||||
#include "LensFlare.h"
|
||||
#include "Camera.h"
|
||||
#include "StateManager.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
#include <math.h>
|
||||
using namespace std;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
|
||||
static string g_strFiles[] =
|
||||
{
|
||||
"flare2.dds",
|
||||
"flare1.dds",
|
||||
"flare2.dds",
|
||||
"flare1.dds",
|
||||
"flare6.dds",
|
||||
"flare4.dds",
|
||||
"flare2.dds",
|
||||
"flare3.dds",
|
||||
""
|
||||
};
|
||||
static float g_fPosition[] =
|
||||
{
|
||||
-0.55f,
|
||||
-0.5f,
|
||||
-0.45f,
|
||||
0.2f,
|
||||
0.3f,
|
||||
0.95f,
|
||||
0.9f,
|
||||
1.0f
|
||||
};
|
||||
static float g_fWidth[] =
|
||||
{
|
||||
20.0f,
|
||||
32.0f,
|
||||
20.0f,
|
||||
32.0f,
|
||||
100.0f,
|
||||
32.0f,
|
||||
20.0f,
|
||||
250.0f
|
||||
};
|
||||
|
||||
static float g_afColors[ ][4] =
|
||||
{
|
||||
{ 1.0f, 1.0f, 0.0f, 1.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ 0.0f, 1.0f, 0.0f, 0.8f },
|
||||
{ 0.3f, 0.5f, 1.0f, 0.9f },
|
||||
{ 0.3f, 0.5f, 1.0f, 0.6f },
|
||||
{ 1.0f, 0.6f, 0.9f, 0.4f },
|
||||
{ 1.0f, 0.0f, 0.0f, 0.5f },
|
||||
{ 1.0f, 0.6f, 0.3f, 0.4f }
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::CLensFlare
|
||||
|
||||
CLensFlare::CLensFlare() :
|
||||
m_fSunSize(0),
|
||||
m_fBeforeBright(0.0f),
|
||||
m_fAfterBright(0.0f),
|
||||
m_bFlareVisible(false),
|
||||
m_bDrawFlare(true),
|
||||
m_bDrawBrightScreen(true),
|
||||
m_bEnabled(true),
|
||||
m_bShowMainFlare(true),
|
||||
m_fMaxBrightness(1.0f)
|
||||
{
|
||||
m_pControlPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension];
|
||||
m_pTestPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension];
|
||||
m_afColor[0] = m_afColor[1] = m_afColor[2] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::~CLensFlare
|
||||
|
||||
CLensFlare::~CLensFlare()
|
||||
{
|
||||
delete[] m_pControlPixels;
|
||||
delete[] m_pTestPixels;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::Interpolate
|
||||
|
||||
float CLensFlare::Interpolate(float fStart, float fEnd, float fPercent)
|
||||
{
|
||||
return fStart + (fEnd - fStart) * fPercent;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::DrawBeforeFlare
|
||||
|
||||
void CLensFlare::Compute(const D3DXVECTOR3 & c_rv3LightDirection)
|
||||
{
|
||||
float afSunPos[3];
|
||||
|
||||
D3DXVECTOR3 v3Target = CCameraManager::Instance().GetCurrentCamera()->GetTarget();
|
||||
|
||||
afSunPos[0] = v3Target.x - c_rv3LightDirection.x * 99999999.0f;
|
||||
afSunPos[1] = v3Target.y - c_rv3LightDirection.y * 99999999.0f;
|
||||
afSunPos[2] = v3Target.z - c_rv3LightDirection.z * 99999999.0f;
|
||||
|
||||
float fX, fY;
|
||||
ProjectPosition(afSunPos[0], afSunPos[1], afSunPos[2], &fX, &fY);
|
||||
|
||||
// set flare location
|
||||
SetFlareLocation(fX, fY);
|
||||
|
||||
// determine visibility
|
||||
float fSunVectorMagnitude = sqrtf(afSunPos[0] * afSunPos[0] +
|
||||
afSunPos[1] * afSunPos[1] +
|
||||
afSunPos[2] * afSunPos[2]);
|
||||
float afSunVector[3];
|
||||
afSunVector[0] = -afSunPos[0] / fSunVectorMagnitude;
|
||||
afSunVector[1] = -afSunPos[1] / fSunVectorMagnitude;
|
||||
afSunVector[2] = -afSunPos[2] / fSunVectorMagnitude;
|
||||
|
||||
float afCameraDirection[3];
|
||||
afCameraDirection[0] = ms_matView._13;
|
||||
afCameraDirection[1] = ms_matView._23;
|
||||
afCameraDirection[2] = ms_matView._33;
|
||||
|
||||
|
||||
float fDotProduct =
|
||||
(afSunVector[0] * afCameraDirection[0]) +
|
||||
(afSunVector[1] * afCameraDirection[1]) +
|
||||
(afSunVector[2] * afCameraDirection[2]);
|
||||
|
||||
if (acosf(fDotProduct) < 0.5f * D3DX_PI)
|
||||
SetVisible(true);
|
||||
else
|
||||
SetVisible(false);
|
||||
|
||||
// set flare brightness
|
||||
fX /= ms_Viewport.Width;
|
||||
fY /= ms_Viewport.Height;
|
||||
|
||||
float fDistance = sqrtf(((0.5f - fX) * (0.5f - fX)) + ((0.5f - fY) * (0.5f - fY)));
|
||||
float fBeforeBright = Interpolate(0.0f, c_fHalfMaxBright, 1.0f - (fDistance * c_fDistanceScale));
|
||||
float fAfterBright = Interpolate(0.0f, 1.0f, 1.0f - (fDistance * c_fDistanceScale));
|
||||
|
||||
SetBrightnesses(fBeforeBright, fAfterBright);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::DrawBeforeFlare
|
||||
|
||||
void CLensFlare::DrawBeforeFlare()
|
||||
{
|
||||
if (!m_bFlareVisible || !m_bEnabled || !m_bShowMainFlare)
|
||||
return;
|
||||
|
||||
if (m_SunFlareImageInstance.IsEmpty())
|
||||
return;
|
||||
|
||||
D3DXMATRIX matProj;
|
||||
D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f);
|
||||
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj);
|
||||
STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity);
|
||||
|
||||
D3DXMATRIX matWorld;
|
||||
D3DXMatrixTranslation(&matWorld, m_afFlarePos[0], m_afFlarePos[1], 0.0f);
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); // glShadeModel(GL_FLAT);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
/*
|
||||
if (m_fBeforeBright != 0.0f && m_bDrawFlare && m_bDrawBrightScreen && false) // 왠 false?
|
||||
{
|
||||
glColor4f(1.0f, 1.0f, 1.0f, m_fBeforeBright);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glVertex2f(0.0f, 0.0f);
|
||||
glVertex2f(0.0f, 1.0f);
|
||||
glVertex2f(1.0f, 0.0f);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
glEnd();
|
||||
}
|
||||
*/
|
||||
float fAspectRatio = ms_Viewport.Width / float(ms_Viewport.Height);
|
||||
float fHeight = m_fSunSize * fAspectRatio;
|
||||
D3DXCOLOR color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
SVertex vertices[4];
|
||||
vertices[0].x = -m_fSunSize;
|
||||
vertices[0].y = -fHeight;
|
||||
vertices[0].z = 0.0f;
|
||||
vertices[0].color = color;
|
||||
vertices[0].u = 0.0f;
|
||||
vertices[0].v = 0.0f;
|
||||
|
||||
vertices[1].x = -m_fSunSize;
|
||||
vertices[1].y = fHeight;
|
||||
vertices[1].z = 0.0f;
|
||||
vertices[1].color = color;
|
||||
vertices[1].u = 0.0f;
|
||||
vertices[1].v = 1.0f;
|
||||
|
||||
vertices[2].x = m_fSunSize;
|
||||
vertices[2].y = -fHeight;
|
||||
vertices[2].z = 0.0f;
|
||||
vertices[2].color = color;
|
||||
vertices[2].u = 1.0f;
|
||||
vertices[2].v = 0.0f;
|
||||
|
||||
vertices[3].x = m_fSunSize;
|
||||
vertices[3].y = fHeight;
|
||||
vertices[3].z = 0.0f;
|
||||
vertices[3].color = color;
|
||||
vertices[3].u = 1.0f;
|
||||
vertices[3].v = 1.0f;
|
||||
|
||||
STATEMANAGER.SetTexture(0, m_SunFlareImageInstance.GetTexturePointer()->GetD3DTexture());
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
|
||||
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(SVertex));
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SHADEMODE); // glShadeModel(GL_FLAT);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_VIEW);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::DrawAfterFlare
|
||||
|
||||
void CLensFlare::DrawAfterFlare()
|
||||
{
|
||||
if (m_bEnabled && m_fAfterBright != 0.0f && m_bDrawBrightScreen)
|
||||
{
|
||||
SetDiffuseColor(m_afColor[0], m_afColor[1], m_afColor[2], m_fAfterBright);
|
||||
RenderBar2d(0.0f, 0.0f, 1024.0f, 1024.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::SetMainFlare
|
||||
|
||||
void CLensFlare::SetMainFlare(string strSunFile, float fSunSize)
|
||||
{
|
||||
if (m_bEnabled && m_bShowMainFlare)
|
||||
{
|
||||
m_fSunSize = fSunSize;
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer(strSunFile.c_str());
|
||||
|
||||
if (!pResource->IsType(CGraphicImage::Type()))
|
||||
assert(false);
|
||||
|
||||
m_SunFlareImageInstance.SetImagePointer(static_cast<CGraphicImage *> (pResource));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::DrawFlare
|
||||
|
||||
void CLensFlare::DrawFlare()
|
||||
{
|
||||
if (m_bEnabled && m_bFlareVisible && m_bDrawFlare && m_fAfterBright != 0.0f)
|
||||
{
|
||||
//glPushAttrib(GL_ENABLE_BIT);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); // glDisable(GL_LIGHTING);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND);
|
||||
|
||||
D3DXMATRIX matProj;
|
||||
D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, ms_Viewport.Width, ms_Viewport.Height, 0.0f, -1.0f, 1.0f);
|
||||
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj);
|
||||
STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity);
|
||||
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity);
|
||||
//glMatrixMode(GL_MODELVIEW);
|
||||
//glLoadIdentity();
|
||||
|
||||
//glDisable(GL_TEXTURE_2D);
|
||||
DrawAfterFlare();
|
||||
|
||||
//glEnable(GL_TEXTURE_2D);
|
||||
m_cFlare.Draw(m_fAfterBright,
|
||||
ms_Viewport.Width,
|
||||
ms_Viewport.Height,
|
||||
static_cast<int>(m_afFlareWinPos[0]),
|
||||
static_cast<int>(m_afFlareWinPos[1]));
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); // glDisable(GL_LIGHTING);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_VIEW);
|
||||
//glDisable(GL_TEXTURE_2D);
|
||||
//glPopAttrib();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::CharacterizeFlare
|
||||
void CLensFlare::CharacterizeFlare(bool bEnabled, bool bShowMainFlare, float fMaxBrightness, const D3DXCOLOR & c_rColor)
|
||||
{
|
||||
m_bEnabled = bEnabled;
|
||||
m_bShowMainFlare = bShowMainFlare;
|
||||
m_fMaxBrightness = fMaxBrightness;
|
||||
|
||||
m_afColor[0] = c_rColor.r;
|
||||
m_afColor[1] = c_rColor.g;
|
||||
m_afColor[2] = c_rColor.b;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::Initialize
|
||||
void CLensFlare::Initialize(std::string strPath)
|
||||
{
|
||||
if (m_bEnabled)
|
||||
m_cFlare.Init(strPath);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::SetFlareLocation
|
||||
void CLensFlare::SetFlareLocation(double dX, double dY)
|
||||
{
|
||||
if (m_bEnabled)
|
||||
{
|
||||
m_afFlareWinPos[0] = float(dX);
|
||||
m_afFlareWinPos[1] = float(dY);
|
||||
|
||||
m_afFlarePos[0] = float(dX) / ms_Viewport.Width;
|
||||
m_afFlarePos[1] = float(dY) / ms_Viewport.Height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::SetBrightnesses
|
||||
|
||||
void CLensFlare::SetBrightnesses(float fBeforeBright, float fAfterBright)
|
||||
{
|
||||
if (m_bEnabled)
|
||||
{
|
||||
m_fBeforeBright = fBeforeBright;
|
||||
m_fAfterBright = fAfterBright;
|
||||
|
||||
ClampBrightness();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::ReadControlPixels
|
||||
|
||||
void CLensFlare::ReadControlPixels()
|
||||
{
|
||||
if (m_bEnabled)
|
||||
ReadDepthPixels(m_pControlPixels);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::AdjustBrightness
|
||||
|
||||
void CLensFlare::AdjustBrightness()
|
||||
{
|
||||
if (m_bEnabled)
|
||||
{
|
||||
ReadDepthPixels(m_pTestPixels);
|
||||
|
||||
int nDifferent = 0;
|
||||
|
||||
for (int i = 0; i < c_nDepthTestDimension * c_nDepthTestDimension; ++i)
|
||||
if (m_pTestPixels[i] != m_pControlPixels[i])
|
||||
++nDifferent;
|
||||
|
||||
float fAdjust = (static_cast<float>(nDifferent) / (c_nDepthTestDimension * c_nDepthTestDimension));
|
||||
fAdjust = sqrtf(fAdjust) * 0.85f;
|
||||
m_fAfterBright *= 1.0f - fAdjust;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::ReadDepthPixels
|
||||
|
||||
void CLensFlare::ReadDepthPixels(float * /*pPixels*/)
|
||||
{
|
||||
/*
|
||||
LPDIRECT3DSURFACE8 lpSurface;
|
||||
if (FAILED(ms_lpd3dDevice->GetDepthStencilSurface(&lpSurface)))
|
||||
assert(false);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
lpSurface->LockRect(&rect, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE);
|
||||
|
||||
lpSurface->UnlockRect();
|
||||
*/
|
||||
/*
|
||||
glReadPixels(GLint(m_afFlareWinPos[0] - c_nDepthTestDimension / 2),
|
||||
GLint(m_afFlareWinPos[1] - c_nDepthTestDimension / 2),
|
||||
c_nDepthTestDimension, c_nDepthTestDimension,
|
||||
GL_DEPTH_COMPONENT, GL_FLOAT, pPixels);
|
||||
*/
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare::ClampBrightness
|
||||
|
||||
void CLensFlare::ClampBrightness()
|
||||
{
|
||||
// before
|
||||
if (m_fBeforeBright < 0.0f)
|
||||
m_fBeforeBright = 0.0f;
|
||||
else if (m_fBeforeBright > 1.0f)
|
||||
m_fBeforeBright = 1.0f;
|
||||
|
||||
m_fBeforeBright *= m_fMaxBrightness;
|
||||
|
||||
if (m_fAfterBright < 0.0f)
|
||||
m_fAfterBright = 0.0f;
|
||||
else if (m_fAfterBright > 1.0f)
|
||||
m_fAfterBright = 1.0f;
|
||||
|
||||
m_fAfterBright *= m_fMaxBrightness;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CFlare implementation
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CFlare::CFlare
|
||||
|
||||
CFlare::CFlare()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CFlare::~CFlare
|
||||
|
||||
CFlare::~CFlare()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CFlare::Init
|
||||
|
||||
void CFlare::Init(std::string strPath)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (g_strFiles[i] != "")
|
||||
{
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer((strPath + "/" + string(g_strFiles[i])).c_str());
|
||||
|
||||
if (!pResource->IsType(CGraphicImage::Type()))
|
||||
assert(false);
|
||||
|
||||
SFlarePiece * pPiece = new SFlarePiece;
|
||||
|
||||
pPiece->m_imageInstance.SetImagePointer(static_cast<CGraphicImage *> (pResource));
|
||||
pPiece->m_fPosition = g_fPosition[i];
|
||||
pPiece->m_fWidth = g_fWidth[i];
|
||||
pPiece->m_pColor = g_afColors[i];
|
||||
|
||||
m_vFlares.push_back(pPiece);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CFlare::Draw
|
||||
void CFlare::Draw(float fBrightScale, int nWidth, int nHeight, int nX, int nY)
|
||||
{
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
||||
|
||||
float fDX = float(nX) - float(nWidth) / 2.0f;
|
||||
float fDY = float(nY) - float(nHeight) / 2.0f;
|
||||
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
|
||||
for (unsigned int i = 0; i < m_vFlares.size(); i++)
|
||||
{
|
||||
float fCenterX = float(nX) - (m_vFlares[i]->m_fPosition + 1.0f) * fDX;
|
||||
float fCenterY = float(nY) - (m_vFlares[i]->m_fPosition + 1.0f) * fDY;
|
||||
float fW = m_vFlares[i]->m_fWidth;
|
||||
|
||||
D3DXCOLOR d3dColor(m_vFlares[i]->m_pColor[0] * fBrightScale,
|
||||
m_vFlares[i]->m_pColor[1] * fBrightScale,
|
||||
m_vFlares[i]->m_pColor[2] * fBrightScale,
|
||||
m_vFlares[i]->m_pColor[3] * fBrightScale);
|
||||
|
||||
STATEMANAGER.SetTexture(0, m_vFlares[i]->m_imageInstance.GetTexturePointer()->GetD3DTexture());
|
||||
|
||||
TVertex vertices[4];
|
||||
|
||||
vertices[0].u = 0.0f;
|
||||
vertices[0].v = 0.0f;
|
||||
vertices[0].x = fCenterX - fW;
|
||||
vertices[0].y = fCenterY - fW;
|
||||
vertices[0].z = 0.0f;
|
||||
vertices[0].color = d3dColor;
|
||||
|
||||
vertices[1].u = 0.0f;
|
||||
vertices[1].v = 1.0f;
|
||||
vertices[1].x = fCenterX - fW;
|
||||
vertices[1].y = fCenterY + fW;
|
||||
vertices[1].z = 0.0f;
|
||||
vertices[1].color = d3dColor;
|
||||
|
||||
vertices[2].u = 1.0f;
|
||||
vertices[2].v = 0.0f;
|
||||
vertices[2].x = fCenterX + fW;
|
||||
vertices[2].y = fCenterY - fW;
|
||||
vertices[2].z = 0.0f;
|
||||
vertices[2].color = d3dColor;
|
||||
|
||||
vertices[3].u = 1.0f;
|
||||
vertices[3].v = 1.0f;
|
||||
vertices[3].x = fCenterX + fW;
|
||||
vertices[3].y = fCenterY + fW;
|
||||
vertices[3].z = 0.0f;
|
||||
vertices[3].color = d3dColor;
|
||||
|
||||
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(TVertex));
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare Class
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
//
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Preprocessor
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GrpImageInstance.h"
|
||||
#include "GrpScreen.h"
|
||||
|
||||
#include <float.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Constants
|
||||
|
||||
const float c_fHalfMaxBright = 0.45f;
|
||||
const float c_fDistanceScale = 1.0f;
|
||||
const int c_nDepthTestDimension = 15;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CFlare
|
||||
|
||||
class CFlare
|
||||
{
|
||||
public:
|
||||
void Draw(float fBrightScale, int nWidth, int nHeight, int nX, int nY);
|
||||
void Init(std::string strPath);
|
||||
|
||||
CFlare();
|
||||
virtual ~CFlare();
|
||||
|
||||
private:
|
||||
struct SFlarePiece
|
||||
{
|
||||
SFlarePiece() :
|
||||
m_fPosition(0.0f),
|
||||
m_fWidth(0.0f),
|
||||
m_pColor(NULL)
|
||||
{
|
||||
}
|
||||
CGraphicImageInstance m_imageInstance;
|
||||
float m_fPosition; // -1.0 = light location, 0.0 = center, 1.0 = far end of flare
|
||||
float m_fWidth; // height = width
|
||||
float * m_pColor;
|
||||
};
|
||||
|
||||
std::vector<SFlarePiece *> m_vFlares;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLensFlare
|
||||
class CLensFlare : public CScreen
|
||||
{
|
||||
public:
|
||||
CLensFlare();
|
||||
virtual ~CLensFlare();
|
||||
|
||||
void Compute(const D3DXVECTOR3 & c_rv3LightDirection); // D3DTS_VIEW로 부터 카메라 방향을 얻어오므로, 카메라 설정 뒤에 해야 함.
|
||||
|
||||
void DrawBeforeFlare();
|
||||
void DrawAfterFlare();
|
||||
void DrawFlare();
|
||||
|
||||
void SetMainFlare(std::string strSunFile, float fSunSize);
|
||||
void Initialize(std::string strPath);
|
||||
|
||||
void SetFlareLocation(double dX, double dY);
|
||||
|
||||
void SetVisible(bool bState) { m_bFlareVisible = bState; }
|
||||
bool IsVisible() { return m_bFlareVisible; }
|
||||
|
||||
void SetBrightnesses(float fBeforeBright, float fAfterBright);
|
||||
|
||||
void ReadControlPixels();
|
||||
void AdjustBrightness();
|
||||
|
||||
void CharacterizeFlare(bool bEnabled, bool bShowMainFlare, float fMaxBrightness, const D3DXCOLOR & c_rColor);
|
||||
|
||||
protected:
|
||||
float Interpolate(float fStart, float fEnd, float fPercent);
|
||||
|
||||
private:
|
||||
float m_afFlarePos[2], m_afFlareWinPos[2];
|
||||
float m_fBeforeBright, m_fAfterBright;
|
||||
bool m_bFlareVisible, m_bDrawFlare, m_bDrawBrightScreen;
|
||||
float m_fSunSize;
|
||||
CFlare m_cFlare;
|
||||
float * m_pControlPixels;
|
||||
float * m_pTestPixels;
|
||||
bool m_bEnabled;
|
||||
bool m_bShowMainFlare;
|
||||
float m_fMaxBrightness;
|
||||
float m_afColor[4];
|
||||
|
||||
CGraphicImageInstance m_SunFlareImageInstance;
|
||||
|
||||
void ReadDepthPixels(float * pPixels);
|
||||
void ClampBrightness();
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "MSWindow.h"
|
||||
|
||||
class CMSApplication : public CMSWindow
|
||||
{
|
||||
public:
|
||||
CMSApplication();
|
||||
virtual ~CMSApplication();
|
||||
|
||||
void Initialize(HINSTANCE hInstance);
|
||||
|
||||
void MessageLoop();
|
||||
|
||||
bool IsMessage();
|
||||
bool MessageProcess();
|
||||
|
||||
protected:
|
||||
void ClearWindowClass();
|
||||
|
||||
LRESULT WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EterBase/Stl.h"
|
||||
|
||||
class CMSWindow
|
||||
{
|
||||
public:
|
||||
CMSWindow();
|
||||
|
||||
virtual ~CMSWindow();
|
||||
|
||||
void Destroy();
|
||||
bool Create(const char* c_szName, int brush=BLACK_BRUSH, DWORD cs=0, DWORD ws=WS_OVERLAPPEDWINDOW, HICON hIcon=NULL, int iCursorResource=32512);
|
||||
|
||||
void Show();
|
||||
void Hide();
|
||||
|
||||
void SetVisibleMode(bool isVisible);
|
||||
|
||||
void SetPosition(int x, int y);
|
||||
void SetCenterPosition();
|
||||
|
||||
void SetText(const char* c_szText);
|
||||
|
||||
void AdjustSize(int width, int height);
|
||||
void SetSize(int width, int height);
|
||||
|
||||
bool IsVisible();
|
||||
bool IsActive();
|
||||
|
||||
void GetMousePosition(POINT* ppt);
|
||||
void GetClientRect(RECT* prc);
|
||||
void GetWindowRect(RECT* prc);
|
||||
|
||||
int GetScreenWidth();
|
||||
int GetScreenHeight();
|
||||
|
||||
HWND GetWindowHandle();
|
||||
HINSTANCE GetInstance();
|
||||
|
||||
virtual LRESULT WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
||||
virtual void OnSize(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
const char* RegisterWindowClass(DWORD style, int brush, WNDPROC pfnWndProc, HICON hIcon=NULL, int iCursorResource=32512);
|
||||
|
||||
protected:
|
||||
typedef std::set<char*, stl_sz_less> TWindowClassSet;
|
||||
|
||||
protected:
|
||||
HWND m_hWnd;
|
||||
RECT m_rect;
|
||||
bool m_isActive;
|
||||
bool m_isVisible;
|
||||
|
||||
protected:
|
||||
static TWindowClassSet ms_stWCSet;
|
||||
static HINSTANCE ms_hInstance;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef __INC_ETERLIB_MUTEX_H__
|
||||
#define __INC_ETERLIB_MUTEX_H__
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool Trylock();
|
||||
|
||||
private:
|
||||
CRITICAL_SECTION lock;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
#include "StdAfx.h"
|
||||
#include "NetAddress.h"
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
|
||||
bool CNetworkAddress::GetHostName(char* szName, int size)
|
||||
{
|
||||
if (gethostname(szName, size)==SOCKET_ERROR)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
CNetworkAddress::CNetworkAddress()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CNetworkAddress::~CNetworkAddress()
|
||||
{
|
||||
}
|
||||
|
||||
CNetworkAddress::operator const SOCKADDR_IN&() const
|
||||
{
|
||||
return m_sockAddrIn;
|
||||
}
|
||||
|
||||
void CNetworkAddress::Clear()
|
||||
{
|
||||
memset(&m_sockAddrIn, 0, sizeof(m_sockAddrIn));
|
||||
m_sockAddrIn.sin_family=AF_INET;
|
||||
}
|
||||
|
||||
bool CNetworkAddress::IsIP(const char* c_szAddr)
|
||||
{
|
||||
if (c_szAddr[0]<'0' || c_szAddr[0]>'9')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CNetworkAddress::Set(const char* c_szAddr, int port)
|
||||
{
|
||||
if (IsIP(c_szAddr))
|
||||
{
|
||||
SetIP(c_szAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SetDNS(c_szAddr))
|
||||
return false;
|
||||
}
|
||||
|
||||
SetPort(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CNetworkAddress::SetLocalIP()
|
||||
{
|
||||
SetIP(INADDR_ANY);
|
||||
}
|
||||
|
||||
void CNetworkAddress::SetIP(DWORD ip)
|
||||
{
|
||||
m_sockAddrIn.sin_addr.s_addr=htonl(ip);
|
||||
}
|
||||
|
||||
void CNetworkAddress::SetIP(const char* c_szIP)
|
||||
{
|
||||
m_sockAddrIn.sin_addr.s_addr=inet_addr(c_szIP);
|
||||
}
|
||||
|
||||
bool CNetworkAddress::SetDNS(const char* c_szDNS)
|
||||
{
|
||||
HOSTENT* pHostent=gethostbyname(c_szDNS);
|
||||
if (!pHostent) return false;
|
||||
memcpy(&m_sockAddrIn.sin_addr, pHostent->h_addr, sizeof(m_sockAddrIn.sin_addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CNetworkAddress::SetPort(int port)
|
||||
{
|
||||
m_sockAddrIn.sin_port = htons(port);
|
||||
}
|
||||
|
||||
int CNetworkAddress::GetSize()
|
||||
{
|
||||
return sizeof(m_sockAddrIn);
|
||||
}
|
||||
|
||||
DWORD CNetworkAddress::GetIP()
|
||||
{
|
||||
return ntohl(m_sockAddrIn.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
void CNetworkAddress::GetIP(char* szIP, int len)
|
||||
{
|
||||
BYTE IPs[4];
|
||||
*((DWORD*)IPs)=m_sockAddrIn.sin_addr.s_addr;
|
||||
|
||||
_snprintf(szIP, len, "%d.%d.%d.%d", IPs[0], IPs[1], IPs[2], IPs[3]);
|
||||
}
|
||||
|
||||
int CNetworkAddress::GetPort()
|
||||
{
|
||||
return ntohs(m_sockAddrIn.sin_port);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
|
||||
class CNetworkAddress
|
||||
{
|
||||
public:
|
||||
static bool GetHostName(char* szName, int size);
|
||||
|
||||
public:
|
||||
CNetworkAddress();
|
||||
~CNetworkAddress();
|
||||
|
||||
void Clear();
|
||||
|
||||
bool Set(const char* c_szAddr, int port);
|
||||
|
||||
void SetLocalIP();
|
||||
void SetIP(DWORD ip);
|
||||
void SetIP(const char* c_szIP);
|
||||
bool SetDNS(const char* c_szDNS);
|
||||
|
||||
void SetPort(int port);
|
||||
|
||||
int GetPort();
|
||||
int GetSize();
|
||||
|
||||
void GetIP(char* szIP, int len);
|
||||
|
||||
DWORD GetIP();
|
||||
|
||||
operator const SOCKADDR_IN&() const;
|
||||
|
||||
|
||||
private:
|
||||
bool IsIP(const char* c_szAddr);
|
||||
|
||||
private:
|
||||
SOCKADDR_IN m_sockAddrIn;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "StdAfx.h"
|
||||
#include "NetDatagram.h"
|
||||
|
||||
CNetworkDatagram::CNetworkDatagram()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CNetworkDatagram::~CNetworkDatagram()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CNetworkDatagram::Destroy()
|
||||
{
|
||||
if (INVALID_SOCKET==m_sock)
|
||||
return;
|
||||
|
||||
closesocket(m_sock);
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
bool CNetworkDatagram::Create(UINT uPort)
|
||||
{
|
||||
assert(INVALID_SOCKET==m_sock);
|
||||
m_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
DWORD arg = 1;
|
||||
ioctlsocket(m_sock, FIONBIO, &arg); // Non-blocking mode
|
||||
|
||||
SOCKADDR_IN sockAddrIn;
|
||||
memset(&sockAddrIn, 0, sizeof(SOCKADDR_IN));
|
||||
sockAddrIn.sin_family = AF_INET;
|
||||
sockAddrIn.sin_addr.s_addr = INADDR_ANY;
|
||||
sockAddrIn.sin_port = htons(uPort);
|
||||
|
||||
if (SOCKET_ERROR == bind(m_sock, (PSOCKADDR)&sockAddrIn, sizeof(SOCKADDR_IN)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
void CNetworkDatagram::Update()
|
||||
{
|
||||
if (m_sock == INVALID_SOCKET)
|
||||
return;
|
||||
|
||||
FD_ZERO(&m_fdsRecv);
|
||||
FD_ZERO(&m_fdsSend);
|
||||
|
||||
FD_SET(m_sock, &m_fdsRecv);
|
||||
FD_SET(m_sock, &m_fdsSend);
|
||||
|
||||
TIMEVAL delay;
|
||||
|
||||
delay.tv_sec = 0;
|
||||
delay.tv_usec = 0;
|
||||
|
||||
if (select(0, &m_fdsRecv, &m_fdsSend, NULL, &delay) == SOCKET_ERROR)
|
||||
return;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
bool CNetworkDatagram::CanRecv()
|
||||
{
|
||||
if (FD_ISSET(m_sock, &m_fdsRecv))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int CNetworkDatagram::PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn)
|
||||
{
|
||||
int nSockAddrInLen=sizeof(SOCKADDR_IN);
|
||||
return recvfrom(m_sock, (char*)pvBuf, uBufLen, MSG_PEEK, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen);
|
||||
}
|
||||
|
||||
int CNetworkDatagram::RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn)
|
||||
{
|
||||
int nSockAddrInLen=sizeof(SOCKADDR_IN);
|
||||
return recvfrom(m_sock, (char*)pvBuf, uBufLen, 0, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen);
|
||||
}
|
||||
|
||||
int CNetworkDatagram::SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn)
|
||||
{
|
||||
return sendto(m_sock, (const char *)c_pvBuf, uBufLen, 0, (PSOCKADDR)&c_rkSockAddrIn, sizeof(SOCKADDR_IN));
|
||||
}
|
||||
|
||||
|
||||
void CNetworkDatagram::__Initialize()
|
||||
{
|
||||
m_sock=INVALID_SOCKET;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
class CNetworkDatagram
|
||||
{
|
||||
public:
|
||||
CNetworkDatagram();
|
||||
virtual ~CNetworkDatagram();
|
||||
|
||||
void Destroy();
|
||||
bool Create(UINT uPort);
|
||||
|
||||
void Update();
|
||||
|
||||
bool CanRecv();
|
||||
|
||||
int PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn);
|
||||
int RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn);
|
||||
int SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn);
|
||||
|
||||
private:
|
||||
void __Initialize();
|
||||
|
||||
private:
|
||||
SOCKET m_sock;
|
||||
|
||||
fd_set m_fdsRecv;
|
||||
fd_set m_fdsSend;
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "StdAfx.h"
|
||||
#include "NetDatagramReceiver.h"
|
||||
|
||||
BOOL CNetDatagramReceiver::Process()
|
||||
{
|
||||
m_recvBufCurrentPos = 0;
|
||||
m_recvBufCurrentSize = 0;
|
||||
|
||||
int irecvAddrLength = sizeof(SOCKADDR_IN);
|
||||
m_recvBufCurrentSize = recvfrom(m_Socket, (char *)m_recvBuf, m_recvBufSize, 0, (PSOCKADDR)&m_SockAddr, &irecvAddrLength);
|
||||
|
||||
if (m_recvBufCurrentSize <= 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CNetDatagramReceiver::Recv(void * pBuffer, int iSize)
|
||||
{
|
||||
if (!Peek(pBuffer, iSize))
|
||||
return FALSE;
|
||||
|
||||
m_recvBufCurrentPos += iSize;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CNetDatagramReceiver::Peek(void * pBuffer, int iSize)
|
||||
{
|
||||
if (m_recvBufCurrentSize < m_recvBufCurrentPos+iSize)
|
||||
return FALSE;
|
||||
|
||||
memcpy(pBuffer, m_recvBuf + m_recvBufCurrentPos, iSize);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CNetDatagramReceiver::isBind()
|
||||
{
|
||||
return m_isBind;
|
||||
}
|
||||
|
||||
BOOL CNetDatagramReceiver::Bind(DWORD /*dwAddress*/, WORD wPortIndex)
|
||||
{
|
||||
m_Socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
DWORD arg = 1;
|
||||
ioctlsocket(m_Socket, FIONBIO, &arg); // Non-blocking mode
|
||||
|
||||
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
|
||||
m_SockAddr.sin_family = AF_INET;
|
||||
// m_SockAddr.sin_addr.s_addr = dwAddress;
|
||||
m_SockAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
m_SockAddr.sin_port = htons(wPortIndex);
|
||||
|
||||
if (bind(m_Socket, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN)) < 0)
|
||||
{
|
||||
Tracef("Failed binding socket\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_isBind = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CNetDatagramReceiver::SetRecvBufferSize(int recvBufSize)
|
||||
{
|
||||
if (m_recvBuf)
|
||||
{
|
||||
if (m_recvBufSize>recvBufSize)
|
||||
return;
|
||||
|
||||
delete [] m_recvBuf;
|
||||
}
|
||||
m_recvBufSize=recvBufSize;
|
||||
m_recvBuf=new char[m_recvBufSize];
|
||||
}
|
||||
|
||||
void CNetDatagramReceiver::Clear()
|
||||
{
|
||||
|
||||
m_isBind = FALSE;
|
||||
|
||||
m_dwPortIndex = 1000;
|
||||
|
||||
m_Socket = 0;
|
||||
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
|
||||
|
||||
m_recvBufCurrentPos = 0;
|
||||
m_recvBufCurrentSize = 0;
|
||||
}
|
||||
|
||||
CNetDatagramReceiver::CNetDatagramReceiver()
|
||||
{
|
||||
m_recvBuf = NULL;
|
||||
m_recvBufSize = 0;
|
||||
|
||||
Clear();
|
||||
}
|
||||
CNetDatagramReceiver::~CNetDatagramReceiver()
|
||||
{
|
||||
if (m_recvBuf)
|
||||
delete [] m_recvBuf;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
|
||||
class CNetDatagramReceiver
|
||||
{
|
||||
public:
|
||||
CNetDatagramReceiver();
|
||||
virtual ~CNetDatagramReceiver();
|
||||
|
||||
void Clear();
|
||||
BOOL Bind(DWORD dwAddress, WORD wPortIndex);
|
||||
BOOL isBind();
|
||||
|
||||
BOOL Process();
|
||||
BOOL Recv(void * pBuffer, int iSize);
|
||||
BOOL Peek(void * pBuffer, int iSize);
|
||||
|
||||
void SetRecvBufferSize(int recvBufSize);
|
||||
|
||||
protected:
|
||||
BOOL m_isBind;
|
||||
|
||||
DWORD m_dwPortIndex;
|
||||
|
||||
SOCKET m_Socket;
|
||||
SOCKADDR_IN m_SockAddr;
|
||||
|
||||
int m_recvBufCurrentPos;
|
||||
int m_recvBufCurrentSize;
|
||||
|
||||
char* m_recvBuf;
|
||||
int m_recvBufSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "StdAfx.h"
|
||||
#include "NetDatagramSender.h"
|
||||
|
||||
BOOL CNetDatagramSender::SetSocket(const char * c_szIP, WORD wPortIndex)
|
||||
{
|
||||
return SetSocket(inet_addr(c_szIP), wPortIndex);
|
||||
}
|
||||
|
||||
BOOL CNetDatagramSender::SetSocket(DWORD dwAddress, WORD wPortIndex)
|
||||
{
|
||||
m_isSocket = TRUE;
|
||||
|
||||
m_dwAddress = dwAddress;
|
||||
m_wPortIndex = wPortIndex;
|
||||
|
||||
m_Socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
|
||||
m_SockAddr.sin_family = AF_INET;
|
||||
m_SockAddr.sin_addr.s_addr = dwAddress;
|
||||
m_SockAddr.sin_port = htons(wPortIndex);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CNetDatagramSender::Send(const void * pBuffer, int iSize)
|
||||
{
|
||||
assert(isSocket());
|
||||
|
||||
int iSendingLength = sendto(m_Socket, (const char *)pBuffer, iSize, 0, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN));
|
||||
if (iSendingLength < 0)
|
||||
{
|
||||
Tracef("Failed sending packet\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CNetDatagramSender::isSocket()
|
||||
{
|
||||
return m_isSocket;
|
||||
}
|
||||
|
||||
CNetDatagramSender::CNetDatagramSender()
|
||||
{
|
||||
m_isSocket = FALSE;
|
||||
|
||||
m_dwAddress = 0;
|
||||
m_wPortIndex = 1000;
|
||||
|
||||
m_Socket = 0;
|
||||
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
|
||||
}
|
||||
|
||||
CNetDatagramSender::~CNetDatagramSender()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
|
||||
class CNetDatagramSender
|
||||
{
|
||||
public:
|
||||
CNetDatagramSender();
|
||||
virtual ~CNetDatagramSender();
|
||||
|
||||
BOOL isSocket();
|
||||
|
||||
BOOL SetSocket(const char * c_szIP, WORD wPortIndex);
|
||||
BOOL SetSocket(DWORD dwAddress, WORD wPortIndex);
|
||||
BOOL Send(const void * pBuffer, int iSize);
|
||||
|
||||
protected:
|
||||
BOOL m_isSocket;
|
||||
|
||||
WORD m_dwAddress;
|
||||
WORD m_wPortIndex;
|
||||
|
||||
SOCKET m_Socket;
|
||||
SOCKADDR_IN m_SockAddr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "StdAfx.h"
|
||||
#include "NetDevice.h"
|
||||
|
||||
CNetworkDevice::CNetworkDevice()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CNetworkDevice::~CNetworkDevice()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CNetworkDevice::Initialize()
|
||||
{
|
||||
m_isWSA=false;
|
||||
}
|
||||
|
||||
void CNetworkDevice::Destroy()
|
||||
{
|
||||
if (m_isWSA)
|
||||
{
|
||||
WSACleanup();
|
||||
m_isWSA=false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CNetworkDevice::Create()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Initialize();
|
||||
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(1, 1), &wsaData)!=0)
|
||||
return false;
|
||||
|
||||
m_isWSA=true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
class CNetworkDevice
|
||||
{
|
||||
public:
|
||||
CNetworkDevice();
|
||||
virtual ~CNetworkDevice();
|
||||
|
||||
void Destroy();
|
||||
bool Create();
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
bool m_isWSA;
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "StdAfx.h"
|
||||
#include "NetPacketHeaderMap.h"
|
||||
|
||||
void CNetworkPacketHeaderMap::Set(int header, TPacketType rPacketType)
|
||||
{
|
||||
m_headerMap[header] = rPacketType;
|
||||
}
|
||||
bool CNetworkPacketHeaderMap::Get(int header, TPacketType * pPacketType)
|
||||
{
|
||||
std::map<int, TPacketType>::iterator f=m_headerMap.find(header);
|
||||
|
||||
if (m_headerMap.end()==f)
|
||||
return false;
|
||||
|
||||
*pPacketType = f->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CNetworkPacketHeaderMap::CNetworkPacketHeaderMap()
|
||||
{
|
||||
}
|
||||
|
||||
CNetworkPacketHeaderMap::~CNetworkPacketHeaderMap()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
class CNetworkPacketHeaderMap
|
||||
{
|
||||
public:
|
||||
typedef struct SPacketType
|
||||
{
|
||||
SPacketType(int iSize = 0, bool bFlag = false)
|
||||
{
|
||||
iPacketSize = iSize;
|
||||
isDynamicSizePacket = bFlag;
|
||||
}
|
||||
|
||||
int iPacketSize;
|
||||
bool isDynamicSizePacket;
|
||||
} TPacketType;
|
||||
|
||||
public:
|
||||
CNetworkPacketHeaderMap();
|
||||
virtual ~CNetworkPacketHeaderMap();
|
||||
|
||||
void Set(int header, TPacketType rPacketType);
|
||||
bool Get(int header, TPacketType * pPacketType);
|
||||
|
||||
protected:
|
||||
std::map<int, TPacketType> m_headerMap;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
#include "../EterBase/cipher.h"
|
||||
#endif
|
||||
#include "../EterBase/tea.h"
|
||||
#include "NetAddress.h"
|
||||
|
||||
class CNetworkStream
|
||||
{
|
||||
public:
|
||||
CNetworkStream();
|
||||
virtual ~CNetworkStream();
|
||||
|
||||
void SetRecvBufferSize(int recvBufSize);
|
||||
void SetSendBufferSize(int sendBufSize);
|
||||
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
void SetSecurityMode(bool isSecurityMode, const char* c_szTeaKey);
|
||||
void SetSecurityMode(bool isSecurityMode, const char* c_szTeaEncryptKey, const char* c_szTeaDecryptKey);
|
||||
#endif
|
||||
bool IsSecurityMode();
|
||||
|
||||
int GetRecvBufferSize();
|
||||
|
||||
void Clear();
|
||||
void ClearRecvBuffer();
|
||||
|
||||
void Process();
|
||||
|
||||
bool Connect(const CNetworkAddress& c_rkNetAddr, int limitSec = 3);
|
||||
bool Connect(const char* c_szAddr, int port, int limitSec = 3);
|
||||
bool Connect(DWORD dwAddr, int port, int limitSec = 3);
|
||||
void Disconnect();
|
||||
|
||||
bool Peek(int len);
|
||||
bool Peek(int len, char* pDestBuf);
|
||||
bool Recv(int len);
|
||||
bool Recv(int len, char* pDestBuf);
|
||||
bool Send(int len, const char* pSrcBuf);
|
||||
|
||||
bool Peek(int len, void* pDestBuf);
|
||||
bool Recv(int len, void* pDestBuf);
|
||||
|
||||
bool Send(int len, const void* pSrcBuf);
|
||||
bool SendFlush(int len, const void* pSrcBuf);
|
||||
|
||||
bool IsOnline();
|
||||
|
||||
void SetPacketSequenceMode(bool isOn);
|
||||
bool SendSequence();
|
||||
|
||||
protected:
|
||||
virtual void OnConnectSuccess();
|
||||
virtual void OnConnectFailure();
|
||||
virtual void OnRemoteDisconnect();
|
||||
virtual void OnDisconnect();
|
||||
virtual bool OnProcess();
|
||||
|
||||
bool __SendInternalBuffer();
|
||||
bool __RecvInternalBuffer();
|
||||
|
||||
void __PopSendBuffer();
|
||||
|
||||
int __GetSendBufferSize();
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
size_t Prepare(void* buffer, size_t* length);
|
||||
bool Activate(size_t agreed_length, const void* buffer, size_t length);
|
||||
void ActivateCipher();
|
||||
#endif
|
||||
|
||||
private:
|
||||
time_t m_connectLimitTime;
|
||||
|
||||
char* m_recvTEABuf;
|
||||
int m_recvTEABufInputPos;
|
||||
int m_recvTEABufSize;
|
||||
|
||||
char* m_recvBuf;
|
||||
int m_recvBufSize;
|
||||
int m_recvBufInputPos;
|
||||
int m_recvBufOutputPos;
|
||||
|
||||
char* m_sendBuf;
|
||||
int m_sendBufSize;
|
||||
int m_sendBufInputPos;
|
||||
int m_sendBufOutputPos;
|
||||
|
||||
char* m_sendTEABuf;
|
||||
int m_sendTEABufSize;
|
||||
int m_sendTEABufInputPos;
|
||||
|
||||
bool m_isOnline;
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
Cipher m_cipher;
|
||||
#else
|
||||
// Obsolete encryption stuff here
|
||||
bool m_isSecurityMode;
|
||||
char m_szEncryptKey[TEA_KEY_LENGTH]; // Client 에서 보낼 패킷을 Encrypt 할때 사용하는 Key
|
||||
char m_szDecryptKey[TEA_KEY_LENGTH]; // Server 에서 전송된 패킷을 Decrypt 할때 사용하는 Key
|
||||
#endif
|
||||
|
||||
SOCKET m_sock;
|
||||
|
||||
CNetworkAddress m_addr;
|
||||
|
||||
// Sequence
|
||||
DWORD m_iSequence;
|
||||
bool m_bUseSequence;
|
||||
std::vector<BYTE> m_kVec_bSequenceTable;
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "StdAfx.h"
|
||||
#include "PathStack.h"
|
||||
|
||||
CPathStack::CPathStack()
|
||||
{
|
||||
SetBase();
|
||||
}
|
||||
|
||||
CPathStack::~CPathStack()
|
||||
{
|
||||
MoveBase();
|
||||
}
|
||||
|
||||
void CPathStack::GetCurrentPathName(std::string* pstCurPathName)
|
||||
{
|
||||
assert(pstCurPathName!=NULL);
|
||||
|
||||
char szPathName[MAX_PATH+1];
|
||||
_getcwd(szPathName, MAX_PATH);
|
||||
|
||||
*pstCurPathName = szPathName;
|
||||
}
|
||||
|
||||
void CPathStack::Push()
|
||||
{
|
||||
char szPathName[MAX_PATH+1];
|
||||
_getcwd(szPathName, MAX_PATH);
|
||||
|
||||
m_stPathNameDeque.push_front(szPathName);
|
||||
}
|
||||
|
||||
bool CPathStack::Pop()
|
||||
{
|
||||
if (m_stPathNameDeque.empty())
|
||||
{
|
||||
assert(!"CPathStack::Pop Empty Stack");
|
||||
return false;
|
||||
}
|
||||
|
||||
_chdir(m_stPathNameDeque.front().c_str());
|
||||
m_stPathNameDeque.pop_front();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPathStack::MoveBase()
|
||||
{
|
||||
_chdir(m_stBasePathName.c_str());
|
||||
}
|
||||
|
||||
void CPathStack::SetBase()
|
||||
{
|
||||
GetCurrentPathName(&m_stBasePathName);
|
||||
}
|
||||
|
||||
void CPathStack::Move(const char* c_szPathName)
|
||||
{
|
||||
_chdir(c_szPathName);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
class CPathStack
|
||||
{
|
||||
public:
|
||||
CPathStack();
|
||||
virtual ~CPathStack();
|
||||
|
||||
void SetBase();
|
||||
|
||||
void MoveBase();
|
||||
|
||||
void Push();
|
||||
|
||||
bool Pop();
|
||||
|
||||
void Move(const char* c_szPathName);
|
||||
void GetCurrentPathName(std::string* pstCurPathName);
|
||||
|
||||
protected:
|
||||
std::string m_stBasePathName;
|
||||
std::deque<std::string> m_stPathNameDeque;
|
||||
};
|
||||
@@ -0,0 +1,685 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EterBase/Debug.h"
|
||||
#include <algorithm> // PORT: std::find below; MSVC's headers pulled it in transitively
|
||||
|
||||
//#define DYNAMIC_POOL_STRICT
|
||||
|
||||
template<typename T>
|
||||
class CDynamicPool
|
||||
{
|
||||
public:
|
||||
CDynamicPool()
|
||||
{
|
||||
//Tracen(typeid(T).name());
|
||||
m_uInitCapacity=0;
|
||||
m_uUsedCapacity=0;
|
||||
}
|
||||
virtual ~CDynamicPool()
|
||||
{
|
||||
assert(m_kVct_pkData.empty());
|
||||
//#ifdef _DEBUG
|
||||
// char szText[256];
|
||||
// sprintf(szText, "--------------------------------------------------------------------- %s Pool Capacity %d\n", typeid(T).name(), m_uUsedCapacity);
|
||||
// OutputDebugString(szText);
|
||||
// printf(szText);
|
||||
//#endif
|
||||
}
|
||||
|
||||
void SetName(const char* c_szName)
|
||||
{
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
if (!m_kVct_pkData.empty())
|
||||
{
|
||||
char szText[256];
|
||||
sprintf(szText, "--------------------------------------------------------------------- %s Pool Destroy\n", typeid(T).name());
|
||||
OutputDebugString(szText);
|
||||
printf(szText);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
for (auto v : m_kVct_pkData)
|
||||
Delete(v);
|
||||
m_kVct_pkData.clear();
|
||||
m_kVct_pkFree.clear();
|
||||
}
|
||||
|
||||
void Create(UINT uCapacity)
|
||||
{
|
||||
m_uInitCapacity=uCapacity;
|
||||
m_kVct_pkData.reserve(uCapacity);
|
||||
m_kVct_pkFree.reserve(uCapacity);
|
||||
}
|
||||
T* Alloc()
|
||||
{
|
||||
if (m_kVct_pkFree.empty())
|
||||
{
|
||||
T* pkNewData=new T;
|
||||
m_kVct_pkData.push_back(pkNewData);
|
||||
++m_uUsedCapacity;
|
||||
return pkNewData;
|
||||
}
|
||||
|
||||
T* pkFreeData=m_kVct_pkFree.back();
|
||||
m_kVct_pkFree.pop_back();
|
||||
return pkFreeData;
|
||||
}
|
||||
void Free(T* pkData)
|
||||
{
|
||||
#ifdef DYNAMIC_POOL_STRICT
|
||||
assert(__IsValidData(pkData));
|
||||
assert(!__IsFreeData(pkData));
|
||||
#endif
|
||||
m_kVct_pkFree.push_back(pkData);
|
||||
}
|
||||
void FreeAll()
|
||||
{
|
||||
m_kVct_pkFree=m_kVct_pkData;
|
||||
}
|
||||
|
||||
DWORD GetCapacity()
|
||||
{
|
||||
return m_kVct_pkData.size();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool __IsValidData(T* pkData)
|
||||
{
|
||||
if (m_kVct_pkData.end()==std::find(m_kVct_pkData.begin(), m_kVct_pkData.end(), pkData))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool __IsFreeData(T* pkData)
|
||||
{
|
||||
if (m_kVct_pkFree.end()==std::find(m_kVct_pkFree.begin(), m_kVct_pkFree.end(), pkData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Delete(T* pkData)
|
||||
{
|
||||
delete pkData;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<T*> m_kVct_pkData;
|
||||
std::vector<T*> m_kVct_pkFree;
|
||||
|
||||
UINT m_uInitCapacity;
|
||||
UINT m_uUsedCapacity;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class CDynamicPoolEx
|
||||
{
|
||||
public:
|
||||
CDynamicPoolEx()
|
||||
{
|
||||
m_uInitCapacity=0;
|
||||
m_uUsedCapacity=0;
|
||||
}
|
||||
virtual ~CDynamicPoolEx()
|
||||
{
|
||||
assert(m_kVct_pkFree.size()==m_kVct_pkData.size());
|
||||
Destroy();
|
||||
|
||||
#ifdef _DEBUG
|
||||
char szText[256];
|
||||
sprintf(szText, "--------------------------------------------------------------------- %s Pool Capacity %d\n", typeid(T).name(), m_uUsedCapacity);
|
||||
OutputDebugString(szText);
|
||||
printf(szText);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (!m_kVct_pkData.empty())
|
||||
{
|
||||
char szText[256];
|
||||
sprintf(szText, "--------------------------------------------------------------------- %s Pool Destroy\n", typeid(T).name());
|
||||
OutputDebugString(szText);
|
||||
printf(szText);
|
||||
}
|
||||
#endif
|
||||
for (auto v : m_kVct_pkData)
|
||||
Delete(v);
|
||||
m_kVct_pkData.clear();
|
||||
m_kVct_pkFree.clear();
|
||||
}
|
||||
|
||||
void Create(UINT uCapacity)
|
||||
{
|
||||
m_uInitCapacity=uCapacity;
|
||||
m_kVct_pkData.reserve(uCapacity);
|
||||
m_kVct_pkFree.reserve(uCapacity);
|
||||
}
|
||||
T* Alloc()
|
||||
{
|
||||
if (m_kVct_pkFree.empty())
|
||||
{
|
||||
T* pkNewData=New();
|
||||
m_kVct_pkData.push_back(pkNewData);
|
||||
++m_uUsedCapacity;
|
||||
return pkNewData;
|
||||
}
|
||||
|
||||
T* pkFreeData=m_kVct_pkFree.back();
|
||||
m_kVct_pkFree.pop_back();
|
||||
return pkFreeData;
|
||||
}
|
||||
void Free(T* pkData)
|
||||
{
|
||||
#ifdef DYNAMIC_POOL_STRICT
|
||||
assert(__IsValidData(pkData));
|
||||
assert(!__IsFreeData(pkData));
|
||||
#endif
|
||||
m_kVct_pkFree.push_back(pkData);
|
||||
}
|
||||
void FreeAll()
|
||||
{
|
||||
m_kVct_pkFree=m_kVct_pkData;
|
||||
}
|
||||
|
||||
DWORD GetCapacity()
|
||||
{
|
||||
return m_kVct_pkData.size();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool __IsValidData(T* pkData)
|
||||
{
|
||||
if (m_kVct_pkData.end()==std::find(m_kVct_pkData.begin(), m_kVct_pkData.end(), pkData))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool __IsFreeData(T* pkData)
|
||||
{
|
||||
if (m_kVct_pkFree.end()==std::find(m_kVct_pkFree.begin(), m_kVct_pkFree.end(), pkData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static T* New()
|
||||
{
|
||||
return (T*)::operator new(sizeof(T));
|
||||
}
|
||||
static void Delete(T* pkData)
|
||||
{
|
||||
::operator delete(pkData);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<T*> m_kVct_pkData;
|
||||
std::vector<T*> m_kVct_pkFree;
|
||||
|
||||
UINT m_uInitCapacity;
|
||||
UINT m_uUsedCapacity;
|
||||
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CPooledObject
|
||||
{
|
||||
public:
|
||||
CPooledObject()
|
||||
{
|
||||
}
|
||||
virtual ~CPooledObject()
|
||||
{
|
||||
}
|
||||
|
||||
void * operator new(size_t /*mem_size*/) // PORT: was unsigned int (size_t on ILP32 Win32)
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void operator delete(void* pT)
|
||||
{
|
||||
ms_kPool.Free((T*)pT);
|
||||
}
|
||||
|
||||
|
||||
static void DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
}
|
||||
|
||||
static void DeleteAll()
|
||||
{
|
||||
ms_kPool.FreeAll();
|
||||
}
|
||||
|
||||
protected:
|
||||
static CDynamicPoolEx<T> ms_kPool;
|
||||
};
|
||||
|
||||
template <class T> CDynamicPoolEx<T> CPooledObject<T>::ms_kPool;
|
||||
|
||||
/*
|
||||
|
||||
template <class T>
|
||||
class CDynamicSizePool
|
||||
{
|
||||
#define GETPREVP(p) *(T**)((char*)p+sizeof(T))
|
||||
#define GETNEXTP(p) *(T**)((char*)p+sizeof(T)+sizeof(T*))
|
||||
public:
|
||||
CDynamicSizePool()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
virtual ~CDynamicSizePool()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
m_nodes = NULL;
|
||||
m_nodeCount = 0;
|
||||
|
||||
m_pFreeList = NULL;
|
||||
m_pUsedList = NULL;
|
||||
}
|
||||
|
||||
void SetName(const char* c_szName)
|
||||
{
|
||||
m_stName = c_szName;
|
||||
}
|
||||
|
||||
T* Alloc()
|
||||
{
|
||||
void* pnewNode;
|
||||
|
||||
if (m_pFreeList)
|
||||
{
|
||||
pnewNode = m_pFreeList;
|
||||
m_pFreeList = GETNEXTP(m_pFreeList);
|
||||
}
|
||||
else
|
||||
{
|
||||
pnewNode = AllocNode();
|
||||
}
|
||||
|
||||
if (!pnewNode)
|
||||
return NULL;
|
||||
|
||||
if (!m_pUsedList)
|
||||
{
|
||||
m_pUsedList = pnewNode;
|
||||
GETPREVP(m_pUsedList) = NULL;
|
||||
GETNEXTP(m_pUsedList) = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
GETPREVP(m_pUsedList) = (T*) pnewNode;
|
||||
GETNEXTP(pnewNode) = (T*) m_pUsedList;
|
||||
GETPREVP(pnewNode) = NULL;
|
||||
m_pUsedList = pnewNode;
|
||||
}
|
||||
//Tracef("%s Pool Alloc %p\n", m_stName.c_str(), pnewNode);
|
||||
return (T*) pnewNode;
|
||||
}
|
||||
|
||||
void Free(T * pdata)
|
||||
{
|
||||
void* pfreeNode = (void*) pdata;
|
||||
|
||||
if (pfreeNode == m_pUsedList)
|
||||
{
|
||||
if (NULL != (m_pUsedList = GETNEXTP(m_pUsedList)))
|
||||
GETPREVP(m_pUsedList) = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GETNEXTP(pfreeNode))
|
||||
GETPREVP(GETNEXTP(pfreeNode)) = GETPREVP(pfreeNode);
|
||||
|
||||
if (GETPREVP(pfreeNode))
|
||||
GETNEXTP(GETPREVP(pfreeNode)) = GETNEXTP(pfreeNode);
|
||||
}
|
||||
|
||||
GETPREVP(pfreeNode) = NULL;
|
||||
GETNEXTP(pfreeNode) = (T*)m_pFreeList;
|
||||
m_pFreeList = pfreeNode;
|
||||
//Tracef("%s Pool Free\n", m_stName.c_str());
|
||||
}
|
||||
|
||||
void FreeAll()
|
||||
{
|
||||
void * pcurNode;
|
||||
void * pnextNode;
|
||||
|
||||
pcurNode = m_pUsedList;
|
||||
|
||||
while (pcurNode)
|
||||
{
|
||||
pnextNode = GETNEXTP(pcurNode);
|
||||
Free(pcurNode);
|
||||
pcurNode = pnextNode;
|
||||
}
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
void* pcurNode;
|
||||
void* pnextNode;
|
||||
int count = 0;
|
||||
|
||||
pcurNode = m_pFreeList;
|
||||
while (pcurNode)
|
||||
{
|
||||
pnextNode = GETNEXTP(pcurNode);
|
||||
((T*)pcurNode)->~T();
|
||||
::operator delete(pcurNode);
|
||||
pcurNode = pnextNode;
|
||||
++count;
|
||||
}
|
||||
m_pFreeList = NULL;
|
||||
|
||||
pcurNode = m_pUsedList;
|
||||
while (pcurNode)
|
||||
{
|
||||
pnextNode = GETNEXTP(pcurNode);
|
||||
((T*)pcurNode)->~T();
|
||||
::operator delete(pcurNode);
|
||||
pcurNode = pnextNode;
|
||||
++count;
|
||||
}
|
||||
m_pUsedList = NULL;
|
||||
//Tracef("%s Pool Clear %d\n", m_stName.c_str(), count);
|
||||
}
|
||||
|
||||
protected:
|
||||
void* AllocNode()
|
||||
{
|
||||
return ::operator new(sizeof(T)+sizeof(T*)*2);
|
||||
}
|
||||
|
||||
protected:
|
||||
void * m_nodes;
|
||||
void * m_pFreeList;
|
||||
void * m_pUsedList;
|
||||
|
||||
int m_nodeCount;
|
||||
std::string m_stName;
|
||||
#undef GETNEXTP
|
||||
#undef GETPREVP
|
||||
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CPooledObject
|
||||
{
|
||||
public:
|
||||
CPooledObject()
|
||||
{
|
||||
}
|
||||
virtual ~CPooledObject()
|
||||
{
|
||||
}
|
||||
|
||||
void * operator new(unsigned int mem_size)
|
||||
{
|
||||
return ms_DynamicSizePool.Alloc();
|
||||
}
|
||||
|
||||
void operator delete(void* pT)
|
||||
{
|
||||
ms_DynamicSizePool.Free((T*)pT);
|
||||
}
|
||||
|
||||
static void SetPoolName(const char* szPoolName)
|
||||
{
|
||||
ms_DynamicSizePool.SetName(szPoolName);
|
||||
}
|
||||
|
||||
static void ClearPool()
|
||||
{
|
||||
ms_DynamicSizePool.Clear();
|
||||
}
|
||||
|
||||
static void FreePool()
|
||||
{
|
||||
ms_DynamicSizePool.FreeAll();
|
||||
}
|
||||
|
||||
protected:
|
||||
static CDynamicSizePool<T> ms_DynamicSizePool;
|
||||
};
|
||||
|
||||
template <class T> CDynamicSizePool<T> CPooledObject<T>::ms_DynamicSizePool;
|
||||
*/
|
||||
|
||||
/*
|
||||
template<typename T>
|
||||
class CPoolNode : public T
|
||||
{
|
||||
public:
|
||||
CPoolNode()
|
||||
{
|
||||
m_pNext = NULL;
|
||||
m_pPrev = NULL;
|
||||
}
|
||||
|
||||
virtual ~CPoolNode()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
CPoolNode<T> * m_pNext;
|
||||
CPoolNode<T> * m_pPrev;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CDynamicPool
|
||||
{
|
||||
public:
|
||||
typedef CPoolNode<T> TNode;
|
||||
|
||||
public:
|
||||
CDynamicPool()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
virtual ~CDynamicPool()
|
||||
{
|
||||
assert(m_pFreeList==NULL && "CDynamicPool::~CDynamicPool() - NOT Clear");
|
||||
assert(m_pUsedList==NULL && "CDynamicPool::~CDynamicPool() - NOT Clear");
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
m_nodes = NULL;
|
||||
m_nodeCount = 0;
|
||||
|
||||
m_pFreeList = NULL;
|
||||
m_pUsedList = NULL;
|
||||
}
|
||||
|
||||
void SetName(const char* c_szName)
|
||||
{
|
||||
m_stName = c_szName;
|
||||
}
|
||||
|
||||
DWORD GetCapacity()
|
||||
{
|
||||
return m_nodeCount;
|
||||
}
|
||||
|
||||
T* Alloc()
|
||||
{
|
||||
TNode* pnewNode;
|
||||
|
||||
if (m_pFreeList)
|
||||
{
|
||||
pnewNode = m_pFreeList;
|
||||
m_pFreeList = m_pFreeList->m_pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
pnewNode = AllocNode();
|
||||
}
|
||||
|
||||
if (!pnewNode)
|
||||
return NULL;
|
||||
|
||||
if (!m_pUsedList)
|
||||
{
|
||||
m_pUsedList = pnewNode;
|
||||
m_pUsedList->m_pPrev = m_pUsedList->m_pNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pUsedList->m_pPrev = pnewNode;
|
||||
pnewNode->m_pNext = m_pUsedList;
|
||||
pnewNode->m_pPrev = NULL;
|
||||
m_pUsedList = pnewNode;
|
||||
}
|
||||
//Tracef("%s Pool Alloc %p\n", m_stName.c_str(), pnewNode);
|
||||
return (T*) pnewNode;
|
||||
}
|
||||
|
||||
bool IsUsedData(T* pdata)
|
||||
{
|
||||
TNode* pchkNode=(TNode*)pdata;
|
||||
TNode* pcurNode = m_pUsedList;
|
||||
while (pcurNode)
|
||||
{
|
||||
if (pcurNode==pdata)
|
||||
return true;
|
||||
|
||||
pcurNode = pcurNode->m_pNext;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsFreeData(T* pdata)
|
||||
{
|
||||
TNode* pchkNode=(TNode*)pdata;
|
||||
TNode* pcurNode = m_pFreeList;
|
||||
while (pcurNode)
|
||||
{
|
||||
if (pcurNode==pdata)
|
||||
return true;
|
||||
|
||||
pcurNode = pcurNode->m_pNext;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Free(T * pdata)
|
||||
{
|
||||
assert(IsUsedData(pdata));
|
||||
assert(!IsFreeData(pdata));
|
||||
|
||||
TNode* pfreeNode = (TNode*) pdata;
|
||||
|
||||
if (pfreeNode == m_pUsedList)
|
||||
{
|
||||
m_pUsedList = m_pUsedList->m_pNext;
|
||||
if (NULL != m_pUsedList)
|
||||
m_pUsedList->m_pPrev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pfreeNode->m_pNext)
|
||||
pfreeNode->m_pNext->m_pPrev = pfreeNode->m_pPrev;
|
||||
|
||||
if (pfreeNode->m_pPrev)
|
||||
pfreeNode->m_pPrev->m_pNext = pfreeNode->m_pNext;
|
||||
}
|
||||
|
||||
pfreeNode->m_pPrev = NULL;
|
||||
pfreeNode->m_pNext = m_pFreeList;
|
||||
m_pFreeList = pfreeNode;
|
||||
//Tracef("%s Pool Free\n", m_stName.c_str());
|
||||
}
|
||||
|
||||
void FreeAll()
|
||||
{
|
||||
TNode * pcurNode;
|
||||
TNode * pnextNode;
|
||||
|
||||
pcurNode = m_pUsedList;
|
||||
|
||||
while (pcurNode)
|
||||
{
|
||||
pnextNode = pcurNode->m_pNext;
|
||||
Free(pcurNode);
|
||||
pcurNode = pnextNode;
|
||||
}
|
||||
|
||||
assert(NULL==m_pUsedList);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
TNode* pcurNode;
|
||||
TNode* pnextNode;
|
||||
|
||||
DWORD count = 0;
|
||||
|
||||
pcurNode = m_pFreeList;
|
||||
while (pcurNode)
|
||||
{
|
||||
pnextNode = pcurNode->m_pNext;
|
||||
delete pcurNode;
|
||||
pcurNode = pnextNode;
|
||||
++count;
|
||||
}
|
||||
m_pFreeList = NULL;
|
||||
|
||||
pcurNode = m_pUsedList;
|
||||
while (pcurNode)
|
||||
{
|
||||
pnextNode = pcurNode->m_pNext;
|
||||
delete pcurNode;
|
||||
pcurNode = pnextNode;
|
||||
++count;
|
||||
}
|
||||
|
||||
m_pUsedList = NULL;
|
||||
|
||||
assert(count==m_nodeCount && "CDynamicPool::Clear()");
|
||||
|
||||
m_nodeCount=0;
|
||||
}
|
||||
|
||||
protected:
|
||||
TNode* AllocNode()
|
||||
{
|
||||
++m_nodeCount;
|
||||
return new TNode;
|
||||
}
|
||||
|
||||
protected:
|
||||
TNode * m_nodes;
|
||||
TNode * m_pFreeList;
|
||||
TNode * m_pUsedList;
|
||||
|
||||
DWORD m_nodeCount;
|
||||
std::string m_stName;
|
||||
};
|
||||
*/
|
||||
@@ -0,0 +1,264 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EterBase/Timer.h"
|
||||
#include "../EterBase/Debug.h"
|
||||
|
||||
/*
|
||||
class CProfiler : public CSingleton<CProfiler>
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
STACK_DATA_MAX_NUM = 64,
|
||||
};
|
||||
|
||||
public:
|
||||
typedef struct SProfileStackData
|
||||
{
|
||||
int iCallStep;
|
||||
long iStartTime;
|
||||
long iEndTime;
|
||||
|
||||
std::string strName;
|
||||
} TProfileStackData;
|
||||
typedef struct SProfileAccumulationData
|
||||
{
|
||||
int iStartTime;
|
||||
int iCallingCount;
|
||||
int iCollapsedTime;
|
||||
|
||||
std::string strName;
|
||||
} TProfileAccumulationData;
|
||||
|
||||
typedef std::map<std::string, CGraphicTextInstance*> TGraphicTextInstanceMap;
|
||||
typedef std::map<std::string, TProfileAccumulationData> TProfileAccumulationDataMap;
|
||||
|
||||
public:
|
||||
CProfiler()
|
||||
{
|
||||
Clear();
|
||||
m_ProfileAccumulationDataMap.clear();
|
||||
}
|
||||
virtual ~CProfiler()
|
||||
{
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_ProfileStackDataCount = 0;
|
||||
m_iCallStep = 0;
|
||||
|
||||
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin();
|
||||
for (; itor != m_ProfileAccumulationDataMap.end(); ++itor)
|
||||
{
|
||||
TProfileAccumulationData & rData = itor->second;
|
||||
rData.iCallingCount = 0;
|
||||
rData.iCollapsedTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Push(const char * c_szName)
|
||||
{
|
||||
assert(m_ProfileStackDataCount < STACK_DATA_MAX_NUM);
|
||||
TProfileStackData & rProfileStackData = m_ProfileStackDatas[m_ProfileStackDataCount++];
|
||||
|
||||
rProfileStackData.iCallStep = m_iCallStep;
|
||||
rProfileStackData.iStartTime = ELTimer_GetMSec();
|
||||
rProfileStackData.strName = c_szName;
|
||||
|
||||
++m_iCallStep;
|
||||
|
||||
TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(c_szName);
|
||||
|
||||
if (m_GraphicTextInstanceMap.end() == itor)
|
||||
{
|
||||
CGraphicTextInstance * pGraphicTextInstance = CGraphicTextInstance::New();
|
||||
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer("굴림체.fnt");
|
||||
pGraphicTextInstance->Clear();
|
||||
pGraphicTextInstance->SetTextPointer(static_cast<CGraphicText*>(pResource));
|
||||
|
||||
m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance));
|
||||
}
|
||||
}
|
||||
void Pop(const char * c_szName)
|
||||
{
|
||||
TProfileStackData * pProfileStackData;
|
||||
|
||||
if (!GetProfileStackDataPointer(c_szName, &pProfileStackData))
|
||||
{
|
||||
assert(!"The name doesn't exist");
|
||||
return;
|
||||
}
|
||||
|
||||
pProfileStackData->iEndTime = ELTimer_GetMSec();
|
||||
|
||||
--m_iCallStep;
|
||||
}
|
||||
|
||||
void PushAccumulation(const char * c_szName)
|
||||
{
|
||||
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName);
|
||||
|
||||
if (itor == m_ProfileAccumulationDataMap.end())
|
||||
{
|
||||
TProfileAccumulationData ProfileAccumulationData;
|
||||
ProfileAccumulationData.iCollapsedTime = 0;
|
||||
ProfileAccumulationData.iCallingCount = 0;
|
||||
ProfileAccumulationData.strName = c_szName;
|
||||
m_ProfileAccumulationDataMap.insert(TProfileAccumulationDataMap::value_type(c_szName, ProfileAccumulationData));
|
||||
|
||||
itor = m_ProfileAccumulationDataMap.find(c_szName);
|
||||
|
||||
/////
|
||||
|
||||
CGraphicTextInstance * pGraphicTextInstance = m_GraphicTextInstancePool.Alloc();
|
||||
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer("굴림체.fnt");
|
||||
pGraphicTextInstance->Clear();
|
||||
pGraphicTextInstance->SetTextPointer(static_cast<CGraphicText*>(pResource));
|
||||
|
||||
m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance));
|
||||
}
|
||||
|
||||
TProfileAccumulationData & rData = itor->second;
|
||||
rData.iStartTime = ELTimer_GetMSec();
|
||||
}
|
||||
|
||||
void PopAccumulation(const char * c_szName)
|
||||
{
|
||||
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName);
|
||||
|
||||
if (itor == m_ProfileAccumulationDataMap.end())
|
||||
return;
|
||||
|
||||
TProfileAccumulationData & rData = itor->second;
|
||||
rData.iCollapsedTime += ELTimer_GetMSec() - rData.iStartTime;
|
||||
++rData.iCallingCount;
|
||||
}
|
||||
|
||||
void ProfileByConsole()
|
||||
{
|
||||
for (int i = 0; i < m_ProfileStackDataCount; ++i)
|
||||
{
|
||||
TProfileStackData & rProfileStackData = m_ProfileStackDatas[i];
|
||||
|
||||
// for (int i = 0; i < rProfileStackData.iCallStep; ++i)
|
||||
// Tracef("\t");
|
||||
|
||||
Tracef("%-10s: %2d\t", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime);
|
||||
}
|
||||
Tracef("\n");
|
||||
}
|
||||
|
||||
void ProfileOneStackDataByConsole(const char * c_szName)
|
||||
{
|
||||
TProfileStackData * pProfileStackData;
|
||||
|
||||
if (!GetProfileStackDataPointer(c_szName, &pProfileStackData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Tracef("%-10s: %3d\n", pProfileStackData->strName.c_str(), pProfileStackData->iEndTime - pProfileStackData->iStartTime);
|
||||
}
|
||||
|
||||
void ProfileOneAccumulationDataByConsole(const char * c_szName)
|
||||
{
|
||||
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName);
|
||||
if (itor == m_ProfileAccumulationDataMap.end())
|
||||
return;
|
||||
|
||||
TProfileAccumulationData & rData = itor->second;
|
||||
Tracef("%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]\n", rData.strName.c_str(),
|
||||
rData.iCollapsedTime,
|
||||
rData.iCallingCount);
|
||||
}
|
||||
|
||||
void ProfileByScreen()
|
||||
{
|
||||
float fxPosition = 0;
|
||||
float fyPosition = 10;
|
||||
|
||||
char szText[128];
|
||||
|
||||
for (int i = 0; i < m_ProfileStackDataCount; ++i)
|
||||
{
|
||||
TProfileStackData & rProfileStackData = m_ProfileStackDatas[i];
|
||||
|
||||
TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rProfileStackData.strName);
|
||||
|
||||
if (m_GraphicTextInstanceMap.end() != itor)
|
||||
{
|
||||
CGraphicTextInstance * pGraphicTextInstance = itor->second;
|
||||
|
||||
fxPosition = 10 + (float) rProfileStackData.iCallStep * 10 * 4;
|
||||
|
||||
sprintf(szText, "%-10s : %3d", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime);
|
||||
|
||||
pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f);
|
||||
pGraphicTextInstance->SetValue(szText, strlen(szText));
|
||||
pGraphicTextInstance->SetPosition(fxPosition, fyPosition);
|
||||
pGraphicTextInstance->Update();
|
||||
pGraphicTextInstance->Render();
|
||||
|
||||
fyPosition += 17;
|
||||
}
|
||||
}
|
||||
|
||||
fxPosition = 10;
|
||||
fyPosition += 10;
|
||||
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin();
|
||||
for (; itor != m_ProfileAccumulationDataMap.end(); ++itor)
|
||||
{
|
||||
TProfileAccumulationData & rData = itor->second;
|
||||
TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rData.strName);
|
||||
|
||||
if (m_GraphicTextInstanceMap.end() != itor)
|
||||
{
|
||||
CGraphicTextInstance * pGraphicTextInstance = itor->second;
|
||||
|
||||
sprintf(szText, "%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]", rData.strName.c_str(),
|
||||
rData.iCollapsedTime,
|
||||
rData.iCallingCount);
|
||||
|
||||
pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f);
|
||||
pGraphicTextInstance->SetValue(szText, strlen(szText));
|
||||
pGraphicTextInstance->SetPosition(fxPosition, fyPosition);
|
||||
pGraphicTextInstance->Update();
|
||||
pGraphicTextInstance->Render();
|
||||
|
||||
fyPosition += 17;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
bool GetProfileStackDataPointer(const char * c_szName, TProfileStackData ** ppProfileStackData)
|
||||
{
|
||||
for (int i = 0; i < m_ProfileStackDataCount; ++i)
|
||||
{
|
||||
if (0 == m_ProfileStackDatas[i].strName.compare(c_szName))
|
||||
{
|
||||
*ppProfileStackData = &m_ProfileStackDatas[i];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Profile Stack Data
|
||||
int m_ProfileStackDataCount;
|
||||
TProfileStackData m_ProfileStackDatas[STACK_DATA_MAX_NUM];
|
||||
|
||||
// Profile Increase Data
|
||||
TProfileAccumulationDataMap m_ProfileAccumulationDataMap;
|
||||
|
||||
int m_iCallStep;
|
||||
|
||||
TGraphicTextInstanceMap m_GraphicTextInstanceMap;
|
||||
};
|
||||
*/
|
||||
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3dx8.h>
|
||||
|
||||
class CRay
|
||||
{
|
||||
public:
|
||||
CRay(const D3DXVECTOR3 & v3Start, const D3DXVECTOR3 & v3Dir, float fRayRange) : m_v3Start(v3Start), m_v3Direction(v3Dir)
|
||||
{
|
||||
assert(fRayRange >= 0);
|
||||
m_fRayRange = fRayRange;
|
||||
D3DXVec3Normalize(&m_v3Direction, &m_v3Direction);
|
||||
m_v3End = m_v3Start + fRayRange * m_v3Direction;
|
||||
}
|
||||
|
||||
CRay()
|
||||
{
|
||||
}
|
||||
|
||||
void SetStartPoint(const D3DXVECTOR3 & v3Start)
|
||||
{
|
||||
m_v3Start = v3Start;
|
||||
}
|
||||
|
||||
void SetDirection(const D3DXVECTOR3 & v3Dir, float fRayRange)
|
||||
{
|
||||
assert(fRayRange >= 0);
|
||||
m_v3Direction = v3Dir;
|
||||
D3DXVec3Normalize(&m_v3Direction, &m_v3Direction);
|
||||
m_fRayRange = fRayRange;
|
||||
m_v3End = m_v3Start + m_fRayRange * m_v3Direction;
|
||||
}
|
||||
|
||||
void GetStartPoint(D3DXVECTOR3 * pv3Start) const
|
||||
{
|
||||
*pv3Start = m_v3Start;
|
||||
}
|
||||
|
||||
void GetDirection(D3DXVECTOR3 * pv3Dir, float * pfRayRange) const
|
||||
{
|
||||
*pv3Dir = m_v3Direction;
|
||||
*pfRayRange = m_fRayRange;
|
||||
}
|
||||
|
||||
void GetEndPoint(D3DXVECTOR3 * pv3End) const
|
||||
{
|
||||
*pv3End = m_v3End;
|
||||
}
|
||||
|
||||
const CRay & operator = (const CRay & rhs)
|
||||
{
|
||||
assert(rhs.m_fRayRange >= 0);
|
||||
m_v3Start = rhs.m_v3Start;
|
||||
m_v3Direction = rhs.m_v3Direction;
|
||||
m_fRayRange = rhs.m_fRayRange;
|
||||
D3DXVec3Normalize(&m_v3Direction, &m_v3Direction);
|
||||
m_v3End = m_v3Start + m_fRayRange * m_v3Direction;
|
||||
}
|
||||
|
||||
private:
|
||||
D3DXVECTOR3 m_v3Start;
|
||||
D3DXVECTOR3 m_v3End;
|
||||
D3DXVECTOR3 m_v3Direction;
|
||||
float m_fRayRange;
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
#ifndef __INC_REF_H__
|
||||
#define __INC_REF_H__
|
||||
|
||||
#include "ReferenceObject.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
template<typename T> class CRef
|
||||
{
|
||||
public:
|
||||
struct FClear
|
||||
{
|
||||
void operator() (CRef<T>& rRef)
|
||||
{
|
||||
rRef.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
CRef() : m_pObject(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CRef(CReferenceObject* pObject)
|
||||
{
|
||||
m_pObject = NULL;
|
||||
Initialize(pObject);
|
||||
}
|
||||
|
||||
CRef(const CRef& c_rRef)
|
||||
{
|
||||
m_pObject = NULL;
|
||||
Initialize(c_rRef.m_pObject);
|
||||
}
|
||||
|
||||
~CRef()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void operator = (CReferenceObject* pObject)
|
||||
{
|
||||
SetPointer(pObject);
|
||||
}
|
||||
|
||||
void operator = (const CRef& c_rRef)
|
||||
{
|
||||
SetPointer(c_rRef.m_pObject);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (m_pObject)
|
||||
{
|
||||
m_pObject->Release();
|
||||
m_pObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsNull() const
|
||||
{
|
||||
return m_pObject == NULL ? true : false;
|
||||
}
|
||||
|
||||
void SetPointer(CReferenceObject* pObject)
|
||||
{
|
||||
CReferenceObject* pOldObject = m_pObject;
|
||||
|
||||
m_pObject = pObject;
|
||||
|
||||
if (m_pObject)
|
||||
m_pObject->AddReference();
|
||||
|
||||
if (pOldObject)
|
||||
pOldObject->Release();
|
||||
}
|
||||
|
||||
T* GetPointer() const
|
||||
{
|
||||
return static_cast<T*>(m_pObject);
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
assert(m_pObject != NULL);
|
||||
return static_cast<T*>(m_pObject);
|
||||
}
|
||||
|
||||
private:
|
||||
void Initialize(CReferenceObject* pObject)
|
||||
{
|
||||
assert(m_pObject == NULL);
|
||||
|
||||
m_pObject = pObject;
|
||||
|
||||
if (m_pObject)
|
||||
m_pObject->AddReference();
|
||||
}
|
||||
|
||||
private:
|
||||
CReferenceObject* m_pObject;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ReferenceObject.h"
|
||||
|
||||
CReferenceObject::CReferenceObject() : m_refCount(0), m_destructed(false)
|
||||
{
|
||||
}
|
||||
|
||||
CReferenceObject::~CReferenceObject()
|
||||
{
|
||||
}
|
||||
|
||||
void CReferenceObject::AddReference()
|
||||
{
|
||||
if (m_refCount == 0)
|
||||
OnConstruct();
|
||||
|
||||
++m_refCount;
|
||||
}
|
||||
|
||||
int CReferenceObject::GetReferenceCount()
|
||||
{
|
||||
return m_refCount;
|
||||
}
|
||||
|
||||
void CReferenceObject::AddReferenceOnly()
|
||||
{
|
||||
++m_refCount;
|
||||
}
|
||||
|
||||
void CReferenceObject::Release()
|
||||
{
|
||||
if (m_refCount > 1)
|
||||
{
|
||||
--m_refCount;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_destructed == false);
|
||||
assert(m_refCount >= 0);
|
||||
m_refCount = 0;
|
||||
OnSelfDestruct();
|
||||
}
|
||||
|
||||
void CReferenceObject::OnConstruct()
|
||||
{
|
||||
m_destructed = false;
|
||||
}
|
||||
|
||||
void CReferenceObject::OnSelfDestruct()
|
||||
{
|
||||
m_destructed = true;
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool CReferenceObject::canDestroy()
|
||||
{
|
||||
if (m_refCount > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
class CReferenceObject
|
||||
{
|
||||
public:
|
||||
CReferenceObject();
|
||||
virtual ~CReferenceObject();
|
||||
|
||||
void AddReference();
|
||||
void AddReferenceOnly();
|
||||
void Release();
|
||||
|
||||
int GetReferenceCount();
|
||||
|
||||
bool canDestroy();
|
||||
|
||||
protected:
|
||||
virtual void OnConstruct();
|
||||
virtual void OnSelfDestruct();
|
||||
|
||||
private:
|
||||
int m_refCount;
|
||||
bool m_destructed;
|
||||
};
|
||||
@@ -0,0 +1,181 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
#include "../EterBase/CRC32.h"
|
||||
#include "../EterBase/Timer.h"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
bool CResource::ms_bDeleteImmediately = false;
|
||||
|
||||
CResource::CResource(const char* c_szFileName) : me_state(STATE_EMPTY)
|
||||
{
|
||||
SetFileName(c_szFileName);
|
||||
}
|
||||
|
||||
CResource::~CResource()
|
||||
{
|
||||
}
|
||||
|
||||
void CResource::SetDeleteImmediately(bool isSet)
|
||||
{
|
||||
ms_bDeleteImmediately = isSet;
|
||||
}
|
||||
|
||||
void CResource::OnConstruct()
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
void CResource::OnSelfDestruct()
|
||||
{
|
||||
if (ms_bDeleteImmediately)
|
||||
Clear();
|
||||
else
|
||||
CResourceManager::Instance().ReserveDeletingResource(this);
|
||||
}
|
||||
|
||||
void CResource::Load()
|
||||
{
|
||||
if (me_state != STATE_EMPTY)
|
||||
return;
|
||||
|
||||
const char * c_szFileName = GetFileName();
|
||||
|
||||
DWORD dwStart = ELTimer_GetMSec();
|
||||
CMappedFile file;
|
||||
LPCVOID fileData;
|
||||
|
||||
//Tracenf("Load %s", c_szFileName);
|
||||
|
||||
if (CEterPackManager::Instance().Get(file, c_szFileName, &fileData))
|
||||
{
|
||||
m_dwLoadCostMiliiSecond = ELTimer_GetMSec() - dwStart;
|
||||
//Tracef("CResource::Load %s (%d bytes) in %d ms\n", c_szFileName, file.Size(), m_dwLoadCostMiliiSecond);
|
||||
|
||||
if (OnLoad(file.Size(), fileData))
|
||||
{
|
||||
me_state = STATE_EXIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracef("CResource::Load Error %s\n", c_szFileName);
|
||||
me_state = STATE_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnLoad(0, NULL))
|
||||
me_state = STATE_EXIST;
|
||||
else
|
||||
{
|
||||
Tracef("CResource::Load file not exist %s\n", c_szFileName);
|
||||
me_state = STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CResource::Reload()
|
||||
{
|
||||
Clear();
|
||||
Tracef("CResource::Reload %s\n", GetFileName());
|
||||
|
||||
CMappedFile file;
|
||||
LPCVOID fileData;
|
||||
|
||||
if (CEterPackManager::Instance().Get(file, GetFileName(), &fileData))
|
||||
{
|
||||
if (OnLoad(file.Size(), fileData))
|
||||
{
|
||||
me_state = STATE_EXIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
me_state = STATE_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnLoad(0, NULL))
|
||||
me_state = STATE_EXIST;
|
||||
else
|
||||
{
|
||||
me_state = STATE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CResource::TType CResource::StringToType(const char* c_szType)
|
||||
{
|
||||
return GetCRC32(c_szType, strlen(c_szType));
|
||||
}
|
||||
|
||||
int CResource::ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen)
|
||||
{
|
||||
const char * pc;
|
||||
int len = 0;
|
||||
|
||||
for (pc = c_szPathName; *pc && len < retLen; ++pc, ++len)
|
||||
{
|
||||
if (*pc == '/')
|
||||
*(pszRetPathName++) = '\\';
|
||||
else
|
||||
*(pszRetPathName++) = (char) korean_tolower(*pc);
|
||||
}
|
||||
|
||||
*pszRetPathName = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
void CResource::SetFileName(const char* c_szFileName)
|
||||
{
|
||||
// 2004. 2. 1. myevan. 쓰레드가 사용되는 상황에서 static 변수는 사용하지 않는것이 좋다.
|
||||
// 2004. 2. 1. myevan. 파일 이름 처리를 std::string 사용
|
||||
m_stFileName=c_szFileName;
|
||||
}
|
||||
|
||||
void CResource::Clear()
|
||||
{
|
||||
OnClear();
|
||||
me_state = STATE_EMPTY;
|
||||
}
|
||||
|
||||
bool CResource::IsType(TType type)
|
||||
{
|
||||
return OnIsType(type);
|
||||
}
|
||||
|
||||
CResource::TType CResource::Type()
|
||||
{
|
||||
static TType s_type = StringToType("CResource");
|
||||
return s_type;
|
||||
}
|
||||
|
||||
bool CResource::OnIsType(TType type)
|
||||
{
|
||||
if (CResource::Type() == type)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CResource::IsData() const
|
||||
{
|
||||
return me_state != STATE_EMPTY;
|
||||
}
|
||||
|
||||
bool CResource::IsEmpty() const
|
||||
{
|
||||
return OnIsEmpty();
|
||||
}
|
||||
|
||||
bool CResource::CreateDeviceObjects()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CResource::DestroyDeviceObjects()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "ReferenceObject.h"
|
||||
#include <string>
|
||||
|
||||
class CResource : public CReferenceObject
|
||||
{
|
||||
public:
|
||||
typedef DWORD TType;
|
||||
|
||||
enum EState
|
||||
{
|
||||
STATE_EMPTY,
|
||||
STATE_ERROR,
|
||||
STATE_EXIST,
|
||||
STATE_LOAD,
|
||||
STATE_FREE
|
||||
};
|
||||
|
||||
public:
|
||||
void Clear();
|
||||
|
||||
static TType StringToType(const char* c_szType);
|
||||
static TType Type();
|
||||
|
||||
void Load();
|
||||
void Reload();
|
||||
int ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen);
|
||||
|
||||
virtual bool CreateDeviceObjects();
|
||||
virtual void DestroyDeviceObjects();
|
||||
|
||||
public:
|
||||
CResource(const char* c_szFileName);
|
||||
virtual ~CResource();
|
||||
|
||||
static void SetDeleteImmediately(bool isSet = false);
|
||||
|
||||
// is loaded?
|
||||
bool IsData() const;
|
||||
bool IsEmpty() const;
|
||||
bool IsType(TType type);
|
||||
|
||||
DWORD GetLoadCostMilliSecond() { return m_dwLoadCostMiliiSecond; }
|
||||
//const char * GetFileName() const { return m_pszFileName; }
|
||||
const char * GetFileName() const { return m_stFileName.c_str(); }
|
||||
const std::string& GetFileNameString() const { return m_stFileName; }
|
||||
|
||||
virtual bool OnLoad(int iSize, const void * c_pvBuf) = 0;
|
||||
|
||||
protected:
|
||||
void SetFileName(const char* c_szFileName);
|
||||
|
||||
virtual void OnClear() = 0;
|
||||
virtual bool OnIsEmpty() const = 0;
|
||||
virtual bool OnIsType(TType type) = 0;
|
||||
|
||||
virtual void OnConstruct();
|
||||
virtual void OnSelfDestruct();
|
||||
|
||||
protected:
|
||||
std::string m_stFileName;
|
||||
//char * m_pszFileName;
|
||||
DWORD m_dwLoadCostMiliiSecond;
|
||||
EState me_state;
|
||||
|
||||
protected:
|
||||
static bool ms_bDeleteImmediately;
|
||||
};
|
||||
@@ -0,0 +1,525 @@
|
||||
#include "StdAfx.h"
|
||||
#include <io.h>
|
||||
#include "../EterBase/CRC32.h"
|
||||
#include "../EterBase/Timer.h"
|
||||
#include "../EterBase/Stl.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include "GrpImage.h"
|
||||
|
||||
int g_iLoadingDelayTime = 20;
|
||||
|
||||
const long c_Deleting_Wait_Time = 30000; // 삭제 대기 시간 (30초)
|
||||
const long c_DeletingCountPerFrame = 30; // 프레임당 체크 리소스 갯수
|
||||
const long c_Reference_Decrease_Wait_Time = 30000; // 선로딩 리소스의 해제 대기 시간 (30초)
|
||||
|
||||
CFileLoaderThread CResourceManager::ms_loadingThread;
|
||||
|
||||
void CResourceManager::LoadStaticCache(const char* c_szFileName)
|
||||
{
|
||||
CResource* pkRes=GetResourcePointer(c_szFileName);
|
||||
if (!pkRes)
|
||||
{
|
||||
Lognf(1, "CResourceManager::LoadStaticCache %s - FAILED", c_szFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD dwCacheKey=GetCRC32(c_szFileName, strlen(c_szFileName));
|
||||
TResourcePointerMap::iterator f=m_pCacheMap.find(dwCacheKey);
|
||||
if (m_pCacheMap.end()!=f)
|
||||
return;
|
||||
|
||||
pkRes->AddReference();
|
||||
m_pCacheMap.insert(TResourcePointerMap::value_type(dwCacheKey, pkRes));
|
||||
|
||||
}
|
||||
|
||||
void CResourceManager::ProcessBackgroundLoading()
|
||||
{
|
||||
TResourceRequestMap::iterator itor = m_RequestMap.begin();
|
||||
|
||||
while (itor != m_RequestMap.end())
|
||||
{
|
||||
DWORD dwFileCRC = itor->first;
|
||||
std::string & stFileName = itor->second;
|
||||
|
||||
if (isResourcePointerData(dwFileCRC) ||
|
||||
(m_WaitingMap.end() != m_WaitingMap.find(dwFileCRC)))
|
||||
{
|
||||
//printf("SKP %s\n", stFileName.c_str());
|
||||
itor = m_RequestMap.erase(itor);
|
||||
continue;
|
||||
}
|
||||
|
||||
//printf("REQ %s\n", stFileName.c_str());
|
||||
ms_loadingThread.Request(stFileName);
|
||||
m_WaitingMap.insert(TResourceRequestMap::value_type(dwFileCRC, stFileName));
|
||||
itor = m_RequestMap.erase(itor);
|
||||
//break; // NOTE: 여기서 break 하면 천천히 로딩 된다.
|
||||
}
|
||||
|
||||
DWORD dwCurrentTime = ELTimer_GetMSec();
|
||||
|
||||
CFileLoaderThread::TData * pData;
|
||||
while (ms_loadingThread.Fetch(&pData))
|
||||
{
|
||||
//printf("LOD %s\n", pData->stFileName.c_str());
|
||||
CResource * pResource = GetResourcePointer(pData->stFileName.c_str());
|
||||
|
||||
if (pResource)
|
||||
{
|
||||
if (pResource->IsEmpty())
|
||||
{
|
||||
pResource->OnLoad(pData->dwSize, pData->pvBuf);
|
||||
pResource->AddReferenceOnly();
|
||||
|
||||
// 여기서 올라간 레퍼런스 카운트를 일정 시간이 지난 뒤에 풀어주기 위하여
|
||||
m_pResRefDecreaseWaitingMap.insert(TResourceRefDecreaseWaitingMap::value_type(dwCurrentTime, pResource));
|
||||
}
|
||||
}
|
||||
|
||||
m_WaitingMap.erase(GetCRC32(pData->stFileName.c_str(), pData->stFileName.size()));
|
||||
|
||||
delete [] ((char *) pData->pvBuf);
|
||||
delete pData;
|
||||
}
|
||||
|
||||
// DO : 일정 시간이 지나고 난뒤 미리 로딩해 두었던 리소스의 레퍼런스 카운트를 감소 시킨다 - [levites]
|
||||
long lCurrentTime = ELTimer_GetMSec();
|
||||
|
||||
TResourceRefDecreaseWaitingMap::iterator itorRef = m_pResRefDecreaseWaitingMap.begin();
|
||||
|
||||
while (itorRef != m_pResRefDecreaseWaitingMap.end())
|
||||
{
|
||||
const long & rCreatingTime = itorRef->first;
|
||||
|
||||
if (lCurrentTime - rCreatingTime > c_Reference_Decrease_Wait_Time)
|
||||
{
|
||||
CResource * pResource = itorRef->second;
|
||||
|
||||
// Decrease Reference Count
|
||||
pResource->Release();
|
||||
itorRef = m_pResRefDecreaseWaitingMap.erase(itorRef);
|
||||
//Tracef("Decrease Pre Loading Resource\n", rCreatingTime);
|
||||
}
|
||||
else
|
||||
++itorRef;
|
||||
}
|
||||
}
|
||||
|
||||
void CResourceManager::PushBackgroundLoadingSet(std::set<std::string> & LoadingSet)
|
||||
{
|
||||
std::set<std::string>::iterator itor = LoadingSet.begin();
|
||||
|
||||
while (itor != LoadingSet.end())
|
||||
{
|
||||
DWORD dwFileCRC = __GetFileCRC(itor->c_str());
|
||||
|
||||
if (NULL != isResourcePointerData(dwFileCRC))
|
||||
{
|
||||
++itor;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_RequestMap.insert(TResourceRequestMap::value_type(dwFileCRC, itor->c_str()));
|
||||
++itor;
|
||||
}
|
||||
}
|
||||
|
||||
void CResourceManager::__DestroyCacheMap()
|
||||
{
|
||||
TResourcePointerMap::iterator i;
|
||||
for (i = m_pCacheMap.begin(); i != m_pCacheMap.end(); ++i)
|
||||
{
|
||||
CResource* pResource = i->second;
|
||||
pResource->Release();
|
||||
}
|
||||
|
||||
m_pCacheMap.clear();
|
||||
}
|
||||
|
||||
void CResourceManager::__DestroyDeletingResourceMap()
|
||||
{
|
||||
Tracenf("CResourceManager::__DestroyDeletingResourceMap %d", m_ResourceDeletingMap.size());
|
||||
for (TResourceDeletingMap::iterator i = m_ResourceDeletingMap.begin(); i != m_ResourceDeletingMap.end(); ++i)
|
||||
(i->first)->Clear();
|
||||
|
||||
m_ResourceDeletingMap.clear();
|
||||
}
|
||||
|
||||
void CResourceManager::__DestroyResourceMap()
|
||||
{
|
||||
Tracenf("CResourceManager::__DestroyResourceMap %d", m_pResMap.size());
|
||||
|
||||
TResourcePointerMap::iterator i;
|
||||
for (i = m_pResMap.begin(); i != m_pResMap.end(); ++i)
|
||||
{
|
||||
CResource* pResource = i->second;
|
||||
pResource->Clear();
|
||||
}
|
||||
|
||||
stl_wipe_second(m_pResMap);
|
||||
}
|
||||
|
||||
void CResourceManager::DestroyDeletingList()
|
||||
{
|
||||
CResource::SetDeleteImmediately(true);
|
||||
|
||||
__DestroyCacheMap();
|
||||
__DestroyDeletingResourceMap();
|
||||
}
|
||||
|
||||
void CResourceManager::Destroy()
|
||||
{
|
||||
assert(m_ResourceDeletingMap.empty() && "CResourceManager::Destroy - YOU MUST CALL DestroyDeletingList");
|
||||
__DestroyResourceMap();
|
||||
}
|
||||
|
||||
void CResourceManager::RegisterResourceNewFunctionPointer(const char* c_szFileExt, CResource* (*pNewFunc)(const char* c_szFileName))
|
||||
{
|
||||
m_pResNewFuncMap[c_szFileExt] = pNewFunc;
|
||||
}
|
||||
|
||||
void CResourceManager::RegisterResourceNewFunctionByTypePointer(int iType, CResource* (*pNewFunc) (const char* c_szFileName))
|
||||
{
|
||||
assert(iType >= 0);
|
||||
m_pResNewFuncByTypeMap[iType] = pNewFunc;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::InsertResourcePointer(DWORD dwFileCRC, CResource* pResource)
|
||||
{
|
||||
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
|
||||
|
||||
if (m_pResMap.end() != itor)
|
||||
{
|
||||
TraceError("CResource::InsertResourcePointer: %s is already registered\n", pResource->GetFileName());
|
||||
assert(!"CResource::InsertResourcePointer: Resource already resistered");
|
||||
delete pResource;
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
m_pResMap.insert(TResourcePointerMap::value_type(dwFileCRC, pResource));
|
||||
return pResource;
|
||||
}
|
||||
|
||||
|
||||
int __ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen)
|
||||
{
|
||||
const char * pc;
|
||||
int len = 0;
|
||||
|
||||
for (pc = c_szPathName; *pc && len < retLen; ++pc, ++len)
|
||||
{
|
||||
if (*pc == '/')
|
||||
*(pszRetPathName++) = '\\';
|
||||
else
|
||||
*(pszRetPathName++) = (char) korean_tolower(*pc);
|
||||
}
|
||||
|
||||
*pszRetPathName = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::GetTypeResourcePointer(const char * c_szFileName, int iType)
|
||||
{
|
||||
if (!c_szFileName || !*c_szFileName)
|
||||
{
|
||||
assert(c_szFileName != NULL && *c_szFileName != '\0');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * c_pszFile;
|
||||
DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile);
|
||||
CResource * pResource = FindResourcePointer(dwFileCRC);
|
||||
|
||||
if (pResource) // 이미 리소스가 있으면 리턴 한다.
|
||||
return pResource;
|
||||
|
||||
CResource * (*newFunc) (const char *) = NULL;
|
||||
|
||||
if (iType != -1)
|
||||
{
|
||||
TResourceNewFunctionByTypePointerMap::iterator f = m_pResNewFuncByTypeMap.find(iType);
|
||||
|
||||
if (m_pResNewFuncByTypeMap.end() != f)
|
||||
newFunc = f->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * pcFileExt = strrchr(c_pszFile, '.');
|
||||
|
||||
if (pcFileExt)
|
||||
{
|
||||
static char s_szFileExt[8 + 1];
|
||||
strncpy(s_szFileExt, pcFileExt + 1, 8);
|
||||
|
||||
TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt);
|
||||
|
||||
if (m_pResNewFuncMap.end() != f)
|
||||
newFunc = f->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newFunc)
|
||||
{
|
||||
TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile));
|
||||
return pResource;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::GetResourcePointer(const char * c_szFileName)
|
||||
{
|
||||
if (!c_szFileName || !*c_szFileName)
|
||||
{
|
||||
TraceError("CResourceManager::GetResourcePointer: filename error!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * c_pszFile;
|
||||
DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile);
|
||||
CResource * pResource = FindResourcePointer(dwFileCRC);
|
||||
|
||||
if (pResource) // 이미 리소스가 있으면 리턴 한다.
|
||||
return pResource;
|
||||
|
||||
const char * pcFileExt = strrchr(c_pszFile, '.');
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!IsFileExist(c_szFileName) )
|
||||
{
|
||||
if( pcFileExt == NULL || (stricmp( pcFileExt, ".fnt" ) != 0) ) {
|
||||
TraceError("CResourceManager::GetResourcePointer: File not exist %s", c_szFileName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CResource * (*newFunc) (const char *) = NULL;
|
||||
|
||||
if (pcFileExt)
|
||||
{
|
||||
static char s_szFileExt[8 + 1];
|
||||
strncpy(s_szFileExt, pcFileExt + 1, 8);
|
||||
|
||||
TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt);
|
||||
|
||||
if (m_pResNewFuncMap.end() != f)
|
||||
newFunc = f->second;
|
||||
}
|
||||
|
||||
if (!newFunc)
|
||||
{
|
||||
TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile));
|
||||
return pResource;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::FindResourcePointer(DWORD dwFileCRC)
|
||||
{
|
||||
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
|
||||
|
||||
if (m_pResMap.end() == itor)
|
||||
return NULL;
|
||||
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
bool CResourceManager::isResourcePointerData(DWORD dwFileCRC)
|
||||
{
|
||||
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
|
||||
|
||||
if (m_pResMap.end() == itor)
|
||||
return NULL;
|
||||
|
||||
return (itor->second)->IsData();
|
||||
}
|
||||
|
||||
DWORD CResourceManager::__GetFileCRC(const char * c_szFileName, const char ** c_ppszLowerFileName)
|
||||
{
|
||||
static char s_szFullPathFileName[MAX_PATH];
|
||||
const char * src = c_szFileName;
|
||||
char * dst = s_szFullPathFileName;
|
||||
int len = 0;
|
||||
|
||||
while (src[len])
|
||||
{
|
||||
if (src[len]=='/')
|
||||
dst[len] = '\\';
|
||||
else
|
||||
dst[len] = (char) korean_tolower(src[len]);
|
||||
|
||||
++len;
|
||||
}
|
||||
|
||||
dst[len] = '\0';
|
||||
|
||||
if (c_ppszLowerFileName)
|
||||
*c_ppszLowerFileName = &s_szFullPathFileName[0];
|
||||
|
||||
return (GetCRC32(s_szFullPathFileName, len));
|
||||
}
|
||||
|
||||
typedef struct SDumpData
|
||||
{
|
||||
const char * filename;
|
||||
float KB;
|
||||
DWORD cost;
|
||||
} TDumpData;
|
||||
|
||||
bool DumpKBCompare(const TDumpData& lhs, const TDumpData& rhs)
|
||||
{
|
||||
return (lhs.KB > rhs.KB) ? true : false;
|
||||
}
|
||||
|
||||
bool DumpCostCompare(const TDumpData& lhs, const TDumpData& rhs)
|
||||
{
|
||||
return (lhs.cost > rhs.cost) ? true : false;
|
||||
}
|
||||
|
||||
struct FDumpPrint
|
||||
{
|
||||
FILE * m_fp;
|
||||
static float m_totalKB;
|
||||
|
||||
void operator () (TDumpData & data)
|
||||
{
|
||||
m_totalKB += data.KB;
|
||||
fprintf(m_fp, "%6.1f %s\n", data.KB, data.filename);
|
||||
}
|
||||
};
|
||||
|
||||
float FDumpPrint::m_totalKB;
|
||||
|
||||
struct FDumpCostPrint
|
||||
{
|
||||
FILE * m_fp;
|
||||
|
||||
void operator() (TDumpData & data)
|
||||
{
|
||||
fprintf(m_fp, "%-4d %s\n", data.cost, data.filename);
|
||||
}
|
||||
};
|
||||
|
||||
void CResourceManager::DumpFileListToTextFile(const char* c_szFileName)
|
||||
{
|
||||
std::vector<TDumpData> dumpVector;
|
||||
|
||||
for (TResourcePointerMap::iterator i = m_pResMap.begin(); i != m_pResMap.end(); ++i)
|
||||
{
|
||||
CResource* pResource = i->second;
|
||||
TDumpData data;
|
||||
|
||||
if (pResource->IsEmpty())
|
||||
continue;
|
||||
|
||||
data.filename = pResource->GetFileName();
|
||||
|
||||
int filesize;
|
||||
|
||||
const char * ext = strrchr(data.filename, '.');
|
||||
|
||||
if (pResource->IsType(CGraphicImage::Type()) && strnicmp(ext, ".sub", 4))
|
||||
filesize = ((CGraphicImage*) pResource)->GetWidth() * ((CGraphicImage*) pResource)->GetHeight() * 4;
|
||||
else
|
||||
{
|
||||
FILE * fp2 = fopen(data.filename, "rb");
|
||||
|
||||
if (fp2)
|
||||
{
|
||||
fseek(fp2, 0L, SEEK_END);
|
||||
filesize = ftell(fp2);
|
||||
fclose(fp2);
|
||||
}
|
||||
else
|
||||
filesize = 0;
|
||||
}
|
||||
|
||||
data.KB = (float) filesize / (float) 1024;
|
||||
data.cost = pResource->GetLoadCostMilliSecond();
|
||||
|
||||
dumpVector.push_back(data);
|
||||
}
|
||||
|
||||
FILE * fp = fopen(c_szFileName, "w");
|
||||
|
||||
if (fp)
|
||||
{
|
||||
std::sort(dumpVector.begin(), dumpVector.end(), DumpKBCompare);
|
||||
|
||||
FDumpPrint DumpPrint;
|
||||
DumpPrint.m_fp = fp;
|
||||
DumpPrint.m_totalKB = 0;
|
||||
|
||||
std::for_each(dumpVector.begin(), dumpVector.end(), DumpPrint);
|
||||
fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f);
|
||||
|
||||
FDumpCostPrint DumpCostPrint;
|
||||
DumpCostPrint.m_fp = fp;
|
||||
|
||||
std::sort(dumpVector.begin(), dumpVector.end(), DumpCostCompare);
|
||||
std::for_each(dumpVector.begin(), dumpVector.end(), DumpCostPrint);
|
||||
fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
bool CResourceManager::IsFileExist(const char * c_szFileName)
|
||||
{
|
||||
return CEterPackManager::Instance().isExist(c_szFileName);
|
||||
}
|
||||
|
||||
void CResourceManager::Update()
|
||||
{
|
||||
DWORD CurrentTime = ELTimer_GetMSec();
|
||||
CResource * pResource;
|
||||
int Count = 0;
|
||||
|
||||
TResourceDeletingMap::iterator itor = m_ResourceDeletingMap.begin();
|
||||
|
||||
while (itor != m_ResourceDeletingMap.end())
|
||||
{
|
||||
pResource = itor->first;
|
||||
|
||||
if (CurrentTime >= itor->second)
|
||||
{
|
||||
if (pResource->canDestroy())
|
||||
{
|
||||
//Tracef("Resource Clear %s\n", pResource->GetFileName());
|
||||
pResource->Clear();
|
||||
}
|
||||
|
||||
itor = m_ResourceDeletingMap.erase(itor);
|
||||
|
||||
if (++Count >= c_DeletingCountPerFrame)
|
||||
break;
|
||||
}
|
||||
else
|
||||
++itor;
|
||||
}
|
||||
|
||||
ProcessBackgroundLoading();
|
||||
}
|
||||
|
||||
void CResourceManager::ReserveDeletingResource(CResource * pResource)
|
||||
{
|
||||
DWORD dwCurrentTime = ELTimer_GetMSec();
|
||||
m_ResourceDeletingMap.insert(TResourceDeletingMap::value_type(pResource, dwCurrentTime + c_Deleting_Wait_Time));
|
||||
}
|
||||
|
||||
CResourceManager::CResourceManager()
|
||||
{
|
||||
//ms_loadingThread.Create(0);
|
||||
}
|
||||
|
||||
CResourceManager::~CResourceManager()
|
||||
{
|
||||
Destroy();
|
||||
//ms_loadingThread.Shutdown();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "FileLoaderThread.h"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class CResourceManager : public CSingleton<CResourceManager>
|
||||
{
|
||||
public:
|
||||
CResourceManager();
|
||||
virtual ~CResourceManager();
|
||||
|
||||
void LoadStaticCache(const char* c_szFileName);
|
||||
|
||||
void DestroyDeletingList();
|
||||
void Destroy();
|
||||
|
||||
void BeginThreadLoading();
|
||||
void EndThreadLoading();
|
||||
|
||||
CResource * InsertResourcePointer(DWORD dwFileCRC, CResource* pResource);
|
||||
CResource * FindResourcePointer(DWORD dwFileCRC);
|
||||
CResource * GetResourcePointer(const char * c_szFileName);
|
||||
CResource * GetTypeResourcePointer(const char * c_szFileName, int iType=-1);
|
||||
|
||||
// 추가
|
||||
bool isResourcePointerData(DWORD dwFileCRC);
|
||||
|
||||
void RegisterResourceNewFunctionPointer(const char* c_szFileExt, CResource* (*pResNewFunc)(const char* c_szFileName));
|
||||
void RegisterResourceNewFunctionByTypePointer(int iType, CResource* (*pNewFunc) (const char* c_szFileName));
|
||||
|
||||
void DumpFileListToTextFile(const char* c_szFileName);
|
||||
bool IsFileExist(const char * c_szFileName);
|
||||
|
||||
void Update();
|
||||
void ReserveDeletingResource(CResource * pResource);
|
||||
|
||||
public:
|
||||
void ProcessBackgroundLoading();
|
||||
void PushBackgroundLoadingSet(std::set<std::string> & LoadingSet);
|
||||
|
||||
protected:
|
||||
void __DestroyDeletingResourceMap();
|
||||
void __DestroyResourceMap();
|
||||
void __DestroyCacheMap();
|
||||
|
||||
DWORD __GetFileCRC(const char * c_szFileName, const char ** c_pszLowerFile = NULL);
|
||||
|
||||
protected:
|
||||
typedef std::map<DWORD, CResource *> TResourcePointerMap;
|
||||
typedef std::map<std::string, CResource* (*)(const char*)> TResourceNewFunctionPointerMap;
|
||||
typedef std::map<int, CResource* (*)(const char*)> TResourceNewFunctionByTypePointerMap;
|
||||
typedef std::map<CResource *, DWORD> TResourceDeletingMap;
|
||||
typedef std::map<DWORD, std::string> TResourceRequestMap;
|
||||
typedef std::map<long, CResource*> TResourceRefDecreaseWaitingMap;
|
||||
|
||||
protected:
|
||||
TResourcePointerMap m_pCacheMap;
|
||||
TResourcePointerMap m_pResMap;
|
||||
TResourceNewFunctionPointerMap m_pResNewFuncMap;
|
||||
TResourceNewFunctionByTypePointerMap m_pResNewFuncByTypeMap;
|
||||
TResourceDeletingMap m_ResourceDeletingMap;
|
||||
TResourceRequestMap m_RequestMap; // 쓰레드로 로딩 요청한 리스트
|
||||
TResourceRequestMap m_WaitingMap;
|
||||
TResourceRefDecreaseWaitingMap m_pResRefDecreaseWaitingMap;
|
||||
|
||||
static CFileLoaderThread ms_loadingThread;
|
||||
};
|
||||
|
||||
extern int g_iLoadingDelayTime;
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ScreenFilter.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
void CScreenFilter::Render()
|
||||
{
|
||||
if (!m_bEnable)
|
||||
return;
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &ms_matIdentity);
|
||||
STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity);
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, m_bySrcType);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, m_byDestType);
|
||||
|
||||
SetOrtho2D(CScreen::ms_iWidth, CScreen::ms_iHeight, 400.0f);
|
||||
SetDiffuseColor(m_Color.r, m_Color.g, m_Color.b, m_Color.a);
|
||||
RenderBar2d(0, 0, CScreen::ms_iWidth, CScreen::ms_iHeight);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_VIEW);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
|
||||
}
|
||||
|
||||
void CScreenFilter::SetEnable(BOOL /*bFlag*/)
|
||||
{
|
||||
m_bEnable = FALSE;
|
||||
}
|
||||
|
||||
void CScreenFilter::SetBlendType(BYTE bySrcType, BYTE byDestType)
|
||||
{
|
||||
m_bySrcType = bySrcType;
|
||||
m_byDestType = byDestType;
|
||||
}
|
||||
void CScreenFilter::SetColor(const D3DXCOLOR & c_rColor)
|
||||
{
|
||||
m_Color = c_rColor;
|
||||
}
|
||||
|
||||
CScreenFilter::CScreenFilter()
|
||||
{
|
||||
m_bEnable = FALSE;
|
||||
m_bySrcType = D3DBLEND_SRCALPHA;
|
||||
m_byDestType = D3DBLEND_INVSRCALPHA;
|
||||
m_Color = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
CScreenFilter::~CScreenFilter()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "GrpScreen.h"
|
||||
|
||||
class CScreenFilter : public CScreen
|
||||
{
|
||||
public:
|
||||
CScreenFilter();
|
||||
virtual ~CScreenFilter();
|
||||
|
||||
void SetEnable(BOOL bFlag);
|
||||
void SetBlendType(BYTE bySrcType, BYTE byDestType);
|
||||
void SetColor(const D3DXCOLOR & c_rColor);
|
||||
|
||||
void Render();
|
||||
|
||||
protected:
|
||||
BOOL m_bEnable;
|
||||
BYTE m_bySrcType;
|
||||
BYTE m_byDestType;
|
||||
D3DXCOLOR m_Color;
|
||||
};
|
||||
@@ -0,0 +1,188 @@
|
||||
// SkyBox.h: interface for the CSkyBox class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_)
|
||||
#define AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "GrpBase.h"
|
||||
#include "GrpScreen.h"
|
||||
#include "GrpImageInstance.h"
|
||||
#include "ColorTransitionHelper.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
typedef struct SColor
|
||||
{
|
||||
SColor(float _r = 0.0f, float _g = 0.0f, float _b = 0.0f, float _a = 0.0f) : r(_r), g(_g), b(_b), a(_a){}
|
||||
float r, g, b, a;
|
||||
} TColor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TColor m_FirstColor;
|
||||
TColor m_SecondColor;
|
||||
}TGradientColor;
|
||||
|
||||
typedef std::vector<TGradientColor> TVectorGradientColor;
|
||||
typedef TVectorGradientColor::iterator TVectorGradientIterator;
|
||||
|
||||
class CSkyObjectQuad
|
||||
{
|
||||
public:
|
||||
CSkyObjectQuad();
|
||||
virtual ~CSkyObjectQuad();
|
||||
|
||||
void Clear(const unsigned char & c_rucNumVertex,
|
||||
const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha);
|
||||
void SetSrcColor(const unsigned char & c_rucNumVertex,
|
||||
const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha);
|
||||
void SetTransition(const unsigned char & c_rucNumVertex,
|
||||
const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha,
|
||||
DWORD dwDuration);
|
||||
|
||||
void SetVertex(const unsigned char & c_rucNumVertex, const TPDTVertex & c_rPDTVertex);
|
||||
|
||||
void StartTransition();
|
||||
bool Update();
|
||||
void Render();
|
||||
|
||||
private:
|
||||
TPDTVertex m_Vertex[4];
|
||||
TIndex m_Indices[4]; // 인덱스 버퍼...
|
||||
CColorTransitionHelper m_Helper[4];
|
||||
};
|
||||
|
||||
class CSkyObject : public CScreen
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
SKY_RENDER_MODE_DEFAULT, // = SKY_RENDER_MODE_TEXTURE
|
||||
SKY_RENDER_MODE_DIFFUSE,
|
||||
SKY_RENDER_MODE_TEXTURE,
|
||||
SKY_RENDER_MODE_MODULATE,
|
||||
SKY_RENDER_MODE_MODULATE2X,
|
||||
SKY_RENDER_MODE_MODULATE4X,
|
||||
};
|
||||
|
||||
CSkyObject();
|
||||
virtual ~CSkyObject();
|
||||
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
virtual void Render() = 0;
|
||||
virtual void Update() = 0;
|
||||
virtual void StartTransition();
|
||||
|
||||
void SetRenderMode(unsigned char ucRenderMode) { m_ucRenderMode = ucRenderMode; }
|
||||
|
||||
const bool & isTransitionStarted() { return m_bTransitionStarted; }
|
||||
|
||||
protected:
|
||||
CGraphicImageInstance * GenerateTexture(const char * szfilename);
|
||||
void DeleteTexture(CGraphicImageInstance * pGraphicImageInstance);
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 타입 정의
|
||||
|
||||
typedef std::vector<CSkyObjectQuad> TSkyObjectQuadVector;
|
||||
typedef TSkyObjectQuadVector::iterator TSkyObjectQuadIterator;
|
||||
|
||||
typedef struct CSkyBox
|
||||
{
|
||||
void StartTransition();
|
||||
bool Update();
|
||||
void Render();
|
||||
std::string m_strfacename;
|
||||
std::string m_strFaceTextureFileName;
|
||||
TSkyObjectQuadVector m_SkyObjectQuadVector;
|
||||
}TSkyObjectFace;
|
||||
|
||||
typedef std::map <std::string, CGraphicImageInstance*> TGraphicImageInstanceMap;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 구름...
|
||||
TSkyObjectFace m_FaceCloud; // 구름 일단 한장...
|
||||
D3DXMATRIX m_matWorldCloud, m_matTranslationCloud, m_matTextureCloud;
|
||||
D3DXVECTOR3 m_v3PositionCloud;
|
||||
float m_fCloudScaleX, m_fCloudScaleY, m_fCloudHeight;
|
||||
float m_fCloudTextureScaleX, m_fCloudTextureScaleY;
|
||||
float m_fCloudScrollSpeedU, m_fCloudScrollSpeedV;
|
||||
float m_fCloudPositionU, m_fCloudPositionV;
|
||||
|
||||
DWORD m_dwlastTime;
|
||||
|
||||
// 스카이 박스 이미지...
|
||||
TGraphicImageInstanceMap m_GraphicImageInstanceMap;
|
||||
|
||||
// Transform...
|
||||
D3DXMATRIX m_matWorld, m_matTranslation;
|
||||
D3DXVECTOR3 m_v3Position;
|
||||
float m_fScaleX, m_fScaleY, m_fScaleZ;
|
||||
|
||||
// 랜더링 관련... 임시 변수..
|
||||
unsigned char m_ucRenderMode;
|
||||
|
||||
std::string m_strCurTime;
|
||||
bool m_bTransitionStarted;
|
||||
bool m_bSkyMatrixUpdated;
|
||||
|
||||
CGraphicImageInstance m_CloudAlphaImageInstance;
|
||||
};
|
||||
|
||||
class CSkyBox : public CSkyObject
|
||||
{
|
||||
public:
|
||||
CSkyBox();
|
||||
virtual ~CSkyBox();
|
||||
|
||||
void Update();
|
||||
void Render();
|
||||
void RenderCloud();
|
||||
|
||||
void Destroy();
|
||||
void Unload();
|
||||
|
||||
void SetSkyBoxScale(const D3DXVECTOR3 & c_rv3Scale);
|
||||
void SetGradientLevel(BYTE byUpper, BYTE byLower);
|
||||
void SetFaceTexture( const char* c_szFileName, int iFaceIndex );
|
||||
void SetCloudTexture(const char * c_szFileName);
|
||||
void SetCloudScale(const D3DXVECTOR2 & c_rv2CloudScale);
|
||||
void SetCloudHeight(float fHeight);
|
||||
void SetCloudTextureScale(const D3DXVECTOR2 & c_rv2CloudTextureScale);
|
||||
void SetCloudScrollSpeed(const D3DXVECTOR2 & c_rv2CloudScrollSpeed);
|
||||
void SetCloudColor(const TGradientColor & c_rColor, const TGradientColor & c_rNextColor, const DWORD & dwTransitionTime);
|
||||
void Refresh();
|
||||
void SetSkyColor(const TVectorGradientColor & c_rColorVector, const TVectorGradientColor & c_rNextColorVector, long lTransitionTime);
|
||||
void StartTransition();
|
||||
|
||||
protected:
|
||||
void SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints);
|
||||
void SetSkyObjectQuadHorizon(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR3 * c_pv3QuadPoints);
|
||||
|
||||
//void UpdateSkyFaceQuadTransform(D3DXVECTOR3 * c_pv3QuadPoints);
|
||||
|
||||
protected:
|
||||
unsigned char m_ucVirticalGradientLevelUpper;
|
||||
unsigned char m_ucVirticalGradientLevelLower;
|
||||
TSkyObjectFace m_Faces[6];
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_)
|
||||
@@ -0,0 +1,769 @@
|
||||
#include "StdAfx.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
//#define StateManager_Assert(a) if (!(a)) puts("assert"#a)
|
||||
#define StateManager_Assert(a) assert(a)
|
||||
|
||||
struct SLightData
|
||||
{
|
||||
enum
|
||||
{
|
||||
LIGHT_NUM = 8,
|
||||
};
|
||||
D3DLIGHT8 m_akD3DLight[LIGHT_NUM];
|
||||
} m_kLightData;
|
||||
|
||||
|
||||
|
||||
void CStateManager::SetLight(DWORD index, CONST D3DLIGHT8* pLight)
|
||||
{
|
||||
assert(index<SLightData::LIGHT_NUM);
|
||||
m_kLightData.m_akD3DLight[index]=*pLight;
|
||||
|
||||
m_lpD3DDev->SetLight(index, pLight);
|
||||
}
|
||||
|
||||
void CStateManager::GetLight(DWORD index, D3DLIGHT8* pLight)
|
||||
{
|
||||
assert(index<8);
|
||||
*pLight=m_kLightData.m_akD3DLight[index];
|
||||
}
|
||||
|
||||
bool CStateManager::BeginScene()
|
||||
{
|
||||
m_bScene=true;
|
||||
|
||||
D3DXMATRIX m4Proj;
|
||||
D3DXMATRIX m4View;
|
||||
D3DXMATRIX m4World;
|
||||
GetTransform(D3DTS_WORLD, &m4World);
|
||||
GetTransform(D3DTS_PROJECTION, &m4Proj);
|
||||
GetTransform(D3DTS_VIEW, &m4View);
|
||||
SetTransform(D3DTS_WORLD, &m4World);
|
||||
SetTransform(D3DTS_PROJECTION, &m4Proj);
|
||||
SetTransform(D3DTS_VIEW, &m4View);
|
||||
|
||||
if (FAILED(m_lpD3DDev->BeginScene()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CStateManager::EndScene()
|
||||
{
|
||||
m_lpD3DDev->EndScene();
|
||||
m_bScene=false;
|
||||
}
|
||||
|
||||
CStateManager::CStateManager(LPDIRECT3DDEVICE8 lpDevice) : m_lpD3DDev(NULL)
|
||||
{
|
||||
m_bScene = false;
|
||||
m_dwBestMinFilter = D3DTEXF_LINEAR;
|
||||
m_dwBestMagFilter = D3DTEXF_LINEAR;
|
||||
SetDevice(lpDevice);
|
||||
}
|
||||
|
||||
CStateManager::~CStateManager()
|
||||
{
|
||||
if (m_lpD3DDev)
|
||||
{
|
||||
m_lpD3DDev->Release();
|
||||
m_lpD3DDev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CStateManager::SetDevice(LPDIRECT3DDEVICE8 lpDevice)
|
||||
{
|
||||
StateManager_Assert(lpDevice);
|
||||
lpDevice->AddRef();
|
||||
|
||||
if (m_lpD3DDev)
|
||||
{
|
||||
m_lpD3DDev->Release();
|
||||
m_lpD3DDev = NULL;
|
||||
}
|
||||
|
||||
m_lpD3DDev = lpDevice;
|
||||
|
||||
D3DCAPS8 d3dCaps;
|
||||
m_lpD3DDev->GetDeviceCaps(&d3dCaps);
|
||||
|
||||
if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC)
|
||||
m_dwBestMagFilter = D3DTEXF_ANISOTROPIC;
|
||||
else
|
||||
m_dwBestMagFilter = D3DTEXF_LINEAR;
|
||||
|
||||
if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
|
||||
m_dwBestMinFilter = D3DTEXF_ANISOTROPIC;
|
||||
else
|
||||
m_dwBestMinFilter = D3DTEXF_LINEAR;
|
||||
|
||||
DWORD dwMax = d3dCaps.MaxAnisotropy;
|
||||
dwMax = dwMax < 4 ? dwMax : 4;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
m_lpD3DDev->SetTextureStageState(i, D3DTSS_MAXANISOTROPY, dwMax);
|
||||
|
||||
SetDefaultState();
|
||||
}
|
||||
|
||||
void CStateManager::SetBestFiltering(DWORD dwStage)
|
||||
{
|
||||
SetTextureStageState(dwStage, D3DTSS_MINFILTER, m_dwBestMinFilter);
|
||||
SetTextureStageState(dwStage, D3DTSS_MAGFILTER, m_dwBestMagFilter);
|
||||
SetTextureStageState(dwStage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
|
||||
void CStateManager::Restore()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
m_bForce = true;
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; ++i)
|
||||
SetRenderState(D3DRENDERSTATETYPE(i), m_CurrentState.m_RenderStates[i]);
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
|
||||
for (j = 0; j < STATEMANAGER_MAX_TEXTURESTATES; ++j)
|
||||
SetTextureStageState(i, D3DTEXTURESTAGESTATETYPE(j), m_CurrentState.m_TextureStates[i][j]);
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
|
||||
SetTexture(i, m_CurrentState.m_Textures[i]);
|
||||
|
||||
m_bForce = false;
|
||||
}
|
||||
|
||||
void CStateManager::SetDefaultState()
|
||||
{
|
||||
m_CurrentState.ResetState();
|
||||
m_CopyState.ResetState();
|
||||
m_ChipState.ResetState();
|
||||
|
||||
m_bScene = false;
|
||||
m_bForce = true;
|
||||
|
||||
D3DXMATRIX Identity;
|
||||
D3DXMatrixIdentity(&Identity);
|
||||
|
||||
SetTransform(D3DTS_WORLD, &Identity);
|
||||
SetTransform(D3DTS_VIEW, &Identity);
|
||||
SetTransform(D3DTS_PROJECTION, &Identity);
|
||||
|
||||
D3DMATERIAL8 DefaultMat;
|
||||
ZeroMemory(&DefaultMat, sizeof(D3DMATERIAL8));
|
||||
|
||||
DefaultMat.Diffuse.r = 1.0f;
|
||||
DefaultMat.Diffuse.g = 1.0f;
|
||||
DefaultMat.Diffuse.b = 1.0f;
|
||||
DefaultMat.Diffuse.a = 1.0f;
|
||||
DefaultMat.Ambient.r = 1.0f;
|
||||
DefaultMat.Ambient.g = 1.0f;
|
||||
DefaultMat.Ambient.b = 1.0f;
|
||||
DefaultMat.Ambient.a = 1.0f;
|
||||
DefaultMat.Emissive.r = 0.0f;
|
||||
DefaultMat.Emissive.g = 0.0f;
|
||||
DefaultMat.Emissive.b = 0.0f;
|
||||
DefaultMat.Emissive.a = 0.0f;
|
||||
DefaultMat.Specular.r = 0.0f;
|
||||
DefaultMat.Specular.g = 0.0f;
|
||||
DefaultMat.Specular.b = 0.0f;
|
||||
DefaultMat.Specular.a = 0.0f;
|
||||
DefaultMat.Power = 0.0f;
|
||||
|
||||
SetMaterial(&DefaultMat);
|
||||
|
||||
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
|
||||
SetRenderState(D3DRS_LINEPATTERN, 0xFFFFFFFF);
|
||||
SetRenderState(D3DRS_LASTPIXEL, FALSE);
|
||||
SetRenderState(D3DRS_ALPHAREF, 1);
|
||||
SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
|
||||
SetRenderState(D3DRS_ZVISIBLE, FALSE);
|
||||
SetRenderState(D3DRS_FOGSTART, 0);
|
||||
SetRenderState(D3DRS_FOGEND, 0);
|
||||
SetRenderState(D3DRS_FOGDENSITY, 0);
|
||||
SetRenderState(D3DRS_EDGEANTIALIAS, FALSE);
|
||||
SetRenderState(D3DRS_ZBIAS, 0);
|
||||
SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
|
||||
SetRenderState(D3DRS_AMBIENT, 0x00000000);
|
||||
SetRenderState(D3DRS_LOCALVIEWER, FALSE);
|
||||
SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
|
||||
SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
|
||||
SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
|
||||
SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
|
||||
SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
|
||||
SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
|
||||
SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
|
||||
SetRenderState(D3DRS_COLORWRITEENABLE, 0xFFFFFFFF);
|
||||
SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||
SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||
SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
|
||||
SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
SetRenderState(D3DRS_FOGCOLOR, 0xFF000000);
|
||||
SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
|
||||
SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
|
||||
SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||
SetRenderState(D3DRS_ZENABLE, TRUE);
|
||||
SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
|
||||
SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
||||
SetRenderState(D3DRS_DITHERENABLE, TRUE);
|
||||
SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||
SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||
SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||
SetRenderState(D3DRS_COLORVERTEX, FALSE);
|
||||
SetRenderState(D3DRS_WRAP0, 0);
|
||||
SetRenderState(D3DRS_WRAP1, 0);
|
||||
SetRenderState(D3DRS_WRAP2, 0);
|
||||
SetRenderState(D3DRS_WRAP3, 0);
|
||||
SetRenderState(D3DRS_WRAP4, 0);
|
||||
SetRenderState(D3DRS_WRAP5, 0);
|
||||
SetRenderState(D3DRS_WRAP6, 0);
|
||||
SetRenderState(D3DRS_WRAP7, 0);
|
||||
|
||||
SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
|
||||
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(3, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(4, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(4, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
SetTextureStageState(4, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(4, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(5, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(5, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
SetTextureStageState(5, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(5, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(5, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
SetTextureStageState(6, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(6, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(6, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
SetTextureStageState(6, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(6, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(6, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
SetTextureStageState(7, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(7, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(7, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
SetTextureStageState(7, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
SetTextureStageState(7, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
SetTextureStageState(7, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
|
||||
SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
|
||||
SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 2);
|
||||
SetTextureStageState(3, D3DTSS_TEXCOORDINDEX, 3);
|
||||
SetTextureStageState(4, D3DTSS_TEXCOORDINDEX, 4);
|
||||
SetTextureStageState(5, D3DTSS_TEXCOORDINDEX, 5);
|
||||
SetTextureStageState(6, D3DTSS_TEXCOORDINDEX, 6);
|
||||
SetTextureStageState(7, D3DTSS_TEXCOORDINDEX, 7);
|
||||
|
||||
SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(2, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(3, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(3, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(4, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(4, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(4, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(5, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(5, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(5, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(6, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(6, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(6, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(7, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(7, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
SetTextureStageState(7, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(4, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(4, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(5, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(5, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(6, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(6, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(7, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
SetTextureStageState(7, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
|
||||
SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
SetTextureStageState(2, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
SetTextureStageState(3, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
SetTextureStageState(4, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
SetTextureStageState(5, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
SetTextureStageState(6, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
SetTextureStageState(7, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
|
||||
SetTexture(0, NULL);
|
||||
SetTexture(1, NULL);
|
||||
SetTexture(2, NULL);
|
||||
SetTexture(3, NULL);
|
||||
SetTexture(4, NULL);
|
||||
SetTexture(5, NULL);
|
||||
SetTexture(6, NULL);
|
||||
SetTexture(7, NULL);
|
||||
|
||||
SetPixelShader(0);
|
||||
SetVertexShader(D3DFVF_XYZ);
|
||||
|
||||
D3DXVECTOR4 av4Null[STATEMANAGER_MAX_VCONSTANTS];
|
||||
memset(av4Null, 0, sizeof(av4Null));
|
||||
SetVertexShaderConstant(0, av4Null, STATEMANAGER_MAX_VCONSTANTS);
|
||||
SetPixelShaderConstant(0, av4Null, STATEMANAGER_MAX_PCONSTANTS);
|
||||
|
||||
m_bForce = false;
|
||||
|
||||
#ifdef _DEBUG
|
||||
int i, j;
|
||||
for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++)
|
||||
m_bRenderStateSavingFlag[i] = FALSE;
|
||||
|
||||
for (j = 0; j < STATEMANAGER_MAX_TRANSFORMSTATES; j++)
|
||||
m_bTransformSavingFlag[j] = FALSE;
|
||||
|
||||
for (j = 0; j < STATEMANAGER_MAX_STAGES; ++j)
|
||||
for (i = 0; i < STATEMANAGER_MAX_TEXTURESTATES; ++i)
|
||||
m_bTextureStageStateSavingFlag[j][i] = FALSE;
|
||||
#endif _DEBUG
|
||||
}
|
||||
|
||||
// Material
|
||||
void CStateManager::SaveMaterial()
|
||||
{
|
||||
m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial;
|
||||
}
|
||||
|
||||
void CStateManager::SaveMaterial(const D3DMATERIAL8 * pMaterial)
|
||||
{
|
||||
// Check that we have set this up before, if not, the default is this.
|
||||
m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial;
|
||||
SetMaterial(pMaterial);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreMaterial()
|
||||
{
|
||||
SetMaterial(&m_CopyState.m_D3DMaterial);
|
||||
}
|
||||
|
||||
void CStateManager::SetMaterial(const D3DMATERIAL8 * pMaterial)
|
||||
{
|
||||
m_lpD3DDev->SetMaterial(pMaterial);
|
||||
m_CurrentState.m_D3DMaterial = *pMaterial;
|
||||
}
|
||||
|
||||
void CStateManager::GetMaterial(D3DMATERIAL8 * pMaterial)
|
||||
{
|
||||
// Set the renderstate and remember it.
|
||||
*pMaterial = m_CurrentState.m_D3DMaterial;
|
||||
}
|
||||
|
||||
// Renderstates
|
||||
DWORD CStateManager::GetRenderState(D3DRENDERSTATETYPE Type)
|
||||
{
|
||||
return m_CurrentState.m_RenderStates[Type];
|
||||
}
|
||||
|
||||
void CStateManager::SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (m_bRenderStateSavingFlag[Type])
|
||||
{
|
||||
Tracef(" CStateManager::SaveRenderState - This render state is already saved [%d, %d]\n", Type, dwValue);
|
||||
StateManager_Assert(!" This render state is already saved!");
|
||||
}
|
||||
m_bRenderStateSavingFlag[Type] = TRUE;
|
||||
#endif _DEBUG
|
||||
|
||||
// Check that we have set this up before, if not, the default is this.
|
||||
m_CopyState.m_RenderStates[Type] = m_CurrentState.m_RenderStates[Type];
|
||||
SetRenderState(Type, dwValue);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreRenderState(D3DRENDERSTATETYPE Type)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (!m_bRenderStateSavingFlag[Type])
|
||||
{
|
||||
Tracef(" CStateManager::SaveRenderState - This render state was not saved [%d, %d]\n", Type);
|
||||
StateManager_Assert(!" This render state was not saved!");
|
||||
}
|
||||
m_bRenderStateSavingFlag[Type] = FALSE;
|
||||
#endif _DEBUG
|
||||
|
||||
SetRenderState(Type, m_CopyState.m_RenderStates[Type]);
|
||||
}
|
||||
|
||||
void CStateManager::SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value)
|
||||
{
|
||||
if (m_CurrentState.m_RenderStates[Type] == Value)
|
||||
return;
|
||||
|
||||
m_lpD3DDev->SetRenderState(Type, Value);
|
||||
m_CurrentState.m_RenderStates[Type] = Value;
|
||||
}
|
||||
|
||||
void CStateManager::GetRenderState(D3DRENDERSTATETYPE Type, DWORD * pdwValue)
|
||||
{
|
||||
*pdwValue = m_CurrentState.m_RenderStates[Type];
|
||||
}
|
||||
|
||||
// Textures
|
||||
void CStateManager::SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture)
|
||||
{
|
||||
// Check that we have set this up before, if not, the default is this.
|
||||
m_CopyState.m_Textures[dwStage] = m_CurrentState.m_Textures[dwStage];
|
||||
SetTexture(dwStage, pTexture);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreTexture(DWORD dwStage)
|
||||
{
|
||||
SetTexture(dwStage, m_CopyState.m_Textures[dwStage]);
|
||||
}
|
||||
|
||||
void CStateManager::SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture)
|
||||
{
|
||||
if (pTexture == m_CurrentState.m_Textures[dwStage])
|
||||
return;
|
||||
|
||||
m_lpD3DDev->SetTexture(dwStage, pTexture);
|
||||
m_CurrentState.m_Textures[dwStage] = pTexture;
|
||||
}
|
||||
|
||||
void CStateManager::GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 * ppTexture)
|
||||
{
|
||||
*ppTexture = m_CurrentState.m_Textures[dwStage];
|
||||
}
|
||||
|
||||
// Texture stage states
|
||||
void CStateManager::SaveTextureStageState(DWORD dwStage,D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue)
|
||||
{
|
||||
// Check that we have set this up before, if not, the default is this.
|
||||
#ifdef _DEBUG
|
||||
if (m_bTextureStageStateSavingFlag[dwStage][Type])
|
||||
{
|
||||
Tracef(" CStateManager::SaveTextureStageState - This texture stage state is already saved [%d, %d]\n", dwStage, Type);
|
||||
StateManager_Assert(!" This texture stage state is already saved!");
|
||||
}
|
||||
m_bTextureStageStateSavingFlag[dwStage][Type] = TRUE;
|
||||
#endif _DEBUG
|
||||
m_CopyState.m_TextureStates[dwStage][Type] = m_CurrentState.m_TextureStates[dwStage][Type];
|
||||
SetTextureStageState(dwStage, Type, dwValue);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (!m_bTextureStageStateSavingFlag[dwStage][Type])
|
||||
{
|
||||
Tracef(" CStateManager::RestoreTextureStageState - This texture stage state was not saved [%d, %d]\n", dwStage, Type);
|
||||
StateManager_Assert(!" This texture stage state was not saved!");
|
||||
}
|
||||
m_bTextureStageStateSavingFlag[dwStage][Type] = FALSE;
|
||||
#endif _DEBUG
|
||||
SetTextureStageState(dwStage, Type, m_CopyState.m_TextureStates[dwStage][Type]);
|
||||
}
|
||||
|
||||
void CStateManager::SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue)
|
||||
{
|
||||
if (m_CurrentState.m_TextureStates[dwStage][Type] == dwValue)
|
||||
return;
|
||||
|
||||
m_lpD3DDev->SetTextureStageState(dwStage, Type, dwValue);
|
||||
m_CurrentState.m_TextureStates[dwStage][Type] = dwValue;
|
||||
}
|
||||
|
||||
void CStateManager::GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD * pdwValue)
|
||||
{
|
||||
*pdwValue = m_CurrentState.m_TextureStates[dwStage][Type];
|
||||
}
|
||||
|
||||
// Vertex Shader
|
||||
void CStateManager::SaveVertexShader(DWORD dwShader)
|
||||
{
|
||||
m_CopyState.m_dwVertexShader = m_CurrentState.m_dwVertexShader;
|
||||
SetVertexShader(dwShader);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreVertexShader()
|
||||
{
|
||||
SetVertexShader(m_CopyState.m_dwVertexShader);
|
||||
}
|
||||
|
||||
void CStateManager::SetVertexShader(DWORD dwShader)
|
||||
{
|
||||
if (m_CurrentState.m_dwVertexShader == dwShader)
|
||||
return;
|
||||
|
||||
m_lpD3DDev->SetVertexShader(dwShader);
|
||||
m_CurrentState.m_dwVertexShader = dwShader;
|
||||
}
|
||||
|
||||
void CStateManager::GetVertexShader(DWORD * pdwShader)
|
||||
{
|
||||
*pdwShader = m_CurrentState.m_dwVertexShader;
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
void CStateManager::SavePixelShader(DWORD dwShader)
|
||||
{
|
||||
m_CopyState.m_dwPixelShader = m_CurrentState.m_dwPixelShader;
|
||||
SetPixelShader(dwShader);
|
||||
}
|
||||
|
||||
void CStateManager::RestorePixelShader()
|
||||
{
|
||||
SetPixelShader(m_CopyState.m_dwPixelShader);
|
||||
}
|
||||
|
||||
void CStateManager::SetPixelShader(DWORD dwShader)
|
||||
{
|
||||
if (m_CurrentState.m_dwPixelShader == dwShader)
|
||||
return;
|
||||
|
||||
m_lpD3DDev->SetPixelShader(dwShader);
|
||||
m_CurrentState.m_dwPixelShader = dwShader;
|
||||
}
|
||||
|
||||
void CStateManager::GetPixelShader(DWORD * pdwShader)
|
||||
{
|
||||
*pdwShader = m_CurrentState.m_dwPixelShader;
|
||||
}
|
||||
|
||||
// *** These states are cached, but not protected from multiple sends of the same value.
|
||||
// Transform
|
||||
void CStateManager::SaveTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (m_bTransformSavingFlag[Type])
|
||||
{
|
||||
Tracef(" CStateManager::SaveTransform - This transform is already saved [%d]\n", Type);
|
||||
StateManager_Assert(!" This trasform is already saved!");
|
||||
}
|
||||
m_bTransformSavingFlag[Type] = TRUE;
|
||||
#endif _DEBUG
|
||||
|
||||
m_CopyState.m_Matrices[Type] = m_CurrentState.m_Matrices[Type];
|
||||
SetTransform(Type, (D3DXMATRIX *)pMatrix);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreTransform(D3DTRANSFORMSTATETYPE Type)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (!m_bTransformSavingFlag[Type])
|
||||
{
|
||||
Tracef(" CStateManager::RestoreTransform - This transform was not saved [%d]\n", Type);
|
||||
StateManager_Assert(!" This render state was not saved!");
|
||||
}
|
||||
m_bTransformSavingFlag[Type] = FALSE;
|
||||
#endif _DEBUG
|
||||
|
||||
SetTransform(Type, &m_CopyState.m_Matrices[Type]);
|
||||
}
|
||||
|
||||
// Don't cache-check the transform. To much to do
|
||||
void CStateManager::SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix)
|
||||
{
|
||||
if (m_bScene)
|
||||
{
|
||||
m_lpD3DDev->SetTransform(Type, pMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(D3DTS_VIEW==Type || D3DTS_PROJECTION==Type || D3DTS_WORLD==Type);
|
||||
}
|
||||
|
||||
m_CurrentState.m_Matrices[Type] = *pMatrix;
|
||||
}
|
||||
|
||||
void CStateManager::GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX * pMatrix)
|
||||
{
|
||||
*pMatrix = m_CurrentState.m_Matrices[Type];
|
||||
}
|
||||
|
||||
// SetVertexShaderConstant
|
||||
void CStateManager::SaveVertexShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < dwConstantCount; i++)
|
||||
{
|
||||
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
|
||||
m_CopyState.m_VertexShaderConstants[dwRegister + i] = m_CurrentState.m_VertexShaderConstants[dwRegister + i];
|
||||
}
|
||||
|
||||
SetVertexShaderConstant(dwRegister, pConstantData, dwConstantCount);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount)
|
||||
{
|
||||
SetVertexShaderConstant(dwRegister, &m_CopyState.m_VertexShaderConstants[dwRegister], dwConstantCount);
|
||||
}
|
||||
|
||||
void CStateManager::SetVertexShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
|
||||
{
|
||||
m_lpD3DDev->SetVertexShaderConstant(dwRegister, pConstantData, dwConstantCount);
|
||||
|
||||
// Set the renderstate and remember it.
|
||||
for (DWORD i = 0; i < dwConstantCount; i++)
|
||||
{
|
||||
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
|
||||
m_CurrentState.m_VertexShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
|
||||
}
|
||||
}
|
||||
|
||||
// SetPixelShaderConstant
|
||||
void CStateManager::SavePixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < dwConstantCount; i++)
|
||||
{
|
||||
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
|
||||
m_CopyState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
|
||||
}
|
||||
|
||||
SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount);
|
||||
}
|
||||
|
||||
void CStateManager::RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount)
|
||||
{
|
||||
SetPixelShaderConstant(dwRegister, &m_CopyState.m_PixelShaderConstants[dwRegister], dwConstantCount);
|
||||
}
|
||||
|
||||
void CStateManager::SetPixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
|
||||
{
|
||||
m_lpD3DDev->SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount);
|
||||
|
||||
// Set the renderstate and remember it.
|
||||
for (DWORD i = 0; i < dwConstantCount; i++)
|
||||
{
|
||||
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
|
||||
m_CurrentState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
|
||||
}
|
||||
}
|
||||
|
||||
void CStateManager::SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData,UINT Stride)
|
||||
{
|
||||
// Check that we have set this up before, if not, the default is this.
|
||||
m_CopyState.m_StreamData[StreamNumber] = m_CurrentState.m_StreamData[StreamNumber];
|
||||
SetStreamSource(StreamNumber, pStreamData, Stride);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreStreamSource(UINT StreamNumber)
|
||||
{
|
||||
SetStreamSource(StreamNumber,
|
||||
m_CopyState.m_StreamData[StreamNumber].m_lpStreamData,
|
||||
m_CopyState.m_StreamData[StreamNumber].m_Stride);
|
||||
}
|
||||
|
||||
void CStateManager::SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride)
|
||||
{
|
||||
CStreamData kStreamData(pStreamData, Stride);
|
||||
if (m_CurrentState.m_StreamData[StreamNumber] == kStreamData)
|
||||
return;
|
||||
|
||||
m_lpD3DDev->SetStreamSource(StreamNumber, pStreamData, Stride);
|
||||
m_CurrentState.m_StreamData[StreamNumber] = kStreamData;
|
||||
}
|
||||
|
||||
void CStateManager::SaveIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex)
|
||||
{
|
||||
m_CopyState.m_IndexData = m_CurrentState.m_IndexData;
|
||||
SetIndices(pIndexData, BaseVertexIndex);
|
||||
}
|
||||
|
||||
void CStateManager::RestoreIndices()
|
||||
{
|
||||
SetIndices(m_CopyState.m_IndexData.m_lpIndexData, m_CopyState.m_IndexData.m_BaseVertexIndex);
|
||||
}
|
||||
|
||||
void CStateManager::SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex)
|
||||
{
|
||||
CIndexData kIndexData(pIndexData, BaseVertexIndex);
|
||||
|
||||
if (m_CurrentState.m_IndexData == kIndexData)
|
||||
return;
|
||||
|
||||
m_lpD3DDev->SetIndices(pIndexData, BaseVertexIndex);
|
||||
m_CurrentState.m_IndexData = kIndexData;
|
||||
}
|
||||
|
||||
HRESULT CStateManager::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
|
||||
{
|
||||
return (m_lpD3DDev->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount));
|
||||
}
|
||||
|
||||
HRESULT CStateManager::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride)
|
||||
{
|
||||
m_CurrentState.m_StreamData[0] = NULL;
|
||||
return (m_lpD3DDev->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride));
|
||||
}
|
||||
|
||||
HRESULT CStateManager::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount)
|
||||
{
|
||||
return (m_lpD3DDev->DrawIndexedPrimitive(PrimitiveType, minIndex, NumVertices, startIndex, primCount));
|
||||
}
|
||||
|
||||
HRESULT CStateManager::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, D3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride)
|
||||
{
|
||||
m_CurrentState.m_IndexData = NULL;
|
||||
m_CurrentState.m_StreamData[0] = NULL;
|
||||
return (m_lpD3DDev->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride));
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 1999, 2000 NVIDIA Corporation
|
||||
|
||||
This file is provided without support, instruction, or implied warranty of any
|
||||
kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is
|
||||
not liable under any circumstances for any damages or loss whatsoever arising
|
||||
from the use or inability to use this file or items derived from it.
|
||||
|
||||
Comments:
|
||||
|
||||
A simple class to manage rendering state. Created as a singleton.
|
||||
Create it as a static global, or with new. It doesn't matter as long as it is created
|
||||
before you use the CStateManager::GetSingleton() API to get a reference to it.
|
||||
|
||||
Call it with STATEMANAGER.SetRenderState(...)
|
||||
Call it with STATEMANAGER.SetTextureStageState(...), etc.
|
||||
|
||||
Call the 'Save' versions of the function if you want to deviate from the current state.
|
||||
Call the 'Restore' version to retrieve the last Save.
|
||||
|
||||
There are two levels of caching:
|
||||
- All Sets/Saves/Restores are tracked for redundancy. This reduces the size of the batch to
|
||||
be flushed
|
||||
- The flush function is called before rendering, and only copies state that is
|
||||
different from the current chip state.
|
||||
|
||||
If you get an assert it is probably because an API call failed.
|
||||
|
||||
See NVLink for a good example of how this class is used.
|
||||
|
||||
Don't be afraid of the vector being used to track the flush batch. It will grow as big as
|
||||
it needs to be and then stop, so it shouldn't be reallocated.
|
||||
|
||||
The state manager holds a reference to the d3d device.
|
||||
|
||||
- cmaughan@nvidia.com
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CSTATEMANAGER_H
|
||||
#define __CSTATEMANAGER_H
|
||||
|
||||
#include <d3d8.h>
|
||||
#include <d3dx8.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../EterBase/Singleton.h"
|
||||
|
||||
#define CHECK_D3DAPI(a) \
|
||||
{ \
|
||||
HRESULT hr = (a); \
|
||||
\
|
||||
if (hr != S_OK) \
|
||||
assert(!#a); \
|
||||
}
|
||||
|
||||
static const DWORD STATEMANAGER_MAX_RENDERSTATES = 256;
|
||||
static const DWORD STATEMANAGER_MAX_TEXTURESTATES = 128;
|
||||
static const DWORD STATEMANAGER_MAX_STAGES = 8;
|
||||
static const DWORD STATEMANAGER_MAX_VCONSTANTS = 96;
|
||||
static const DWORD STATEMANAGER_MAX_PCONSTANTS = 8;
|
||||
static const DWORD STATEMANAGER_MAX_TRANSFORMSTATES = 300; // World1 lives way up there...
|
||||
static const DWORD STATEMANAGER_MAX_STREAMS = 16;
|
||||
|
||||
class CStreamData
|
||||
{
|
||||
public:
|
||||
CStreamData(LPDIRECT3DVERTEXBUFFER8 pStreamData = NULL, UINT Stride = 0) : m_lpStreamData(pStreamData), m_Stride(Stride)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const CStreamData& rhs) const
|
||||
{
|
||||
return ((m_lpStreamData == rhs.m_lpStreamData) && (m_Stride == rhs.m_Stride));
|
||||
}
|
||||
|
||||
LPDIRECT3DVERTEXBUFFER8 m_lpStreamData;
|
||||
UINT m_Stride;
|
||||
};
|
||||
|
||||
class CIndexData
|
||||
{
|
||||
public:
|
||||
CIndexData(LPDIRECT3DINDEXBUFFER8 pIndexData = NULL, UINT BaseVertexIndex = 0)
|
||||
: m_lpIndexData(pIndexData),
|
||||
m_BaseVertexIndex(BaseVertexIndex)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const CIndexData& rhs) const
|
||||
{
|
||||
return ((m_lpIndexData == rhs.m_lpIndexData) && (m_BaseVertexIndex == rhs.m_BaseVertexIndex));
|
||||
}
|
||||
|
||||
LPDIRECT3DINDEXBUFFER8 m_lpIndexData;
|
||||
UINT m_BaseVertexIndex;
|
||||
};
|
||||
|
||||
// State types managed by the class
|
||||
typedef enum eStateType
|
||||
{
|
||||
STATE_MATERIAL = 0,
|
||||
STATE_RENDER,
|
||||
STATE_TEXTURE,
|
||||
STATE_TEXTURESTAGE,
|
||||
STATE_VSHADER,
|
||||
STATE_PSHADER,
|
||||
STATE_TRANSFORM,
|
||||
STATE_VCONSTANT,
|
||||
STATE_PCONSTANT,
|
||||
STATE_STREAM,
|
||||
STATE_INDEX
|
||||
} eStateType;
|
||||
|
||||
class CStateID
|
||||
{
|
||||
public:
|
||||
CStateID(eStateType Type, DWORD dwValue0 = 0, DWORD dwValue1 = 0)
|
||||
: m_Type(Type),
|
||||
m_dwValue0(dwValue0),
|
||||
m_dwValue1(dwValue1)
|
||||
{
|
||||
}
|
||||
|
||||
CStateID(eStateType Type, DWORD dwStage, D3DTEXTURESTAGESTATETYPE StageType)
|
||||
: m_Type(Type),
|
||||
m_dwStage(dwStage),
|
||||
m_TextureStageStateType(StageType)
|
||||
{
|
||||
}
|
||||
|
||||
CStateID(eStateType Type, D3DRENDERSTATETYPE RenderType)
|
||||
: m_Type(Type),
|
||||
m_RenderStateType(RenderType)
|
||||
{
|
||||
}
|
||||
|
||||
eStateType m_Type;
|
||||
|
||||
union
|
||||
{
|
||||
DWORD m_dwValue0;
|
||||
DWORD m_dwStage;
|
||||
D3DRENDERSTATETYPE m_RenderStateType;
|
||||
D3DTRANSFORMSTATETYPE m_TransformStateType;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
DWORD m_dwValue1;
|
||||
D3DTEXTURESTAGESTATETYPE m_TextureStageStateType;
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::vector<CStateID> TStateID;
|
||||
|
||||
class CStateManagerState
|
||||
{
|
||||
public:
|
||||
CStateManagerState()
|
||||
{
|
||||
}
|
||||
|
||||
void ResetState()
|
||||
{
|
||||
DWORD i, y;
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++)
|
||||
m_RenderStates[i] = 0x7FFFFFFF;
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_STAGES; i++)
|
||||
for (y = 0; y < STATEMANAGER_MAX_TEXTURESTATES; y++)
|
||||
m_TextureStates[i][y] = 0x7FFFFFFF;
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_STREAMS; i++)
|
||||
m_StreamData[i] = CStreamData();
|
||||
|
||||
m_IndexData = CIndexData();
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_STAGES; i++)
|
||||
m_Textures[i] = NULL;
|
||||
|
||||
// Matrices and constants are not cached, just restored. It's silly to check all the
|
||||
// data elements (by which time the driver could have been sent them).
|
||||
for (i = 0; i < STATEMANAGER_MAX_TRANSFORMSTATES; i++)
|
||||
D3DXMatrixIdentity(&m_Matrices[i]);
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_VCONSTANTS; i++)
|
||||
m_VertexShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
for (i = 0; i < STATEMANAGER_MAX_PCONSTANTS; i++)
|
||||
m_PixelShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_dwPixelShader = 0;
|
||||
m_dwVertexShader = D3DFVF_XYZ;
|
||||
|
||||
ZeroMemory(&m_Matrices, sizeof(D3DXMATRIX) * STATEMANAGER_MAX_TRANSFORMSTATES);
|
||||
}
|
||||
|
||||
// Renderstates
|
||||
DWORD m_RenderStates[STATEMANAGER_MAX_RENDERSTATES];
|
||||
|
||||
// Texture stage states
|
||||
DWORD m_TextureStates[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];
|
||||
|
||||
// Vertex shader constants
|
||||
D3DXVECTOR4 m_VertexShaderConstants[STATEMANAGER_MAX_VCONSTANTS];
|
||||
|
||||
// Pixel shader constants
|
||||
D3DXVECTOR4 m_PixelShaderConstants[STATEMANAGER_MAX_PCONSTANTS];
|
||||
|
||||
// Textures
|
||||
LPDIRECT3DBASETEXTURE8 m_Textures[STATEMANAGER_MAX_STAGES];
|
||||
|
||||
// Shaders
|
||||
DWORD m_dwPixelShader;
|
||||
DWORD m_dwVertexShader;
|
||||
|
||||
D3DXMATRIX m_Matrices[STATEMANAGER_MAX_TRANSFORMSTATES];
|
||||
|
||||
D3DMATERIAL8 m_D3DMaterial;
|
||||
|
||||
CStreamData m_StreamData[STATEMANAGER_MAX_STREAMS];
|
||||
CIndexData m_IndexData;
|
||||
};
|
||||
|
||||
class CStateManager : public CSingleton<CStateManager>
|
||||
{
|
||||
public:
|
||||
CStateManager(LPDIRECT3DDEVICE8 lpDevice);
|
||||
virtual ~CStateManager();
|
||||
|
||||
void SetDefaultState();
|
||||
void Restore();
|
||||
|
||||
bool BeginScene();
|
||||
void EndScene();
|
||||
|
||||
// Material
|
||||
void SaveMaterial();
|
||||
void SaveMaterial(const D3DMATERIAL8 * pMaterial);
|
||||
void RestoreMaterial();
|
||||
void SetMaterial(const D3DMATERIAL8 * pMaterial);
|
||||
void GetMaterial(D3DMATERIAL8 * pMaterial);
|
||||
|
||||
void SetLight(DWORD index, CONST D3DLIGHT8* pLight);
|
||||
void GetLight(DWORD index, D3DLIGHT8* pLight);
|
||||
|
||||
// Renderstates
|
||||
void SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue);
|
||||
void RestoreRenderState(D3DRENDERSTATETYPE Type);
|
||||
void SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value);
|
||||
void GetRenderState(D3DRENDERSTATETYPE Type, DWORD * pdwValue);
|
||||
|
||||
// Textures
|
||||
void SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture);
|
||||
void RestoreTexture(DWORD dwStage);
|
||||
void SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture);
|
||||
void GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 * ppTexture);
|
||||
|
||||
// Texture stage states
|
||||
void SaveTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue);
|
||||
void RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type);
|
||||
void SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue);
|
||||
void GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD * pdwValue);
|
||||
void SetBestFiltering(DWORD dwStage); // if possible set anisotropy filtering, or use trilinear
|
||||
|
||||
// Vertex Shader
|
||||
void SaveVertexShader(DWORD dwShader);
|
||||
void RestoreVertexShader();
|
||||
void SetVertexShader(DWORD dwShader);
|
||||
void GetVertexShader(DWORD * pdwShader);
|
||||
|
||||
// Pixel Shader
|
||||
void SavePixelShader(DWORD dwShader);
|
||||
void RestorePixelShader();
|
||||
void SetPixelShader(DWORD dwShader);
|
||||
void GetPixelShader(DWORD * pdwShader);
|
||||
|
||||
// *** These states are cached, but not protected from multiple sends of the same value.
|
||||
// Transform
|
||||
void SaveTransform(D3DTRANSFORMSTATETYPE Transform, const D3DMATRIX* pMatrix);
|
||||
void RestoreTransform(D3DTRANSFORMSTATETYPE Transform);
|
||||
|
||||
// Don't cache-check the transform. To much to do
|
||||
void SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix);
|
||||
void GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX * pMatrix);
|
||||
|
||||
// SetVertexShaderConstant
|
||||
void SaveVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
|
||||
void RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount);
|
||||
void SetVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
|
||||
|
||||
// SetPixelShaderConstant
|
||||
void SavePixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
|
||||
void RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount);
|
||||
void SetPixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
|
||||
|
||||
void SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride);
|
||||
void RestoreStreamSource(UINT StreamNumber);
|
||||
void SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride);
|
||||
|
||||
void SaveIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex);
|
||||
void RestoreIndices();
|
||||
void SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexData,UINT BaseVertexIndex);
|
||||
|
||||
HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
|
||||
HRESULT DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
|
||||
HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount);
|
||||
HRESULT DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, D3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride);
|
||||
|
||||
// Codes For Debug
|
||||
DWORD GetRenderState(D3DRENDERSTATETYPE Type);
|
||||
|
||||
private:
|
||||
void SetDevice(LPDIRECT3DDEVICE8 lpDevice);
|
||||
|
||||
private:
|
||||
CStateManagerState m_ChipState;
|
||||
CStateManagerState m_CurrentState;
|
||||
CStateManagerState m_CopyState;
|
||||
TStateID m_DirtyStates;
|
||||
bool m_bForce;
|
||||
bool m_bScene;
|
||||
DWORD m_dwBestMinFilter;
|
||||
DWORD m_dwBestMagFilter;
|
||||
LPDIRECT3DDEVICE8 m_lpD3DDev;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Saving Flag
|
||||
BOOL m_bRenderStateSavingFlag[STATEMANAGER_MAX_RENDERSTATES];
|
||||
BOOL m_bTextureStageStateSavingFlag[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];
|
||||
BOOL m_bTransformSavingFlag[STATEMANAGER_MAX_TRANSFORMSTATES];
|
||||
#endif _DEBUG
|
||||
};
|
||||
|
||||
#define STATEMANAGER (CStateManager::Instance())
|
||||
|
||||
#endif __CSTATEMANAGER_H
|
||||
@@ -0,0 +1,142 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#define _WIN32_DCOM
|
||||
|
||||
#pragma warning(disable:4710) // not inlined
|
||||
#pragma warning(disable:4786) // character 255 넘어가는거 끄기
|
||||
#pragma warning(disable:4244) // type conversion possible lose of data
|
||||
|
||||
#pragma warning(disable:4018)
|
||||
#pragma warning(disable:4245)
|
||||
#pragma warning(disable:4512)
|
||||
#pragma warning(disable:4201)
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
#pragma warning(disable:4201 4512 4238 4239)
|
||||
#endif
|
||||
|
||||
#include <d3d8.h>
|
||||
#include <d3dx8.h>
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
|
||||
#include <dinput.h>
|
||||
|
||||
#pragma warning ( disable : 4201 )
|
||||
#include <mmsystem.h>
|
||||
#pragma warning ( default : 4201 )
|
||||
#include <process.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <direct.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
#pragma comment(lib, "d3d8.lib")
|
||||
#pragma comment(lib, "d3dx8.lib")
|
||||
|
||||
#include "../EterBase/StdAfx.h"
|
||||
#include "../EterBase/Debug.h"
|
||||
#include "../EterLocale/CodePageId.h"
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
#include "Pool.h"
|
||||
#include "Dynamic.h"
|
||||
#include "Event.h"
|
||||
#include "FuncObject.h"
|
||||
#include "ReferenceObject.h"
|
||||
#include "Ref.h"
|
||||
|
||||
#include "Util.h"
|
||||
#include "TextFileLoader.h"
|
||||
#include "parser.h"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
#include "MSWindow.h"
|
||||
#include "MSApplication.h"
|
||||
#include "Mutex.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#include "GrpBase.h"
|
||||
|
||||
#include "GrpDIB.h"
|
||||
#include "GrpMath.h"
|
||||
#include "GrpDevice.h"
|
||||
|
||||
#include "CollisionData.h"
|
||||
#include "GrpCollisionObject.h"
|
||||
#include "GrpScreen.h"
|
||||
#include "CullingManager.h"
|
||||
|
||||
// Attribute
|
||||
#include "AttributeData.h"
|
||||
#include "AttributeInstance.h"
|
||||
|
||||
#include "GrpObjectInstance.h"
|
||||
#include "GrpRatioInstance.h"
|
||||
|
||||
#include "GrpD3DXBuffer.h"
|
||||
|
||||
#include "GrpTexture.h"
|
||||
#include "GrpImageTexture.h"
|
||||
#include "GrpFontTexture.h"
|
||||
|
||||
#include "GrpText.h"
|
||||
#include "GrpImage.h"
|
||||
#include "GrpSubImage.h"
|
||||
|
||||
#include "GrpIndexBuffer.h"
|
||||
#include "GrpVertexBuffer.h"
|
||||
#include "GrpVertexBufferStatic.h"
|
||||
#include "GrpVertexBufferDynamic.h"
|
||||
#include "GrpVertexShader.h"
|
||||
#include "GrpPixelShader.h"
|
||||
|
||||
|
||||
#include "GrpShadowTexture.h"
|
||||
#include "GrpImageInstance.h"
|
||||
#include "GrpExpandedImageInstance.h"
|
||||
#include "GrpTextInstance.h"
|
||||
#include "GrpLightManager.h"
|
||||
|
||||
#include "TargaResource.h"
|
||||
|
||||
#include "NetDevice.h"
|
||||
#include "NetAddress.h"
|
||||
// #include "NetStream.h"
|
||||
#include "NetPacketHeaderMap.h"
|
||||
#include "NetDatagramSender.h"
|
||||
#include "NetDatagramReceiver.h"
|
||||
|
||||
#include "Input.h"
|
||||
#include "IME.h"
|
||||
|
||||
#include "PathStack.h"
|
||||
//#include "Property.h"
|
||||
|
||||
#include "Profiler.h"
|
||||
|
||||
#include "StateManager.h"
|
||||
|
||||
#include "ColorTransitionHelper.h"
|
||||
#include "LensFlare.h"
|
||||
#include "ScreenFilter.h"
|
||||
#include "EnvironmentMap.h"
|
||||
|
||||
#include "lineintersect_utils.h"
|
||||
|
||||
#include "Decal.h"
|
||||
*/
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "DibBar.h"
|
||||
|
||||
class CTextBar : public CDibBar
|
||||
{
|
||||
public:
|
||||
CTextBar(int fontSize, bool isBold);
|
||||
virtual ~CTextBar();
|
||||
|
||||
void TextOut(int ix, int iy, const char * c_szText);
|
||||
void SetTextColor(int r, int g, int b);
|
||||
void GetTextExtent(const char * c_szText, SIZE* p_size);
|
||||
|
||||
protected:
|
||||
void __SetFont(int fontSize, bool isBold);
|
||||
|
||||
void OnCreate();
|
||||
|
||||
protected:
|
||||
HFONT m_hFont;
|
||||
HFONT m_hOldFont;
|
||||
|
||||
int m_fontSize;
|
||||
bool m_isBold;
|
||||
};
|
||||
@@ -0,0 +1,696 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterBase/CRC32.h"
|
||||
#include <string>
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "Pool.h"
|
||||
#include "TextFileLoader.h"
|
||||
|
||||
std::map<DWORD, CTextFileLoader*> CTextFileLoader::ms_kMap_dwNameKey_pkTextFileLoader;
|
||||
bool CTextFileLoader::ms_isCacheMode=false;
|
||||
|
||||
CDynamicPool<CTextFileLoader::SGroupNode> CTextFileLoader::SGroupNode::ms_kPool;
|
||||
|
||||
CTokenVector* CTextFileLoader::SGroupNode::GetTokenVector(const std::string& c_rstGroupName)
|
||||
{
|
||||
DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length());
|
||||
|
||||
std::map<DWORD, CTokenVector>::iterator f=m_kMap_dwKey_kVct_stToken.find(dwGroupNameKey);
|
||||
if (m_kMap_dwKey_kVct_stToken.end()==f)
|
||||
return NULL;
|
||||
|
||||
return &f->second;
|
||||
}
|
||||
|
||||
bool CTextFileLoader::SGroupNode::IsExistTokenVector(const std::string& c_rstGroupName)
|
||||
{
|
||||
DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length());
|
||||
|
||||
if (m_kMap_dwKey_kVct_stToken.end()==m_kMap_dwKey_kVct_stToken.find(dwGroupNameKey))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTextFileLoader::SGroupNode::InsertTokenVector(const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken)
|
||||
{
|
||||
DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length());
|
||||
|
||||
m_kMap_dwKey_kVct_stToken.insert(std::map<DWORD, CTokenVector>::value_type(dwGroupNameKey, c_rkVct_stToken));
|
||||
}
|
||||
|
||||
DWORD CTextFileLoader::SGroupNode::GenNameKey(const char* c_szGroupName, UINT uGroupNameLen)
|
||||
{
|
||||
return GetCRC32(c_szGroupName, uGroupNameLen);
|
||||
}
|
||||
|
||||
const std::string& CTextFileLoader::SGroupNode::GetGroupName()
|
||||
{
|
||||
return m_strGroupName;
|
||||
}
|
||||
|
||||
bool CTextFileLoader::SGroupNode::IsGroupNameKey(DWORD dwGroupNameKey)
|
||||
{
|
||||
if (dwGroupNameKey==m_dwGroupNameKey)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CTextFileLoader::SGroupNode::SetGroupName(const std::string& c_rstGroupName)
|
||||
{
|
||||
m_strGroupName=c_rstGroupName;
|
||||
stl_lowers(m_strGroupName);
|
||||
|
||||
m_dwGroupNameKey=GenNameKey(m_strGroupName.c_str(), m_strGroupName.length());
|
||||
}
|
||||
|
||||
|
||||
CTextFileLoader::SGroupNode* CTextFileLoader::SGroupNode::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CTextFileLoader::SGroupNode::Delete(SGroupNode* pkNode)
|
||||
{
|
||||
pkNode->m_kMap_dwKey_kVct_stToken.clear();
|
||||
pkNode->ChildNodeVector.clear();
|
||||
pkNode->m_strGroupName="";
|
||||
pkNode->m_dwGroupNameKey=0;
|
||||
ms_kPool.Free(pkNode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CTextFileLoader::SGroupNode::DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
}
|
||||
|
||||
|
||||
CTextFileLoader* CTextFileLoader::Cache(const char* c_szFileName)
|
||||
{
|
||||
DWORD dwNameKey=GetCRC32(c_szFileName, strlen(c_szFileName));
|
||||
std::map<DWORD, CTextFileLoader*>::iterator f=ms_kMap_dwNameKey_pkTextFileLoader.find(dwNameKey);
|
||||
if (ms_kMap_dwNameKey_pkTextFileLoader.end()!=f)
|
||||
{
|
||||
if (!ms_isCacheMode)
|
||||
{
|
||||
delete f->second;
|
||||
|
||||
CTextFileLoader* pkNewTextFileLoader=new CTextFileLoader;
|
||||
pkNewTextFileLoader->Load(c_szFileName);
|
||||
f->second=pkNewTextFileLoader;
|
||||
}
|
||||
f->second->SetTop();
|
||||
return f->second;
|
||||
}
|
||||
|
||||
CTextFileLoader* pkNewTextFileLoader=new CTextFileLoader;
|
||||
pkNewTextFileLoader->Load(c_szFileName);
|
||||
|
||||
ms_kMap_dwNameKey_pkTextFileLoader.insert(std::map<DWORD, CTextFileLoader*>::value_type(dwNameKey, pkNewTextFileLoader));
|
||||
return pkNewTextFileLoader;
|
||||
}
|
||||
|
||||
void CTextFileLoader::SetCacheMode()
|
||||
{
|
||||
ms_isCacheMode=true;
|
||||
}
|
||||
|
||||
void CTextFileLoader::DestroySystem()
|
||||
{
|
||||
{
|
||||
std::map<DWORD, CTextFileLoader*>::iterator i;
|
||||
for (i=ms_kMap_dwNameKey_pkTextFileLoader.begin(); i!=ms_kMap_dwNameKey_pkTextFileLoader.end(); ++i)
|
||||
delete i->second;
|
||||
ms_kMap_dwNameKey_pkTextFileLoader.clear();
|
||||
}
|
||||
|
||||
SGroupNode::DestroySystem();
|
||||
}
|
||||
|
||||
void CTextFileLoader::Destroy()
|
||||
{
|
||||
__DestroyGroupNodeVector();
|
||||
}
|
||||
|
||||
CTextFileLoader::CTextFileLoader()
|
||||
{
|
||||
SetTop();
|
||||
|
||||
m_acBufData=NULL;
|
||||
m_dwBufSize=0;
|
||||
m_dwBufCapacity=0;
|
||||
|
||||
m_GlobalNode.m_strGroupName = "global";
|
||||
m_GlobalNode.pParentNode = NULL;
|
||||
|
||||
m_kVct_pkNode.reserve(128);
|
||||
}
|
||||
|
||||
CTextFileLoader::~CTextFileLoader()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (m_acBufData)
|
||||
delete [] m_acBufData;
|
||||
}
|
||||
|
||||
void CTextFileLoader::__DestroyGroupNodeVector()
|
||||
{
|
||||
std::vector<SGroupNode*>::iterator i;
|
||||
for (i=m_kVct_pkNode.begin(); i!=m_kVct_pkNode.end(); ++i)
|
||||
SGroupNode::Delete(*i);
|
||||
m_kVct_pkNode.clear();
|
||||
}
|
||||
|
||||
const char * CTextFileLoader::GetFileName()
|
||||
{
|
||||
return m_strFileName.c_str();
|
||||
}
|
||||
|
||||
bool CTextFileLoader::IsEmpty()
|
||||
{
|
||||
return m_strFileName.empty();
|
||||
}
|
||||
|
||||
bool CTextFileLoader::Load(const char * c_szFileName)
|
||||
{
|
||||
m_strFileName = "";
|
||||
|
||||
const VOID* pvData;
|
||||
CMappedFile kFile;
|
||||
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
|
||||
return false;
|
||||
|
||||
if (m_dwBufCapacity<kFile.Size())
|
||||
{
|
||||
m_dwBufCapacity=kFile.Size();
|
||||
|
||||
if (m_acBufData)
|
||||
delete [] m_acBufData;
|
||||
|
||||
m_acBufData=new char[m_dwBufCapacity];
|
||||
}
|
||||
|
||||
m_dwBufSize=kFile.Size();
|
||||
memcpy(m_acBufData, pvData, m_dwBufSize);
|
||||
|
||||
m_strFileName = c_szFileName;
|
||||
m_dwcurLineIndex = 0;
|
||||
|
||||
m_textFileLoader.Bind(m_dwBufSize, m_acBufData);
|
||||
return LoadGroup(&m_GlobalNode);
|
||||
}
|
||||
|
||||
bool CTextFileLoader::LoadGroup(TGroupNode * pGroupNode)
|
||||
{
|
||||
CTokenVector stTokenVector;
|
||||
int nLocalGroupDepth = 0;
|
||||
|
||||
for (; m_dwcurLineIndex < m_textFileLoader.GetLineCount(); ++m_dwcurLineIndex)
|
||||
{
|
||||
int iRet;
|
||||
|
||||
if ((iRet = m_textFileLoader.SplitLine2(m_dwcurLineIndex, &stTokenVector)) != 0)
|
||||
{
|
||||
if (iRet == -2)
|
||||
TraceError("cannot find \" in %s:%lu", m_strFileName.c_str(), m_dwcurLineIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
|
||||
if ('{' == stTokenVector[0][0])
|
||||
{
|
||||
nLocalGroupDepth++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('}' == stTokenVector[0][0]) {
|
||||
nLocalGroupDepth--;
|
||||
break;
|
||||
}
|
||||
|
||||
// Group
|
||||
if (0 == stTokenVector[0].compare("group"))
|
||||
{
|
||||
if (2 != stTokenVector.size())
|
||||
{
|
||||
assert(!"There is no group name!");
|
||||
continue;
|
||||
}
|
||||
|
||||
TGroupNode * pNewNode = TGroupNode::New();
|
||||
m_kVct_pkNode.push_back(pNewNode);
|
||||
|
||||
pNewNode->pParentNode = pGroupNode;
|
||||
pNewNode->SetGroupName(stTokenVector[1]);
|
||||
pGroupNode->ChildNodeVector.push_back(pNewNode);
|
||||
|
||||
++m_dwcurLineIndex;
|
||||
|
||||
if( false == LoadGroup(pNewNode) )
|
||||
return false;
|
||||
}
|
||||
// List
|
||||
else if (0 == stTokenVector[0].compare("list"))
|
||||
{
|
||||
if (2 != stTokenVector.size())
|
||||
{
|
||||
assert(!"There is no list name!");
|
||||
continue;
|
||||
}
|
||||
|
||||
CTokenVector stSubTokenVector;
|
||||
|
||||
stl_lowers(stTokenVector[1]);
|
||||
std::string key = stTokenVector[1];
|
||||
|
||||
stTokenVector.clear();
|
||||
|
||||
++m_dwcurLineIndex;
|
||||
for (; m_dwcurLineIndex < m_textFileLoader.GetLineCount(); ++m_dwcurLineIndex)
|
||||
{
|
||||
if (!m_textFileLoader.SplitLine(m_dwcurLineIndex, &stSubTokenVector))
|
||||
continue;
|
||||
|
||||
if ('{' == stSubTokenVector[0][0])
|
||||
continue;
|
||||
|
||||
if ('}' == stSubTokenVector[0][0])
|
||||
break;
|
||||
|
||||
for (DWORD j = 0; j < stSubTokenVector.size(); ++j)
|
||||
{
|
||||
stTokenVector.push_back(stSubTokenVector[j]);
|
||||
}
|
||||
}
|
||||
|
||||
pGroupNode->InsertTokenVector(key, stTokenVector);
|
||||
//pGroupNode->LocalTokenVectorMap.insert(std::make_pair(key, stTokenVector));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string key = stTokenVector[0];
|
||||
|
||||
if (1 == stTokenVector.size())
|
||||
{
|
||||
TraceError("CTextFileLoader::LoadGroup : must have a value (filename: %s line: %d key: %s)",
|
||||
m_strFileName.c_str(),
|
||||
m_dwcurLineIndex,
|
||||
key.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
stTokenVector.erase(stTokenVector.begin());
|
||||
pGroupNode->InsertTokenVector(key, stTokenVector);
|
||||
//pGroupNode->LocalTokenVectorMap.insert(std::make_pair(key, stTokenVector));
|
||||
}
|
||||
}
|
||||
|
||||
return (nLocalGroupDepth == 0);
|
||||
}
|
||||
|
||||
void CTextFileLoader::SetTop()
|
||||
{
|
||||
m_pcurNode = &m_GlobalNode;
|
||||
}
|
||||
|
||||
DWORD CTextFileLoader::GetChildNodeCount()
|
||||
{
|
||||
if (!m_pcurNode)
|
||||
{
|
||||
assert(!"Node to access has not set!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_pcurNode->ChildNodeVector.size();
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::SetChildNode(const char * c_szKey)
|
||||
{
|
||||
if (!m_pcurNode)
|
||||
{
|
||||
assert(!"Node to access has not set!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD dwKey=SGroupNode::GenNameKey(c_szKey, strlen(c_szKey));
|
||||
|
||||
for (DWORD i = 0; i < m_pcurNode->ChildNodeVector.size(); ++i)
|
||||
{
|
||||
TGroupNode * pGroupNode = m_pcurNode->ChildNodeVector[i];
|
||||
if (pGroupNode->IsGroupNameKey(dwKey))
|
||||
{
|
||||
m_pcurNode = pGroupNode;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
BOOL CTextFileLoader::SetChildNode(const std::string & c_rstrKeyHead, DWORD dwIndex)
|
||||
{
|
||||
char szKey[32+1];
|
||||
_snprintf(szKey, sizeof(szKey), "%s%02u", c_rstrKeyHead.c_str(), dwIndex);
|
||||
|
||||
return SetChildNode(szKey);
|
||||
}
|
||||
BOOL CTextFileLoader::SetChildNode(DWORD dwIndex)
|
||||
{
|
||||
if (!m_pcurNode)
|
||||
{
|
||||
assert(!"Node to access has not set!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dwIndex >= m_pcurNode->ChildNodeVector.size())
|
||||
{
|
||||
assert(!"Node index to set is too large to access!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_pcurNode = m_pcurNode->ChildNodeVector[dwIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::SetParentNode()
|
||||
{
|
||||
if (!m_pcurNode)
|
||||
{
|
||||
assert(!"Node to access has not set!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (NULL == m_pcurNode->pParentNode)
|
||||
{
|
||||
assert(!"Current group node is already top!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_pcurNode = m_pcurNode->pParentNode;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetCurrentNodeName(std::string * pstrName)
|
||||
{
|
||||
if (!m_pcurNode)
|
||||
return FALSE;
|
||||
if (NULL == m_pcurNode->pParentNode)
|
||||
return FALSE;
|
||||
|
||||
*pstrName = m_pcurNode->GetGroupName();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::IsToken(const std::string & c_rstrKey)
|
||||
{
|
||||
if (!m_pcurNode)
|
||||
{
|
||||
assert(!"Node to access has not set!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return m_pcurNode->IsExistTokenVector(c_rstrKey);
|
||||
//return m_pcurNode->LocalTokenVectorMap.end() != m_pcurNode->LocalTokenVectorMap.find(c_rstrKey);
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenVector(const std::string & c_rstrKey, CTokenVector ** ppTokenVector)
|
||||
{
|
||||
if (!m_pcurNode)
|
||||
{
|
||||
assert(!"Node to access has not set!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CTokenVector* pkRetTokenVector=m_pcurNode->GetTokenVector(c_rstrKey);
|
||||
if (!pkRetTokenVector)
|
||||
return FALSE;
|
||||
|
||||
*ppTokenVector = pkRetTokenVector;
|
||||
|
||||
//CTokenVectorMap::iterator itor = m_pcurNode->LocalTokenVectorMap.find(c_rstrKey);
|
||||
//if (m_pcurNode->LocalTokenVectorMap.end() == itor)
|
||||
//{
|
||||
//Tracef(" CTextFileLoader::GetTokenVector - Failed to find the key %s [%s :: %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
// return FALSE;
|
||||
//}
|
||||
|
||||
//*ppTokenVector = &itor->second;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenBoolean(const std::string & c_rstrKey, BOOL * pData)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->empty())
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenBoolean - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pData = BOOL(atoi(pTokenVector->at(0).c_str()));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenByte(const std::string & c_rstrKey, BYTE * pData)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->empty())
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenByte - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pData = BYTE(atoi(pTokenVector->at(0).c_str()));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenWord(const std::string & c_rstrKey, WORD * pData)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->empty())
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenWord - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pData = WORD(atoi(pTokenVector->at(0).c_str()));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenInteger(const std::string & c_rstrKey, int * pData)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->empty())
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenInteger - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pData = atoi(pTokenVector->at(0).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenDoubleWord(const std::string & c_rstrKey, DWORD * pData)
|
||||
{
|
||||
return GetTokenInteger(c_rstrKey, *(int **)(&pData));
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenFloat(const std::string & c_rstrKey, float * pData)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->empty())
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenFloat - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pData = atof(pTokenVector->at(0).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenVector2(const std::string & c_rstrKey, D3DXVECTOR2 * pVector2)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->size() != 2)
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenVector2 - This key should have 2 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pVector2->x = atof(pTokenVector->at(0).c_str());
|
||||
pVector2->y = atof(pTokenVector->at(1).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenVector3(const std::string & c_rstrKey, D3DXVECTOR3 * pVector3)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->size() != 3)
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pVector3->x = atof(pTokenVector->at(0).c_str());
|
||||
pVector3->y = atof(pTokenVector->at(1).c_str());
|
||||
pVector3->z = atof(pTokenVector->at(2).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenVector4(const std::string & c_rstrKey, D3DXVECTOR4 * pVector4)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->size() != 4)
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pVector4->x = atof(pTokenVector->at(0).c_str());
|
||||
pVector4->y = atof(pTokenVector->at(1).c_str());
|
||||
pVector4->z = atof(pTokenVector->at(2).c_str());
|
||||
pVector4->w = atof(pTokenVector->at(3).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CTextFileLoader::GetTokenPosition(const std::string & c_rstrKey, D3DXVECTOR3 * pVector)
|
||||
{
|
||||
return GetTokenVector3(c_rstrKey, pVector);
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenQuaternion(const std::string & c_rstrKey, D3DXQUATERNION * pQ)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->size() != 4)
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pQ->x = atof(pTokenVector->at(0).c_str());
|
||||
pQ->y = atof(pTokenVector->at(1).c_str());
|
||||
pQ->z = atof(pTokenVector->at(2).c_str());
|
||||
pQ->w = atof(pTokenVector->at(3).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenDirection(const std::string & c_rstrKey, D3DVECTOR * pVector)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->size() != 3)
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenDirection - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pVector->x = atof(pTokenVector->at(0).c_str());
|
||||
pVector->y = atof(pTokenVector->at(1).c_str());
|
||||
pVector->z = atof(pTokenVector->at(2).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenColor(const std::string & c_rstrKey, D3DXCOLOR * pColor)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->size() != 4)
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenColor - This key should have 4 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pColor->r = atof(pTokenVector->at(0).c_str());
|
||||
pColor->g = atof(pTokenVector->at(1).c_str());
|
||||
pColor->b = atof(pTokenVector->at(2).c_str());
|
||||
pColor->a = atof(pTokenVector->at(3).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenColor(const std::string & c_rstrKey, D3DCOLORVALUE * pColor)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->size() != 4)
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenColor - This key should have 4 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pColor->r = atof(pTokenVector->at(0).c_str());
|
||||
pColor->g = atof(pTokenVector->at(1).c_str());
|
||||
pColor->b = atof(pTokenVector->at(2).c_str());
|
||||
pColor->a = atof(pTokenVector->at(3).c_str());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CTextFileLoader::GetTokenString(const std::string & c_rstrKey, std::string * pString)
|
||||
{
|
||||
CTokenVector * pTokenVector;
|
||||
if (!GetTokenVector(c_rstrKey, &pTokenVector))
|
||||
return FALSE;
|
||||
|
||||
if (pTokenVector->empty())
|
||||
{
|
||||
//Tracef(" CTextFileLoader::GetTokenString - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pString = pTokenVector->at(0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
#ifndef __INC_METIN_II_TEXTFILELOADER_H__
|
||||
#define __INC_METIN_II_TEXTFILELOADER_H__
|
||||
|
||||
#include "../EterBase/FileLoader.h"
|
||||
#include "../EterBase/MappedFile.h"
|
||||
#include "../EterLib/Util.h"
|
||||
#include "../EterLib/Pool.h"
|
||||
|
||||
class CTextFileLoader
|
||||
{
|
||||
public:
|
||||
typedef struct SGroupNode
|
||||
{
|
||||
static DWORD GenNameKey(const char* c_szGroupName, UINT uGroupNameLen);
|
||||
|
||||
void SetGroupName(const std::string& c_rstGroupName);
|
||||
bool IsGroupNameKey(DWORD dwGroupNameKey);
|
||||
|
||||
const std::string& GetGroupName();
|
||||
|
||||
CTokenVector* GetTokenVector(const std::string& c_rstGroupName);
|
||||
bool IsExistTokenVector(const std::string& c_rstGroupName);
|
||||
void InsertTokenVector(const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken);
|
||||
|
||||
DWORD m_dwGroupNameKey;
|
||||
std::string m_strGroupName;
|
||||
|
||||
std::map<DWORD, CTokenVector> m_kMap_dwKey_kVct_stToken;
|
||||
|
||||
SGroupNode * pParentNode;
|
||||
std::vector<SGroupNode*> ChildNodeVector;
|
||||
|
||||
static SGroupNode* New();
|
||||
static void Delete(SGroupNode* pkNode);
|
||||
|
||||
static void DestroySystem();
|
||||
static CDynamicPool<SGroupNode> ms_kPool;
|
||||
} TGroupNode;
|
||||
|
||||
typedef std::vector<TGroupNode*> TGroupNodeVector;
|
||||
|
||||
class CGotoChild
|
||||
{
|
||||
public:
|
||||
CGotoChild(CTextFileLoader * pOwner, const char * c_szKey) : m_pOwner(pOwner)
|
||||
{
|
||||
m_pOwner->SetChildNode(c_szKey);
|
||||
}
|
||||
CGotoChild(CTextFileLoader * pOwner, DWORD dwIndex) : m_pOwner(pOwner)
|
||||
{
|
||||
m_pOwner->SetChildNode(dwIndex);
|
||||
}
|
||||
~CGotoChild()
|
||||
{
|
||||
m_pOwner->SetParentNode();
|
||||
}
|
||||
|
||||
CTextFileLoader * m_pOwner;
|
||||
};
|
||||
|
||||
public:
|
||||
static void DestroySystem();
|
||||
|
||||
static void SetCacheMode();
|
||||
|
||||
static CTextFileLoader* Cache(const char* c_szFileName);
|
||||
|
||||
public:
|
||||
CTextFileLoader();
|
||||
virtual ~CTextFileLoader();
|
||||
|
||||
void Destroy();
|
||||
|
||||
bool Load(const char * c_szFileName);
|
||||
const char * GetFileName();
|
||||
|
||||
bool IsEmpty();
|
||||
|
||||
void SetTop();
|
||||
DWORD GetChildNodeCount();
|
||||
BOOL SetChildNode(const char * c_szKey);
|
||||
BOOL SetChildNode(const std::string & c_rstrKeyHead, DWORD dwIndex);
|
||||
BOOL SetChildNode(DWORD dwIndex);
|
||||
BOOL SetParentNode();
|
||||
BOOL GetCurrentNodeName(std::string * pstrName);
|
||||
|
||||
BOOL IsToken(const std::string & c_rstrKey);
|
||||
BOOL GetTokenVector(const std::string & c_rstrKey, CTokenVector ** ppTokenVector);
|
||||
BOOL GetTokenBoolean(const std::string & c_rstrKey, BOOL * pData);
|
||||
BOOL GetTokenByte(const std::string & c_rstrKey, BYTE * pData);
|
||||
BOOL GetTokenWord(const std::string & c_rstrKey, WORD * pData);
|
||||
BOOL GetTokenInteger(const std::string & c_rstrKey, int * pData);
|
||||
BOOL GetTokenDoubleWord(const std::string & c_rstrKey, DWORD * pData);
|
||||
BOOL GetTokenFloat(const std::string & c_rstrKey, float * pData);
|
||||
BOOL GetTokenVector2(const std::string & c_rstrKey, D3DXVECTOR2 * pVector2);
|
||||
BOOL GetTokenVector3(const std::string & c_rstrKey, D3DXVECTOR3 * pVector3);
|
||||
BOOL GetTokenVector4(const std::string & c_rstrKey, D3DXVECTOR4 * pVector4);
|
||||
|
||||
BOOL GetTokenPosition(const std::string & c_rstrKey, D3DXVECTOR3 * pVector);
|
||||
BOOL GetTokenQuaternion(const std::string & c_rstrKey, D3DXQUATERNION * pQ);
|
||||
BOOL GetTokenDirection(const std::string & c_rstrKey, D3DVECTOR * pVector);
|
||||
BOOL GetTokenColor(const std::string & c_rstrKey, D3DXCOLOR * pColor);
|
||||
BOOL GetTokenColor(const std::string & c_rstrKey, D3DCOLORVALUE * pColor);
|
||||
BOOL GetTokenString(const std::string & c_rstrKey, std::string * pString);
|
||||
|
||||
protected:
|
||||
void __DestroyGroupNodeVector();
|
||||
|
||||
bool LoadGroup(TGroupNode * pGroupNode);
|
||||
|
||||
protected:
|
||||
std::string m_strFileName;
|
||||
|
||||
char* m_acBufData;
|
||||
DWORD m_dwBufSize;
|
||||
DWORD m_dwBufCapacity;
|
||||
|
||||
DWORD m_dwcurLineIndex;
|
||||
|
||||
CMemoryTextFileLoader m_textFileLoader;
|
||||
|
||||
TGroupNode m_GlobalNode;
|
||||
TGroupNode * m_pcurNode;
|
||||
|
||||
std::vector<SGroupNode*> m_kVct_pkNode;
|
||||
|
||||
protected:
|
||||
static std::map<DWORD, CTextFileLoader*> ms_kMap_dwNameKey_pkTextFileLoader;
|
||||
static bool ms_isCacheMode;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,209 @@
|
||||
#include "StdAfx.h"
|
||||
#include "TextTag.h"
|
||||
|
||||
int GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo)
|
||||
{
|
||||
tagLen = 1;
|
||||
|
||||
if (maxLen < 2 || *src != L'|')
|
||||
return TEXT_TAG_PLAIN;
|
||||
|
||||
const wchar_t * cur = ++src;
|
||||
|
||||
if (*cur == L'c') // color
|
||||
{
|
||||
if (maxLen < 10)
|
||||
return TEXT_TAG_PLAIN;
|
||||
|
||||
tagLen = 10;
|
||||
extraInfo.assign(++cur, 8);
|
||||
return TEXT_TAG_COLOR;
|
||||
}
|
||||
else if (*cur == L'|') // ||는 |로 표시한다.
|
||||
{
|
||||
tagLen = 2;
|
||||
return TEXT_TAG_TAG;
|
||||
}
|
||||
else if (*cur == L'r') // restore color
|
||||
{
|
||||
tagLen = 2;
|
||||
return TEXT_TAG_RESTORE_COLOR;
|
||||
}
|
||||
else if (*cur == L'H') // hyperlink |Hitem:10000:0:0:0:0|h[이름]|h
|
||||
{
|
||||
tagLen = 2;
|
||||
return TEXT_TAG_HYPERLINK_START;
|
||||
}
|
||||
else if (*cur == L'h') // end of hyperlink
|
||||
{
|
||||
tagLen = 2;
|
||||
return TEXT_TAG_HYPERLINK_END;
|
||||
}
|
||||
|
||||
return TEXT_TAG_PLAIN;
|
||||
}
|
||||
|
||||
std::wstring GetTextTagOutputString(const wchar_t * src, int src_len)
|
||||
{
|
||||
int len;
|
||||
std::wstring dst;
|
||||
std::wstring extraInfo;
|
||||
int output_len = 0;
|
||||
int hyperlinkStep = 0;
|
||||
|
||||
for (int i = 0; i < src_len; )
|
||||
{
|
||||
int tag = GetTextTag(&src[i], src_len - i, len, extraInfo);
|
||||
|
||||
if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG)
|
||||
{
|
||||
if (hyperlinkStep == 0)
|
||||
{
|
||||
++output_len;
|
||||
dst += src[i];
|
||||
}
|
||||
}
|
||||
else if (tag == TEXT_TAG_HYPERLINK_START)
|
||||
hyperlinkStep = 1;
|
||||
else if (tag == TEXT_TAG_HYPERLINK_END)
|
||||
hyperlinkStep = 0;
|
||||
|
||||
i += len;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
int GetTextTagInternalPosFromRenderPos(const wchar_t * src, int src_len, int offset)
|
||||
{
|
||||
int len;
|
||||
std::wstring dst;
|
||||
std::wstring extraInfo;
|
||||
int output_len = 0;
|
||||
int hyperlinkStep = 0;
|
||||
bool color_tag = false;
|
||||
int internal_offset = 0;
|
||||
|
||||
for (int i = 0; i < src_len; )
|
||||
{
|
||||
int tag = GetTextTag(&src[i], src_len - i, len, extraInfo);
|
||||
|
||||
if (tag == TEXT_TAG_COLOR)
|
||||
{
|
||||
color_tag = true;
|
||||
internal_offset = i;
|
||||
}
|
||||
else if (tag == TEXT_TAG_RESTORE_COLOR)
|
||||
{
|
||||
color_tag = false;
|
||||
}
|
||||
else if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG)
|
||||
{
|
||||
if (hyperlinkStep == 0)
|
||||
{
|
||||
if (!color_tag)
|
||||
internal_offset = i;
|
||||
|
||||
if (offset <= output_len)
|
||||
return internal_offset;
|
||||
|
||||
++output_len;
|
||||
dst += src[i];
|
||||
}
|
||||
}
|
||||
else if (tag == TEXT_TAG_HYPERLINK_START)
|
||||
hyperlinkStep = 1;
|
||||
else if (tag == TEXT_TAG_HYPERLINK_END)
|
||||
hyperlinkStep = 0;
|
||||
|
||||
i += len;
|
||||
}
|
||||
|
||||
return internal_offset;
|
||||
}
|
||||
|
||||
int GetTextTagOutputLen(const wchar_t * src, int src_len)
|
||||
{
|
||||
int len;
|
||||
std::wstring extraInfo;
|
||||
int output_len = 0;
|
||||
int hyperlinkStep = 0;
|
||||
|
||||
for (int i = 0; i < src_len; )
|
||||
{
|
||||
int tag = GetTextTag(&src[i], src_len - i, len, extraInfo);
|
||||
|
||||
if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG)
|
||||
{
|
||||
if (hyperlinkStep == 0)
|
||||
++output_len;
|
||||
}
|
||||
else if (tag == TEXT_TAG_HYPERLINK_START)
|
||||
hyperlinkStep = 1;
|
||||
else if (tag == TEXT_TAG_HYPERLINK_END)
|
||||
hyperlinkStep = 0;
|
||||
|
||||
i += len;
|
||||
}
|
||||
return output_len;
|
||||
}
|
||||
|
||||
int FindColorTagStartPosition(const wchar_t * src, int src_len)
|
||||
{
|
||||
if (src_len < 2)
|
||||
return 0;
|
||||
|
||||
const wchar_t * cur = src;
|
||||
|
||||
// |r의 경우
|
||||
if (*cur == L'r' && *(cur - 1) == L'|')
|
||||
{
|
||||
int len = src_len;
|
||||
|
||||
// ||r은 무시
|
||||
if (len >= 2 && *(cur - 2) == L'|')
|
||||
return 1;
|
||||
|
||||
cur -= 2;
|
||||
len -= 2;
|
||||
|
||||
// |c까지 찾아서 |위치까지 리턴한다.
|
||||
while (len > 1) // 최소 2자를 검사해야 된다.
|
||||
{
|
||||
if (*cur == L'c' && *(cur - 1) == L'|')
|
||||
return (src - cur) + 1;
|
||||
|
||||
--cur;
|
||||
--len;
|
||||
}
|
||||
return (src_len); // 못찾으면 전부;;
|
||||
}
|
||||
// ||의 경우
|
||||
else if (*cur == L'|' && *(cur - 1) == L'|')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FindColorTagEndPosition(const wchar_t * src, int src_len)
|
||||
{
|
||||
const wchar_t * cur = src;
|
||||
|
||||
if (src_len >= 4 && *cur == L'|' && *(cur + 1) == L'c')
|
||||
{
|
||||
int left = src_len - 2;
|
||||
cur += 2;
|
||||
|
||||
while (left > 1)
|
||||
{
|
||||
if (*cur == L'|' && *(cur + 1) == L'r')
|
||||
return (cur - src) + 1;
|
||||
|
||||
--left;
|
||||
++cur;
|
||||
}
|
||||
}
|
||||
else if (src_len >= 2 && *cur == L'|' && *(cur + 1) == L'|')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once // PORT: 40250 TextTag.h has no include guard; the header gate includes every header twice.
|
||||
enum
|
||||
{
|
||||
TEXT_TAG_PLAIN,
|
||||
TEXT_TAG_TAG, // ||
|
||||
TEXT_TAG_COLOR, // |cffffffff
|
||||
TEXT_TAG_HYPERLINK_START, // |H
|
||||
TEXT_TAG_HYPERLINK_END, // |h ex) |Hitem:1234:1:1:1|h
|
||||
TEXT_TAG_RESTORE_COLOR,
|
||||
};
|
||||
|
||||
extern int GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo);
|
||||
extern std::wstring GetTextTagOutputString(const wchar_t * src, int src_len);
|
||||
extern int GetTextTagOutputLen(const wchar_t * src, int len);
|
||||
extern int FindColorTagEndPosition(const wchar_t * src, int src_len);
|
||||
extern int FindColorTagStartPosition(const wchar_t * src, int src_len);
|
||||
extern int GetTextTagInternalPosFromRenderPos(const wchar_t * src, int src_len, int offset);
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef __INC_ETERLIB_THREAD_H__
|
||||
#define __INC_ETERLIB_THREAD_H__
|
||||
|
||||
class CThread
|
||||
{
|
||||
public:
|
||||
CThread();
|
||||
int Create(void * arg);
|
||||
|
||||
protected:
|
||||
static UINT CALLBACK EntryPoint(void * pThis);
|
||||
|
||||
virtual UINT Setup() = 0; // Execute이 불려지기 전에 불려진다.
|
||||
virtual UINT Execute(void * arg) = 0; // 실제 쓰레드가 하는 일이 들어가는 곳
|
||||
|
||||
UINT Run(void * arg);
|
||||
|
||||
void * Arg() const { return m_pArg; }
|
||||
void Arg(void * arg) { m_pArg = arg; }
|
||||
|
||||
HANDLE m_hThread;
|
||||
|
||||
private:
|
||||
void * m_pArg;
|
||||
unsigned m_uThreadID;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,237 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "TextFileLoader.h"
|
||||
|
||||
void PrintfTabs(FILE * File, int iTabCount, const char * c_szString, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, c_szString);
|
||||
|
||||
static char szBuf[1024];
|
||||
_vsnprintf(szBuf, sizeof(szBuf), c_szString, args);
|
||||
va_end(args);
|
||||
|
||||
for (int i = 0; i < iTabCount; ++i)
|
||||
fprintf(File, " ");
|
||||
|
||||
fprintf(File, szBuf);
|
||||
}
|
||||
|
||||
bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap)
|
||||
{
|
||||
LPCVOID pMotionData;
|
||||
CMappedFile File;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pMotionData))
|
||||
return false;
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
CTokenVector stTokenVector;
|
||||
|
||||
textFileLoader.Bind(File.Size(), pMotionData);
|
||||
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
if (2 != stTokenVector.size())
|
||||
return false;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
stl_lowers(stTokenVector[1]);
|
||||
|
||||
rstTokenMap[stTokenVector[0]] = stTokenVector[1];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap)
|
||||
{
|
||||
LPCVOID pModelData;
|
||||
CMappedFile File;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData))
|
||||
return false;
|
||||
|
||||
DWORD i;
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
CTokenVector stTokenVector;
|
||||
|
||||
textFileLoader.Bind(File.Size(), pModelData);
|
||||
|
||||
for (i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
|
||||
// Start or End
|
||||
if (0 == stTokenVector[0].compare("start"))
|
||||
{
|
||||
CTokenVector stSubTokenVector;
|
||||
|
||||
stl_lowers(stTokenVector[1]);
|
||||
std::string key = stTokenVector[1];
|
||||
stTokenVector.clear();
|
||||
|
||||
for (i=i+1; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stSubTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stSubTokenVector[0]);
|
||||
|
||||
if (0 == stSubTokenVector[0].compare("end"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (DWORD j = 0; j < stSubTokenVector.size(); ++j)
|
||||
{
|
||||
stTokenVector.push_back(stSubTokenVector[j]);
|
||||
}
|
||||
}
|
||||
|
||||
rstTokenVectorMap.insert(CTokenVectorMap::value_type(key, stTokenVector));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string key = stTokenVector[0];
|
||||
stTokenVector.erase(stTokenVector.begin());
|
||||
rstTokenVectorMap.insert(CTokenVectorMap::value_type(key, stTokenVector));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 TokenToVector(CTokenVector & rVector)
|
||||
{
|
||||
if (3 != rVector.size())
|
||||
{
|
||||
assert(!"Size of token vector which will be converted to vector is not 3");
|
||||
return D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
return D3DXVECTOR3(atof(rVector[0].c_str()),
|
||||
atof(rVector[1].c_str()),
|
||||
atof(rVector[2].c_str()));
|
||||
}
|
||||
|
||||
D3DXCOLOR TokenToColor(CTokenVector & rVector)
|
||||
{
|
||||
if (4 != rVector.size())
|
||||
{
|
||||
assert(!"Size of token vector which will be converted to color is not 4");
|
||||
return D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
return D3DXCOLOR(atof(rVector[0].c_str()),
|
||||
atof(rVector[1].c_str()),
|
||||
atof(rVector[2].c_str()),
|
||||
atof(rVector[3].c_str()));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// PORT: lines 142-296 of 40250 EterLib/Util.cpp (default code page and font face, with the Win32
|
||||
// EnumFontFamExProc callback) live in platform/EterLib/Util.cpp, which owns the font backend.
|
||||
|
||||
|
||||
int __base64_get( const int c )
|
||||
{
|
||||
if( 'A' <= c && c <= 'Z' )
|
||||
return c-'A';
|
||||
if( 'a' <= c && c <= 'z' )
|
||||
return c - 'a' + 26;
|
||||
if( '0' <= c && c <= '9' )
|
||||
return c - '0' + 52;
|
||||
if( c == '+' )
|
||||
return 62;
|
||||
if( c == '/' )
|
||||
return 63;
|
||||
if( c == '=' ) // end of line
|
||||
return -1;
|
||||
return -2; // non value;
|
||||
}
|
||||
|
||||
void __strcat1(char * str,int i)
|
||||
{
|
||||
char result[2];
|
||||
result[0] = i;
|
||||
result[1] = NULL;
|
||||
strcat(str,result);
|
||||
}
|
||||
|
||||
void base64_decode(const char * str,char * resultStr)
|
||||
{
|
||||
int nCount=0, i=0, r, result;
|
||||
int length = strlen(str);
|
||||
char szDest[5]="";
|
||||
|
||||
strcpy(resultStr,"");
|
||||
while(nCount < length)
|
||||
{
|
||||
i=0;
|
||||
strcpy(szDest, "");
|
||||
while(nCount<length && i<4) // 4개의 바이트를 얻는다.
|
||||
{
|
||||
r = str[nCount++];
|
||||
result = __base64_get(r);
|
||||
if(result!=-2)
|
||||
{
|
||||
if(result!=-1)
|
||||
szDest[i++] = result;
|
||||
else szDest[i++] = '@'; // It's end (64번은 디코딩시 사용되지 않기 때문)
|
||||
}
|
||||
}
|
||||
|
||||
if(i==4) // 4개의 소스를 모두 얻어냈다. 디코드 시작
|
||||
{
|
||||
if( nCount+3 >= length ) // 데이터의 끝에 도달했다.
|
||||
{
|
||||
if( szDest[1] == '@' )
|
||||
{
|
||||
__strcat1(resultStr,(szDest[0]<<2));
|
||||
break;
|
||||
}// exit while loop
|
||||
else
|
||||
__strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte
|
||||
if( szDest[2] == '@' )
|
||||
{
|
||||
__strcat1(resultStr,(szDest[1]<<4));
|
||||
break;
|
||||
}
|
||||
else
|
||||
__strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte
|
||||
if( szDest[3] == '@' )
|
||||
{
|
||||
__strcat1(resultStr,(szDest[2]<<6));
|
||||
break;
|
||||
}
|
||||
else
|
||||
__strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte
|
||||
}
|
||||
else
|
||||
{
|
||||
__strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte
|
||||
__strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte
|
||||
__strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte
|
||||
}
|
||||
}
|
||||
|
||||
}// end of while
|
||||
|
||||
for (i = 0; i < strlen(resultStr); i++)
|
||||
{
|
||||
char c = resultStr[i];
|
||||
int xx = i + 5;
|
||||
resultStr[i] = char(c ^ xx);
|
||||
}
|
||||
// E
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../EterBase/FileLoader.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <d3dx8.h>
|
||||
|
||||
template<typename T>
|
||||
class CTransitor
|
||||
{
|
||||
public:
|
||||
CTransitor() {}
|
||||
~CTransitor() {}
|
||||
|
||||
void SetActive(BOOL bActive = TRUE)
|
||||
{
|
||||
m_bActivated = bActive;
|
||||
}
|
||||
|
||||
BOOL isActive()
|
||||
{
|
||||
return m_bActivated;
|
||||
}
|
||||
|
||||
BOOL isActiveTime(float fcurTime)
|
||||
{
|
||||
if (fcurTime >= m_fEndTime)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD GetID()
|
||||
{
|
||||
return m_dwID;
|
||||
}
|
||||
|
||||
void SetID(DWORD dwID)
|
||||
{
|
||||
m_dwID = dwID;
|
||||
}
|
||||
|
||||
void SetSourceValue(const T & c_rSourceValue)
|
||||
{
|
||||
m_SourceValue = c_rSourceValue;
|
||||
}
|
||||
|
||||
void SetTransition(const T & c_rSourceValue, const T & c_rTargetValue, float fStartTime, float fBlendTime)
|
||||
{
|
||||
m_SourceValue = c_rSourceValue;
|
||||
m_TargetValue = c_rTargetValue;
|
||||
m_fStartTime = fStartTime;
|
||||
m_fEndTime = fStartTime + fBlendTime;
|
||||
}
|
||||
|
||||
BOOL GetValue(float fcurTime, T * pValue)
|
||||
{
|
||||
if (fcurTime <= m_fStartTime)
|
||||
return FALSE;
|
||||
|
||||
float fPercentage = (fcurTime - m_fStartTime) / (m_fEndTime - m_fStartTime);
|
||||
*pValue = m_SourceValue + (m_TargetValue - m_SourceValue) * fPercentage;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
protected:
|
||||
DWORD m_dwID; // Public Transitor ID
|
||||
|
||||
BOOL m_bActivated; // Have been started to blend?
|
||||
float m_fStartTime;
|
||||
float m_fEndTime;
|
||||
|
||||
T m_SourceValue;
|
||||
T m_TargetValue;
|
||||
};
|
||||
|
||||
typedef CTransitor<float> TTransitorFloat;
|
||||
typedef CTransitor<D3DXVECTOR3> TTransitorVector3;
|
||||
typedef CTransitor<D3DXCOLOR> TTransitorColor;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrintfTabs(FILE * File, int iTabCount, const char * c_szString, ...);
|
||||
|
||||
|
||||
//typedef CTokenVector TTokenVector;
|
||||
|
||||
extern bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap);
|
||||
extern bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap);
|
||||
|
||||
extern D3DXVECTOR3 TokenToVector(CTokenVector & rVector);
|
||||
extern D3DXCOLOR TokenToColor(CTokenVector & rVector);
|
||||
|
||||
#define GOTO_CHILD_NODE(TextFileLoader, Index) CTextFileLoader::CGotoChild Child(TextFileLoader, Index);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int CALLBACK EnumFontFamExProc(CONST LOGFONT* plogFont, CONST TEXTMETRIC* textMetric, DWORD dwWord, LPARAM lParam);
|
||||
extern int GetCharsetFromCodePage(WORD codePage);
|
||||
extern const char* GetFontFaceFromCodePageNT(WORD codePage);
|
||||
extern const char* GetFontFaceFromCodePage9x(WORD codePage);
|
||||
extern DWORD GetDefaultCodePage();
|
||||
extern const char * GetDefaultFontFace();
|
||||
extern const char* GetFontFaceFromCodePage(WORD codePage);
|
||||
extern void SetDefaultFontFace(const char* fontFace);
|
||||
extern bool SetDefaultCodePage(DWORD codePage);
|
||||
extern void base64_decode(const char * str,char * resultStr);
|
||||
|
||||
extern DWORD GetMaxTextureWidth();
|
||||
extern DWORD GetMaxTextureHeight();
|
||||
@@ -0,0 +1,849 @@
|
||||
/**************************************************************************************
|
||||
| File: lineintersect_utils.cpp
|
||||
| Purpose: Implementation of line segment intersection utility functions
|
||||
| Book Title: Game Programming Gems II
|
||||
| Chapter Title: Fast, Robust Intersection of 3D Line Segments
|
||||
| Author: Graham Rhodes
|
||||
| Revisions: 05-Apr-2001 - GSR. Original.
|
||||
**************************************************************************************/
|
||||
#include "StdAfx.h"
|
||||
#include <math.h>
|
||||
#include "lineintersect_utils.h"
|
||||
#include <assert.h>
|
||||
|
||||
// uncomment the following line to have the code check intermediate results
|
||||
//#define CHECK_ANSWERS
|
||||
|
||||
// uncomment the following line to use Cramer's rule instead of Gaussian elimination
|
||||
//#define USE_CRAMERS_RULE
|
||||
|
||||
#define FMAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define FMIN(a,b) ((a) > (b) ? (b) : (a))
|
||||
#define FABS(a) ((a) < 0.0f ? -(a) : (a))
|
||||
#define OUT_OF_RANGE(a) ((a) < 0.0f || (a) > 1.f)
|
||||
|
||||
#define MY_EPSILON 0.1f
|
||||
|
||||
__forceinline void FindNearestPointOnLineSegment(const D3DXVECTOR3 & A1,
|
||||
const D3DXVECTOR3 & L,
|
||||
const D3DXVECTOR3 & B,
|
||||
D3DXVECTOR3 & Nearest,
|
||||
float ¶meter)
|
||||
{
|
||||
// Line/Segment is degenerate --- special case #1
|
||||
float D = D3DXVec3LengthSq(&L);
|
||||
if (D < MY_EPSILON*MY_EPSILON)
|
||||
{
|
||||
Nearest = A1;
|
||||
return;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 AB = B-A1;
|
||||
|
||||
// parameter is computed from Equation (20).
|
||||
parameter = (D3DXVec3Dot(&AB,&L)) / D;
|
||||
|
||||
//if (false == infinite_line)
|
||||
parameter = FMAX(0.0f, FMIN(1.0f, parameter));
|
||||
|
||||
Nearest = A1 + parameter * L;
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
||||
| Method: FindNearestPointOfParallelLineSegments
|
||||
|
|
||||
| Purpose: Given two lines (segments) that are known to be parallel, find
|
||||
| a representative point on each that is nearest to the other. If
|
||||
| the lines are considered to be finite then it is possible that there
|
||||
| is one true point on each line that is nearest to the other. This
|
||||
| code properly handles this case.
|
||||
|
|
||||
| This is the most difficult line intersection case to handle, since
|
||||
| there is potentially a family, or locus of points on each line/segment
|
||||
| that are nearest to the other.
|
||||
| Parameters: Input:
|
||||
| ------
|
||||
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
|
||||
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
|
||||
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|
||||
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
|
||||
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
|
||||
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|
||||
| infinite_lines - set to true if lines are to be treated as infinite
|
||||
| epsilon_squared - tolerance value to be used to check for degenerate
|
||||
| and parallel lines, and to check for true intersection.
|
||||
|
|
||||
| Output:
|
||||
| -------
|
||||
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
|
||||
| PointOnSegAy, to segment B. This corresponds to point C in the text.
|
||||
| PointOnSegAz
|
||||
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
|
||||
| PointOnSegBy, to segment A. This corresponds to point D in the text.
|
||||
| PointOnSegBz
|
||||
|
||||
**************************************************************************/
|
||||
__forceinline void FindNearestPointOfParallelLineSegments(const D3DXVECTOR3 & A1,
|
||||
const D3DXVECTOR3 & A2,
|
||||
const D3DXVECTOR3 & La,
|
||||
const D3DXVECTOR3 & B1,
|
||||
const D3DXVECTOR3 & B2,
|
||||
const D3DXVECTOR3 & Lb,
|
||||
//bool infinite_lines, float epsilon_squared,
|
||||
D3DXVECTOR3 & OutA,
|
||||
D3DXVECTOR3 & OutB)
|
||||
{
|
||||
float s[2], temp;
|
||||
FindNearestPointOnLineSegment(A1, La, B1, OutA, s[0]);
|
||||
/*if (true == infinite_lines)
|
||||
{
|
||||
PointOnSegBx = B1x;
|
||||
PointOnSegBy = B1y;
|
||||
PointOnSegBz = B1z;
|
||||
}
|
||||
else*/
|
||||
{
|
||||
//float tp[3];
|
||||
D3DXVECTOR3 tp;
|
||||
FindNearestPointOnLineSegment(A1, La, B2,
|
||||
tp, s[1]);
|
||||
if (s[0] < 0.f && s[1] < 0.f)
|
||||
{
|
||||
OutA = A1;
|
||||
if (s[0] < s[1])
|
||||
{
|
||||
OutB =B2;
|
||||
}
|
||||
else
|
||||
{
|
||||
OutB = B1;
|
||||
}
|
||||
}
|
||||
else if (s[0] > 1.f && s[1] > 1.f)
|
||||
{
|
||||
OutA = A2;
|
||||
if (s[0] < s[1])
|
||||
{
|
||||
OutB = B1;
|
||||
}
|
||||
else
|
||||
{
|
||||
OutB = B2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
|
||||
OutA = A1 + temp * La;
|
||||
FindNearestPointOnLineSegment(B1, Lb,
|
||||
OutA, OutB, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
||||
| Method: AdjustNearestPoints
|
||||
|
|
||||
| Purpose: Given nearest point information for two infinite lines, adjust
|
||||
| to model finite line segments.
|
||||
|
|
||||
| Parameters: Input:
|
||||
| ------
|
||||
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
|
||||
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|
||||
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
|
||||
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|
||||
| epsilon_squared - tolerance value to be used to check for degenerate
|
||||
| and parallel lines, and to check for true intersection.
|
||||
| s - parameter representing nearest point on infinite line A
|
||||
| t - parameter representing nearest point on infinite line B
|
||||
|
|
||||
| Output:
|
||||
| -------
|
||||
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
|
||||
| PointOnSegAy, to segment B. This corresponds to point C in the text.
|
||||
| PointOnSegAz
|
||||
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
|
||||
| PointOnSegBy, to segment A. This corresponds to point D in the text.
|
||||
| PointOnSegBz
|
||||
**************************************************************************/
|
||||
__forceinline void AdjustNearestPoints(const D3DXVECTOR3 & A1,
|
||||
const D3DXVECTOR3 & La,
|
||||
const D3DXVECTOR3 & B1,
|
||||
const D3DXVECTOR3 & Lb,
|
||||
float s, float t,
|
||||
D3DXVECTOR3 & OutA,
|
||||
D3DXVECTOR3 & OutB)
|
||||
{
|
||||
// handle the case where both parameter s and t are out of range
|
||||
if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
|
||||
{
|
||||
s = FMAX(0.0f, FMIN(1.0f, s));
|
||||
OutA = A1 + s*La;
|
||||
FindNearestPointOnLineSegment(B1, Lb,
|
||||
OutA,
|
||||
OutB, t);
|
||||
if (OUT_OF_RANGE(t))
|
||||
{
|
||||
t = FMAX(0.0f, FMIN(1.0f, t));
|
||||
OutB = B1 + t*Lb;
|
||||
FindNearestPointOnLineSegment(A1, La, OutB,
|
||||
OutA, s);
|
||||
FindNearestPointOnLineSegment(B1, Lb, OutA,
|
||||
OutB, t);
|
||||
}
|
||||
}
|
||||
// otherwise, handle the case where the parameter for only one segment is
|
||||
// out of range
|
||||
else if (OUT_OF_RANGE(s))
|
||||
{
|
||||
s = FMAX(0.0f, FMIN(1.0f, s));
|
||||
OutA = A1 + s*La;
|
||||
FindNearestPointOnLineSegment(B1, Lb,
|
||||
OutA,
|
||||
OutB, t);
|
||||
}
|
||||
else if (OUT_OF_RANGE(t))
|
||||
{
|
||||
t = FMAX(0.0f, FMIN(1.0f, t));
|
||||
OutB = B1 + t*Lb;
|
||||
FindNearestPointOnLineSegment(A1, La, OutB,
|
||||
OutA, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void IntersectLineSegments(const D3DXVECTOR3 & A1,
|
||||
const D3DXVECTOR3 & A2,
|
||||
const D3DXVECTOR3 & B1,
|
||||
const D3DXVECTOR3 & B2,
|
||||
//bool infinite_lines, /*float epsilon,*/
|
||||
D3DXVECTOR3 & OutA,
|
||||
D3DXVECTOR3 & OutB)
|
||||
{
|
||||
float temp = 0.f;
|
||||
const float epsilon = MY_EPSILON;
|
||||
const float epsilon_squared = MY_EPSILON*MY_EPSILON;
|
||||
|
||||
// Compute parameters from Equations (1) and (2) in the text
|
||||
D3DXVECTOR3 La = A2-A1;
|
||||
D3DXVECTOR3 Lb = B2-B1;
|
||||
// From Equation (15)
|
||||
float L11 = D3DXVec3LengthSq(&La);
|
||||
float L22 = D3DXVec3LengthSq(&Lb);
|
||||
|
||||
// Line/Segment A is degenerate ---- Special Case #1
|
||||
if (L11 < epsilon_squared)
|
||||
{
|
||||
OutA = A1;
|
||||
FindNearestPointOnLineSegment(B1, Lb, A1,
|
||||
OutB, temp);
|
||||
}
|
||||
// Line/Segment B is degenerate ---- Special Case #1
|
||||
else if (L22 < epsilon_squared)
|
||||
{
|
||||
OutB = B1;
|
||||
FindNearestPointOnLineSegment(A1, La, B1,
|
||||
OutA, temp);
|
||||
}
|
||||
// Neither line/segment is degenerate
|
||||
else
|
||||
{
|
||||
// Compute more parameters from Equation (3) in the text.
|
||||
D3DXVECTOR3 AB = B1 - A1;
|
||||
|
||||
// and from Equation (15).
|
||||
float L12 = -D3DXVec3Dot(&La, &Lb);
|
||||
|
||||
float DetL = L11 * L22 - L12 * L12;
|
||||
// Lines/Segments A and B are parallel ---- special case #2.
|
||||
if (FABS(DetL) < epsilon)
|
||||
{
|
||||
FindNearestPointOfParallelLineSegments(A1, A2,
|
||||
La,
|
||||
B1, B2,
|
||||
Lb,
|
||||
OutA, OutB);
|
||||
}
|
||||
// The general case
|
||||
else
|
||||
{
|
||||
// from Equation (15)
|
||||
float ra = D3DXVec3Dot(&La, &AB);//Lax * ABx + Lay * ABy + Laz * ABz;
|
||||
float rb = D3DXVec3Dot(&Lb, &AB);//-Lbx * ABx - Lby * ABy - Lbz * ABz;
|
||||
|
||||
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
|
||||
|
||||
#ifdef USE_CRAMERS_RULE
|
||||
float s = (L22 * ra - rb * L12)/DetL;
|
||||
#else
|
||||
float s = (ra-L12*t)/L11; // Equation (13)
|
||||
#endif // USE_CRAMERS_RULE
|
||||
|
||||
#ifdef CHECK_ANSWERS
|
||||
float check_ra = s*L11 + t*L12;
|
||||
float check_rb = s*L12 + t*L22;
|
||||
assert(FABS(check_ra-ra) < epsilon);
|
||||
assert(FABS(check_rb-rb) < epsilon);
|
||||
#endif // CHECK_ANSWERS
|
||||
|
||||
// if we are dealing with infinite lines or if parameters s and t both
|
||||
// lie in the range [0,1] then just compute the points using Equations
|
||||
// (1) and (2) from the text.
|
||||
OutA = (A1 + s * La);
|
||||
OutB = (B1 + t * Lb);
|
||||
// otherwise, at least one of s and t is outside of [0,1] and we have to
|
||||
// handle this case.
|
||||
if ((OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
|
||||
{
|
||||
AdjustNearestPoints(A1,La,B1,Lb,
|
||||
s, t,
|
||||
OutA,
|
||||
OutB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
|
||||
const float A2x, const float A2y, const float A2z,
|
||||
const float B1x, const float B1y, const float B1z,
|
||||
const float B2x, const float B2y, const float B2z,
|
||||
bool infinite_lines, float epsilon, float &PointOnSegAx,
|
||||
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
|
||||
float &PointOnSegBy, float &PointOnSegBz)
|
||||
{
|
||||
float temp = 0.f;
|
||||
float epsilon_squared = epsilon * epsilon;
|
||||
|
||||
// Compute parameters from Equations (1) and (2) in the text
|
||||
float Lax = A2x - A1x;
|
||||
float Lay = A2y - A1y;
|
||||
float Laz = A2z - A1z;
|
||||
float Lbx = B2x - B1x;
|
||||
float Lby = B2y - B1y;
|
||||
float Lbz = B2z - B1z;
|
||||
// From Equation (15)
|
||||
float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz);
|
||||
float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz);
|
||||
|
||||
// Line/Segment A is degenerate ---- Special Case #1
|
||||
if (L11 < epsilon_squared)
|
||||
{
|
||||
PointOnSegAx = A1x;
|
||||
PointOnSegAy = A1y;
|
||||
PointOnSegAz = A1z;
|
||||
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z,
|
||||
infinite_lines, epsilon, PointOnSegBx, PointOnSegBy,
|
||||
PointOnSegBz, temp);
|
||||
}
|
||||
// Line/Segment B is degenerate ---- Special Case #1
|
||||
else if (L22 < epsilon_squared)
|
||||
{
|
||||
PointOnSegBx = B1x;
|
||||
PointOnSegBy = B1y;
|
||||
PointOnSegBz = B1z;
|
||||
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
|
||||
infinite_lines, epsilon, PointOnSegAx, PointOnSegAy,
|
||||
PointOnSegAz, temp);
|
||||
}
|
||||
// Neither line/segment is degenerate
|
||||
else
|
||||
{
|
||||
// Compute more parameters from Equation (3) in the text.
|
||||
float ABx = B1x - A1x;
|
||||
float ABy = B1y - A1y;
|
||||
float ABz = B1z - A1z;
|
||||
|
||||
// and from Equation (15).
|
||||
float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz);
|
||||
|
||||
float DetL = L11 * L22 - L12 * L12;
|
||||
// Lines/Segments A and B are parallel ---- special case #2.
|
||||
if (FABS(DetL) < epsilon)
|
||||
{
|
||||
FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z,
|
||||
Lax, Lay, Laz,
|
||||
B1x, B1y, B1z, B2x, B2y, B2z,
|
||||
Lbx, Lby, Lbz,
|
||||
infinite_lines, epsilon,
|
||||
PointOnSegAx, PointOnSegAy, PointOnSegAz,
|
||||
PointOnSegBx, PointOnSegBy, PointOnSegBz);
|
||||
}
|
||||
// The general case
|
||||
else
|
||||
{
|
||||
// from Equation (15)
|
||||
float ra = Lax * ABx + Lay * ABy + Laz * ABz;
|
||||
float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz;
|
||||
|
||||
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
|
||||
|
||||
#ifdef USE_CRAMERS_RULE
|
||||
float s = (L22 * ra - rb * L12)/DetL;
|
||||
#else
|
||||
float s = (ra-L12*t)/L11; // Equation (13)
|
||||
#endif // USE_CRAMERS_RULE
|
||||
|
||||
#ifdef CHECK_ANSWERS
|
||||
float check_ra = s*L11 + t*L12;
|
||||
float check_rb = s*L12 + t*L22;
|
||||
assert(FABS(check_ra-ra) < epsilon);
|
||||
assert(FABS(check_rb-rb) < epsilon);
|
||||
#endif // CHECK_ANSWERS
|
||||
|
||||
// if we are dealing with infinite lines or if parameters s and t both
|
||||
// lie in the range [0,1] then just compute the points using Equations
|
||||
// (1) and (2) from the text.
|
||||
PointOnSegAx = (A1x + s * Lax);
|
||||
PointOnSegAy = (A1y + s * Lay);
|
||||
PointOnSegAz = (A1z + s * Laz);
|
||||
PointOnSegBx = (B1x + t * Lbx);
|
||||
PointOnSegBy = (B1y + t * Lby);
|
||||
PointOnSegBz = (B1z + t * Lbz);
|
||||
// otherwise, at least one of s and t is outside of [0,1] and we have to
|
||||
// handle this case.
|
||||
if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
|
||||
{
|
||||
AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz,
|
||||
B1x, B1y, B1z, Lbx, Lby, Lbz,
|
||||
epsilon, s, t,
|
||||
PointOnSegAx, PointOnSegAy, PointOnSegAz,
|
||||
PointOnSegBx, PointOnSegBy, PointOnSegBz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// pragma to get rid of math.h inline function removal warnings.
|
||||
#pragma warning(disable:4514)
|
||||
|
||||
/**************************************************************************
|
||||
|
|
||||
| Method: IntersectLineSegments
|
||||
|
|
||||
| Purpose: Find the nearest point between two finite length line segments
|
||||
| or two infinite lines in 3-dimensional space. The function calculates
|
||||
| the point on each line/line segment that is closest to the other
|
||||
| line/line segment, the midpoint between the nearest points, and
|
||||
| the vector between these two points. If the two nearest points
|
||||
| are close within a tolerance, a flag is set indicating the lines
|
||||
| have a "true" intersection.
|
||||
|
|
||||
| Parameters: Input:
|
||||
| ------
|
||||
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
|
||||
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
|
||||
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
|
||||
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
|
||||
| infinite_lines - set to true if lines are to be treated as infinite
|
||||
| epsilon - tolerance value to be used to check for degenerate
|
||||
| and parallel lines, and to check for true intersection.
|
||||
|
|
||||
| Output:
|
||||
| -------
|
||||
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
|
||||
| PointOnSegAy, to segment B. This corresponds to point C in the text.
|
||||
| PointOnSegAz
|
||||
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
|
||||
| PointOnSegBy, to segment A. This corresponds to point D in the text.
|
||||
| PointOnSegBz
|
||||
| NearestPointX, - Midpoint between the two nearest points. This can be
|
||||
| NearestPointY, treated as *the* intersection point if nearest points
|
||||
| NearestPointZ are sufficiently close. This corresponds to point P
|
||||
| in the text.
|
||||
| NearestVectorX, - Vector between the nearest point on A to the nearest
|
||||
| point on segment B. This vector is normal to both
|
||||
| lines if the lines are infinite, but is not guaranteed
|
||||
| to be normal to both lines if both lines are finite
|
||||
| length.
|
||||
| true_intersection - true if the nearest points are close within a small
|
||||
| tolerance.
|
||||
**************************************************************************/
|
||||
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
|
||||
const float A2x, const float A2y, const float A2z,
|
||||
const float B1x, const float B1y, const float B1z,
|
||||
const float B2x, const float B2y, const float B2z,
|
||||
bool infinite_lines, float epsilon, float &PointOnSegAx,
|
||||
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
|
||||
float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX,
|
||||
float &NearestPointY, float &NearestPointZ, float &NearestVectorX,
|
||||
float &NearestVectorY, float &NearestVectorZ, bool &true_intersection)
|
||||
{
|
||||
float temp = 0.f;
|
||||
float epsilon_squared = epsilon * epsilon;
|
||||
|
||||
// Compute parameters from Equations (1) and (2) in the text
|
||||
float Lax = A2x - A1x;
|
||||
float Lay = A2y - A1y;
|
||||
float Laz = A2z - A1z;
|
||||
float Lbx = B2x - B1x;
|
||||
float Lby = B2y - B1y;
|
||||
float Lbz = B2z - B1z;
|
||||
// From Equation (15)
|
||||
float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz);
|
||||
float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz);
|
||||
|
||||
// Line/Segment A is degenerate ---- Special Case #1
|
||||
if (L11 < epsilon_squared)
|
||||
{
|
||||
PointOnSegAx = A1x;
|
||||
PointOnSegAy = A1y;
|
||||
PointOnSegAz = A1z;
|
||||
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z,
|
||||
infinite_lines, epsilon, PointOnSegBx, PointOnSegBy,
|
||||
PointOnSegBz, temp);
|
||||
}
|
||||
// Line/Segment B is degenerate ---- Special Case #1
|
||||
else if (L22 < epsilon_squared)
|
||||
{
|
||||
PointOnSegBx = B1x;
|
||||
PointOnSegBy = B1y;
|
||||
PointOnSegBz = B1z;
|
||||
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
|
||||
infinite_lines, epsilon, PointOnSegAx, PointOnSegAy,
|
||||
PointOnSegAz, temp);
|
||||
}
|
||||
// Neither line/segment is degenerate
|
||||
else
|
||||
{
|
||||
// Compute more parameters from Equation (3) in the text.
|
||||
float ABx = B1x - A1x;
|
||||
float ABy = B1y - A1y;
|
||||
float ABz = B1z - A1z;
|
||||
|
||||
// and from Equation (15).
|
||||
float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz);
|
||||
|
||||
float DetL = L11 * L22 - L12 * L12;
|
||||
// Lines/Segments A and B are parallel ---- special case #2.
|
||||
if (FABS(DetL) < epsilon)
|
||||
{
|
||||
FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z,
|
||||
Lax, Lay, Laz,
|
||||
B1x, B1y, B1z, B2x, B2y, B2z,
|
||||
Lbx, Lby, Lbz,
|
||||
infinite_lines, epsilon,
|
||||
PointOnSegAx, PointOnSegAy, PointOnSegAz,
|
||||
PointOnSegBx, PointOnSegBy, PointOnSegBz);
|
||||
}
|
||||
// The general case
|
||||
else
|
||||
{
|
||||
// from Equation (15)
|
||||
float ra = Lax * ABx + Lay * ABy + Laz * ABz;
|
||||
float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz;
|
||||
|
||||
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
|
||||
|
||||
#ifdef USE_CRAMERS_RULE
|
||||
float s = (L22 * ra - rb * L12)/DetL;
|
||||
#else
|
||||
float s = (ra-L12*t)/L11; // Equation (13)
|
||||
#endif // USE_CRAMERS_RULE
|
||||
|
||||
#ifdef CHECK_ANSWERS
|
||||
float check_ra = s*L11 + t*L12;
|
||||
float check_rb = s*L12 + t*L22;
|
||||
assert(FABS(check_ra-ra) < epsilon);
|
||||
assert(FABS(check_rb-rb) < epsilon);
|
||||
#endif // CHECK_ANSWERS
|
||||
|
||||
// if we are dealing with infinite lines or if parameters s and t both
|
||||
// lie in the range [0,1] then just compute the points using Equations
|
||||
// (1) and (2) from the text.
|
||||
PointOnSegAx = (A1x + s * Lax);
|
||||
PointOnSegAy = (A1y + s * Lay);
|
||||
PointOnSegAz = (A1z + s * Laz);
|
||||
PointOnSegBx = (B1x + t * Lbx);
|
||||
PointOnSegBy = (B1y + t * Lby);
|
||||
PointOnSegBz = (B1z + t * Lbz);
|
||||
// otherwise, at least one of s and t is outside of [0,1] and we have to
|
||||
// handle this case.
|
||||
if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
|
||||
{
|
||||
AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz,
|
||||
B1x, B1y, B1z, Lbx, Lby, Lbz,
|
||||
epsilon, s, t,
|
||||
PointOnSegAx, PointOnSegAy, PointOnSegAz,
|
||||
PointOnSegBx, PointOnSegBy, PointOnSegBz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NearestPointX = 0.5f * (PointOnSegAx + PointOnSegBx);
|
||||
NearestPointY = 0.5f * (PointOnSegAy + PointOnSegBy);
|
||||
NearestPointZ = 0.5f * (PointOnSegAz + PointOnSegBz);
|
||||
|
||||
NearestVectorX = PointOnSegBx - PointOnSegAx;
|
||||
NearestVectorY = PointOnSegBy - PointOnSegAy;
|
||||
NearestVectorZ = PointOnSegBz - PointOnSegAz;
|
||||
|
||||
// optional check to indicate if the lines truly intersect
|
||||
true_intersection = (FABS(NearestVectorX) +
|
||||
FABS(NearestVectorY) +
|
||||
FABS(NearestVectorZ)) < epsilon ? true : false;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
||||
| Method: FindNearestPointOnLineSegment
|
||||
|
|
||||
| Purpose: Given a line (segment) and a point in 3-dimensional space,
|
||||
| find the point on the line (segment) that is closest to the
|
||||
| point.
|
||||
|
|
||||
| Parameters: Input:
|
||||
| ------
|
||||
| A1x, A1y, A1z - Coordinates of first defining point of the line/segment
|
||||
| Lx, Ly, Lz - Vector from (A1x, A1y, A1z) to the second defining point
|
||||
| of the line/segment.
|
||||
| Bx, By, Bz - Coordinates of the point
|
||||
| infinite_lines - set to true if lines are to be treated as infinite
|
||||
| epsilon_squared - tolerance value to be used to check for degenerate
|
||||
| and parallel lines, and to check for true intersection.
|
||||
|
|
||||
| Output:
|
||||
| -------
|
||||
| NearestPointX, - Point on line/segment that is closest to (Bx, By, Bz)
|
||||
| NearestPointY,
|
||||
| NearestPointZ
|
||||
| parameter - Parametric coordinate of the nearest point along the
|
||||
| line/segment. parameter = 0 at (A1x, A1y, A1z) and
|
||||
| parameter = 1 at the second defining point of the line/
|
||||
| segmetn
|
||||
**************************************************************************/
|
||||
void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z,
|
||||
const float Lx, const float Ly, const float Lz,
|
||||
const float Bx, const float By, const float Bz,
|
||||
bool infinite_line, float epsilon_squared, float &NearestPointX,
|
||||
float &NearestPointY, float &NearestPointZ,
|
||||
float ¶meter)
|
||||
{
|
||||
// Line/Segment is degenerate --- special case #1
|
||||
float D = Lx * Lx + Ly * Ly + Lz * Lz;
|
||||
if (D < epsilon_squared)
|
||||
{
|
||||
NearestPointX = A1x;
|
||||
NearestPointY = A1y;
|
||||
NearestPointZ = A1z;
|
||||
return;
|
||||
}
|
||||
|
||||
float ABx = Bx - A1x;
|
||||
float ABy = By - A1y;
|
||||
float ABz = Bz - A1z;
|
||||
|
||||
// parameter is computed from Equation (20).
|
||||
parameter = (Lx * ABx + Ly * ABy + Lz * ABz) / D;
|
||||
|
||||
if (false == infinite_line) parameter = FMAX(0.0f, FMIN(1.0f, parameter));
|
||||
|
||||
NearestPointX = A1x + parameter * Lx;
|
||||
NearestPointY = A1y + parameter * Ly;
|
||||
NearestPointZ = A1z + parameter * Lz;
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
||||
| Method: FindNearestPointOfParallelLineSegments
|
||||
|
|
||||
| Purpose: Given two lines (segments) that are known to be parallel, find
|
||||
| a representative point on each that is nearest to the other. If
|
||||
| the lines are considered to be finite then it is possible that there
|
||||
| is one true point on each line that is nearest to the other. This
|
||||
| code properly handles this case.
|
||||
|
|
||||
| This is the most difficult line intersection case to handle, since
|
||||
| there is potentially a family, or locus of points on each line/segment
|
||||
| that are nearest to the other.
|
||||
| Parameters: Input:
|
||||
| ------
|
||||
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
|
||||
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
|
||||
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|
||||
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
|
||||
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
|
||||
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|
||||
| infinite_lines - set to true if lines are to be treated as infinite
|
||||
| epsilon_squared - tolerance value to be used to check for degenerate
|
||||
| and parallel lines, and to check for true intersection.
|
||||
|
|
||||
| Output:
|
||||
| -------
|
||||
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
|
||||
| PointOnSegAy, to segment B. This corresponds to point C in the text.
|
||||
| PointOnSegAz
|
||||
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
|
||||
| PointOnSegBy, to segment A. This corresponds to point D in the text.
|
||||
| PointOnSegBz
|
||||
|
||||
**************************************************************************/
|
||||
void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z,
|
||||
float A2x, float A2y, float A2z,
|
||||
float Lax, float Lay, float Laz,
|
||||
float B1x, float B1y, float B1z,
|
||||
float B2x, float B2y, float B2z,
|
||||
float Lbx, float Lby, float Lbz,
|
||||
bool infinite_lines, float epsilon_squared,
|
||||
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
|
||||
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz)
|
||||
{
|
||||
float s[2], temp;
|
||||
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
|
||||
true, epsilon_squared, PointOnSegAx, PointOnSegAy, PointOnSegAz, s[0]);
|
||||
if (true == infinite_lines)
|
||||
{
|
||||
PointOnSegBx = B1x;
|
||||
PointOnSegBy = B1y;
|
||||
PointOnSegBz = B1z;
|
||||
}
|
||||
else
|
||||
{
|
||||
float tp[3];
|
||||
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B2x, B2y, B2z,
|
||||
true, epsilon_squared, tp[0], tp[1], tp[2], s[1]);
|
||||
if (s[0] < 0.f && s[1] < 0.f)
|
||||
{
|
||||
PointOnSegAx = A1x;
|
||||
PointOnSegAy = A1y;
|
||||
PointOnSegAz = A1z;
|
||||
if (s[0] < s[1])
|
||||
{
|
||||
PointOnSegBx = B2x;
|
||||
PointOnSegBy = B2y;
|
||||
PointOnSegBz = B2z;
|
||||
}
|
||||
else
|
||||
{
|
||||
PointOnSegBx = B1x;
|
||||
PointOnSegBy = B1y;
|
||||
PointOnSegBz = B1z;
|
||||
}
|
||||
}
|
||||
else if (s[0] > 1.f && s[1] > 1.f)
|
||||
{
|
||||
PointOnSegAx = A2x;
|
||||
PointOnSegAy = A2y;
|
||||
PointOnSegAz = A2z;
|
||||
if (s[0] < s[1])
|
||||
{
|
||||
PointOnSegBx = B1x;
|
||||
PointOnSegBy = B1y;
|
||||
PointOnSegBz = B1z;
|
||||
}
|
||||
else
|
||||
{
|
||||
PointOnSegBx = B2x;
|
||||
PointOnSegBy = B2y;
|
||||
PointOnSegBz = B2z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
|
||||
PointOnSegAx = (A1x + temp * Lax);
|
||||
PointOnSegAy = (A1y + temp * Lay);
|
||||
PointOnSegAz = (A1z + temp * Laz);
|
||||
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz,
|
||||
PointOnSegAx, PointOnSegAy, PointOnSegAz, true,
|
||||
epsilon_squared, PointOnSegBx, PointOnSegBy, PointOnSegBz, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
||||
| Method: AdjustNearestPoints
|
||||
|
|
||||
| Purpose: Given nearest point information for two infinite lines, adjust
|
||||
| to model finite line segments.
|
||||
|
|
||||
| Parameters: Input:
|
||||
| ------
|
||||
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
|
||||
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|
||||
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
|
||||
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|
||||
| epsilon_squared - tolerance value to be used to check for degenerate
|
||||
| and parallel lines, and to check for true intersection.
|
||||
| s - parameter representing nearest point on infinite line A
|
||||
| t - parameter representing nearest point on infinite line B
|
||||
|
|
||||
| Output:
|
||||
| -------
|
||||
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
|
||||
| PointOnSegAy, to segment B. This corresponds to point C in the text.
|
||||
| PointOnSegAz
|
||||
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
|
||||
| PointOnSegBy, to segment A. This corresponds to point D in the text.
|
||||
| PointOnSegBz
|
||||
**************************************************************************/
|
||||
void AdjustNearestPoints(float A1x, float A1y, float A1z,
|
||||
float Lax, float Lay, float Laz,
|
||||
float B1x, float B1y, float B1z,
|
||||
float Lbx, float Lby, float Lbz,
|
||||
float epsilon_squared, float s, float t,
|
||||
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
|
||||
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz)
|
||||
{
|
||||
// handle the case where both parameter s and t are out of range
|
||||
if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
|
||||
{
|
||||
s = FMAX(0.0f, FMIN(1.0f, s));
|
||||
PointOnSegAx = (A1x + s * Lax);
|
||||
PointOnSegAy = (A1y + s * Lay);
|
||||
PointOnSegAz = (A1z + s * Laz);
|
||||
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
|
||||
PointOnSegAy, PointOnSegAz, true, epsilon_squared,
|
||||
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
|
||||
if (OUT_OF_RANGE(t))
|
||||
{
|
||||
t = FMAX(0.0f, FMIN(1.0f, t));
|
||||
PointOnSegBx = (B1x + t * Lbx);
|
||||
PointOnSegBy = (B1y + t * Lby);
|
||||
PointOnSegBz = (B1z + t * Lbz);
|
||||
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
|
||||
PointOnSegBy, PointOnSegBz, false, epsilon_squared,
|
||||
PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
|
||||
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
|
||||
PointOnSegAy, PointOnSegAz, false, epsilon_squared,
|
||||
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
|
||||
}
|
||||
}
|
||||
// otherwise, handle the case where the parameter for only one segment is
|
||||
// out of range
|
||||
else if (OUT_OF_RANGE(s))
|
||||
{
|
||||
s = FMAX(0.0f, FMIN(1.0f, s));
|
||||
PointOnSegAx = (A1x + s * Lax);
|
||||
PointOnSegAy = (A1y + s * Lay);
|
||||
PointOnSegAz = (A1z + s * Laz);
|
||||
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
|
||||
PointOnSegAy, PointOnSegAz, false, epsilon_squared,
|
||||
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
|
||||
}
|
||||
else if (OUT_OF_RANGE(t))
|
||||
{
|
||||
t = FMAX(0.0f, FMIN(1.0f, t));
|
||||
PointOnSegBx = (B1x + t * Lbx);
|
||||
PointOnSegBy = (B1y + t * Lby);
|
||||
PointOnSegBz = (B1z + t * Lbz);
|
||||
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
|
||||
PointOnSegBy, PointOnSegBz, false, epsilon_squared,
|
||||
PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/* Copyright (C) Graham Rhodes, 2001.
|
||||
* All rights reserved worldwide.
|
||||
*
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranties. You may freely copy and compile this source into
|
||||
* applications you distribute provided that the copyright text
|
||||
* below is included in the resulting source code, for example:
|
||||
* "Portions Copyright (C) Graham Rhodes, 2001"
|
||||
*/
|
||||
/**************************************************************************************
|
||||
|
|
||||
| File: lineintersect_utils.h
|
||||
|
|
||||
| Purpose: Function prototypes for line segment intersection utility functions
|
||||
|
|
||||
| Book Title: Game Programming Gems II
|
||||
|
|
||||
| Chapter Title: Fast, Robust Intersection of 3D Line Segments
|
||||
|
|
||||
| Author: Graham Rhodes
|
||||
|
|
||||
| Revisions: 05-Apr-2001 - GSR. Original.
|
||||
|
|
||||
**************************************************************************************/
|
||||
#ifndef _lineintersect_utils_h
|
||||
#define _lineintersect_utils_h
|
||||
|
||||
void IntersectLineSegments(const D3DXVECTOR3 & A1,
|
||||
const D3DXVECTOR3 & A2,
|
||||
const D3DXVECTOR3 & B1,
|
||||
const D3DXVECTOR3 & B2,
|
||||
//bool infinite_lines, /*float epsilon,*/
|
||||
D3DXVECTOR3 & OutA,
|
||||
D3DXVECTOR3 & OutB);
|
||||
|
||||
|
||||
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
|
||||
const float A2x, const float A2y, const float A2z,
|
||||
const float B1x, const float B1y, const float B1z,
|
||||
const float B2x, const float B2y, const float B2z,
|
||||
bool infinite_lines, float epsilon, float &PointOnSegAx,
|
||||
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
|
||||
float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX,
|
||||
float &NearestPointY, float &NearestPointZ, float &NearestVectorX,
|
||||
float &NearestVectorY, float &NearestVectorZ, bool &true_intersection);
|
||||
|
||||
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
|
||||
const float A2x, const float A2y, const float A2z,
|
||||
const float B1x, const float B1y, const float B1z,
|
||||
const float B2x, const float B2y, const float B2z,
|
||||
bool infinite_lines, float epsilon, float &PointOnSegAx,
|
||||
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
|
||||
float &PointOnSegBy, float &PointOnSegBz);
|
||||
|
||||
void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z,
|
||||
const float Lx, const float Ly, const float Lz,
|
||||
const float Bx, const float By, const float Bz,
|
||||
bool infinite_line, float epsilon_squared, float &NearestPointX,
|
||||
float &NearestPointY, float &NearestPointZ,
|
||||
float ¶meter);
|
||||
|
||||
void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z,
|
||||
float A2x, float A2y, float A2z,
|
||||
float Lax, float Lay, float Laz,
|
||||
float B1x, float B1y, float B1z,
|
||||
float B2x, float B2y, float B2z,
|
||||
float Lbx, float Lby, float Lbz,
|
||||
bool infinite_lines, float epsilon_squared,
|
||||
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
|
||||
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz);
|
||||
|
||||
void AdjustNearestPoints(float A1x, float A1y, float A1z,
|
||||
float Lax, float Lay, float Laz,
|
||||
float B1x, float B1y, float B1z,
|
||||
float Lbx, float Lby, float Lbz,
|
||||
float epsilon_squared, float s, float t,
|
||||
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
|
||||
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz);
|
||||
|
||||
#endif // _lineintersect_utils_h
|
||||
@@ -0,0 +1,443 @@
|
||||
#include "StdAfx.h"
|
||||
#include "parser.h"
|
||||
|
||||
using namespace script;
|
||||
|
||||
#define ishan(ch) (((ch) & 0xE0) > 0x90)
|
||||
#define isnhspace(ch) (!ishan(ch) && isspace(ch))
|
||||
|
||||
|
||||
extern DWORD GetDefaultCodePage();
|
||||
|
||||
const char* LocaleString_FindChar(const char* base, int len, char test)
|
||||
{
|
||||
if (!base)
|
||||
return NULL;
|
||||
|
||||
DWORD codePage = GetDefaultCodePage();
|
||||
|
||||
int pos = 0;
|
||||
while (pos < len)
|
||||
{
|
||||
const char* cur = base + pos;
|
||||
const char* next = CharNextExA(codePage, cur, 0);
|
||||
int cur_len = next - cur;
|
||||
if (cur_len > 1)
|
||||
{
|
||||
pos += cur_len;
|
||||
}
|
||||
else if (1 == cur_len)
|
||||
{
|
||||
if (*cur == test)
|
||||
return cur;
|
||||
|
||||
++pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int LocaleString_RightTrim(char* base, int len)
|
||||
{
|
||||
DWORD codePage = GetDefaultCodePage();
|
||||
|
||||
int pos = len;
|
||||
|
||||
while (pos > 0)
|
||||
{
|
||||
char* cur = base + pos;
|
||||
char* prev = CharPrevExA(codePage, base, cur , 0);
|
||||
|
||||
int prev_len = cur - prev;
|
||||
if (prev_len != 1)
|
||||
break;
|
||||
|
||||
if (!isspace((unsigned char) *prev) && *prev != '\n' && *prev != '\r')
|
||||
break;
|
||||
|
||||
*prev = '\0';
|
||||
|
||||
pos -= prev_len;
|
||||
}
|
||||
|
||||
if (pos > 0)
|
||||
return pos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LocaleString_RightTrim(char* base)
|
||||
{
|
||||
LocaleString_RightTrim(base, strlen(base));
|
||||
}
|
||||
|
||||
void OLD_rtrim(char* base)
|
||||
{
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
DWORD codePage = GetDefaultCodePage();
|
||||
|
||||
if (949 == codePage || 936 == codePage)
|
||||
{
|
||||
char* end = base + strlen(base) - 1;
|
||||
|
||||
while (end != base)
|
||||
{
|
||||
if (!isnhspace((unsigned char) *end) && *end != '\n' && *end != '\r' || (end!=base && *((unsigned char*)end-1)>0xa0))
|
||||
break;
|
||||
|
||||
*end = '\0';
|
||||
|
||||
end = CharPrevExA(codePage, base, end, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char* end = base + strlen(base);
|
||||
|
||||
while (end != base)
|
||||
{
|
||||
char* prev = CharPrevExA(codePage, base, end, 0);
|
||||
|
||||
int prev_len = end - prev;
|
||||
if (prev_len != 1)
|
||||
break;
|
||||
|
||||
if (!isspace((unsigned char) *prev) && *prev != '\n' && *prev != '\r')
|
||||
break;
|
||||
|
||||
*prev = '\0';
|
||||
|
||||
end = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* LocaleString_Skip(DWORD codePage, const char* cur)
|
||||
{
|
||||
int loopCount = 0;
|
||||
|
||||
while (*cur)
|
||||
{
|
||||
if (++loopCount > 9216)
|
||||
{
|
||||
TraceError("Infinite loop in LocaleString_Skip [%s]", cur);
|
||||
break;
|
||||
}
|
||||
|
||||
const char* next = CharNextExA(codePage, cur, 0);
|
||||
int cur_len = next - cur;
|
||||
if (cur_len > 1)
|
||||
{
|
||||
cur = next;
|
||||
}
|
||||
else if (1 == cur_len)
|
||||
{
|
||||
if (!isspace((unsigned char) *cur) && *cur != '\n' && *cur != '\r')
|
||||
return cur;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
bool Group::GetArg(const char *c_arg_base, int arg_len, TArgList & argList)
|
||||
{
|
||||
char szName[32 + 1];
|
||||
char szValue[64 + 1];
|
||||
|
||||
int iNameLen = 0;
|
||||
int iValueLen = 0;
|
||||
int iCharLen = 0;
|
||||
|
||||
int pos = 0;
|
||||
|
||||
bool isValue = false;
|
||||
|
||||
DWORD codePage = GetDefaultCodePage();
|
||||
|
||||
while (pos < arg_len)
|
||||
{
|
||||
const char* cur = c_arg_base + pos;
|
||||
const char* next = CharNextExA(codePage, cur, 0);
|
||||
iCharLen = next - cur;
|
||||
|
||||
if (iCharLen > 1)
|
||||
{
|
||||
if (isValue)
|
||||
{
|
||||
if (iValueLen >= 64)
|
||||
{
|
||||
TraceError("argument value overflow: must be shorter than 64 letters");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(szValue+iValueLen, cur, iCharLen);
|
||||
iValueLen += iCharLen;
|
||||
szValue[iValueLen] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iNameLen >= 32)
|
||||
{
|
||||
TraceError("argument name overflow: must be shorter than 32 letters");
|
||||
return false;
|
||||
}
|
||||
memcpy(szName+iNameLen, cur, iCharLen);
|
||||
iNameLen += iCharLen;
|
||||
szName[iNameLen] = '\0';
|
||||
}
|
||||
}
|
||||
else if (iCharLen == 1)
|
||||
{
|
||||
const char c = *cur;
|
||||
if (c == '|')
|
||||
{
|
||||
if (iNameLen == 0)
|
||||
{
|
||||
TraceError("no argument name");
|
||||
return false;
|
||||
}
|
||||
|
||||
isValue = false;
|
||||
|
||||
iNameLen = LocaleString_RightTrim(szName, iNameLen);
|
||||
iValueLen = LocaleString_RightTrim(szValue, iValueLen);
|
||||
argList.push_back(TArg(szName, szValue));
|
||||
|
||||
iNameLen = 0;
|
||||
iValueLen = 0;
|
||||
}
|
||||
else if (c == ';')
|
||||
{
|
||||
isValue = true;
|
||||
}
|
||||
// 값이 아니고, 이름이 시작되지 않았을 경우 빈칸은 건너 뛴다.
|
||||
else if (!isValue && iNameLen == 0 && isspace((unsigned char) c))
|
||||
{
|
||||
}
|
||||
// 엔터는 건너 뛴다
|
||||
else if (c == '\r' || c == '\n')
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isValue)
|
||||
{
|
||||
if (iValueLen >= 64)
|
||||
{
|
||||
TraceError("argument value overflow: must be shorter than 64 letters");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(szValue+iValueLen, cur, iCharLen);
|
||||
iValueLen += iCharLen;
|
||||
szValue[iValueLen] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iNameLen >= 32)
|
||||
{
|
||||
TraceError("argument name overflow: must be shorter than 32 letters");
|
||||
return false;
|
||||
}
|
||||
memcpy(szName+iNameLen, cur, iCharLen);
|
||||
iNameLen += iCharLen;
|
||||
szName[iNameLen] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pos += iCharLen;
|
||||
}
|
||||
|
||||
if (iNameLen != 0 && iValueLen != 0)
|
||||
{
|
||||
iNameLen = LocaleString_RightTrim(szName, iNameLen);
|
||||
iValueLen = LocaleString_RightTrim(szValue, iValueLen);
|
||||
argList.push_back(TArg(szName, szValue));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Group::Create(const std::string & stSource)
|
||||
{
|
||||
m_cmdList.clear();
|
||||
|
||||
if (stSource.empty())
|
||||
return false;
|
||||
|
||||
const char *str_base = stSource.c_str();
|
||||
if (!str_base || !*str_base)
|
||||
{
|
||||
TraceError("Source file has no content");
|
||||
return false;
|
||||
}
|
||||
int str_len = stSource.length();
|
||||
int str_pos = 0;
|
||||
|
||||
DWORD codePage = GetDefaultCodePage();
|
||||
|
||||
char box_data[1024 + 1];
|
||||
|
||||
static std::string stLetter;
|
||||
|
||||
while (str_pos < str_len)
|
||||
{
|
||||
TCmd cmd;
|
||||
|
||||
const char* word = str_base + str_pos;
|
||||
const char* word_next = CharNextExA(codePage, word, 0);
|
||||
|
||||
int word_len = word_next - word;
|
||||
|
||||
if (word_len > 1)
|
||||
{
|
||||
str_pos += word_len;
|
||||
|
||||
{
|
||||
stLetter.assign(word, word_next);
|
||||
|
||||
cmd.name.assign("LETTER");
|
||||
cmd.argList.push_back(TArg("value", stLetter));
|
||||
|
||||
m_cmdList.push_back(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
else if (word_len == 1)
|
||||
{
|
||||
const char cur = *word;
|
||||
|
||||
if ('[' == cur)
|
||||
{
|
||||
++str_pos;
|
||||
|
||||
const char* box_begin = str_base + str_pos;
|
||||
const char* box_end = LocaleString_FindChar(box_begin, str_len - str_pos, ']');
|
||||
if (!box_end)
|
||||
{
|
||||
TraceError(" !! PARSING ERROR - Syntax Error : %s\n", box_begin);
|
||||
return false;
|
||||
}
|
||||
str_pos += box_end - box_begin + 1;
|
||||
|
||||
|
||||
int data_len = 0;
|
||||
{
|
||||
const char* data_begin = LocaleString_Skip(codePage, box_begin);
|
||||
const char* data_end = box_end;
|
||||
data_len = data_end - data_begin;
|
||||
if (data_len >= 1024)
|
||||
{
|
||||
TraceError(" !! PARSING ERROR - Buffer Overflow : %d, %s\n", data_len, str_base);
|
||||
return false;
|
||||
}
|
||||
memcpy(box_data, data_begin, data_len);
|
||||
box_data[data_len] = '\0';
|
||||
|
||||
data_len = LocaleString_RightTrim(box_data, data_len); // 오른쪽 빈칸 자르기
|
||||
}
|
||||
|
||||
{
|
||||
const char* space = LocaleString_FindChar(box_data, data_len, ' ');
|
||||
if (space) // 인자가 있음
|
||||
{
|
||||
int name_len = space - box_data;
|
||||
cmd.name.assign(box_data, name_len);
|
||||
|
||||
const char* space_next = CharNextExA(codePage, space, 0);
|
||||
const char* arg = LocaleString_Skip(codePage, space_next);
|
||||
|
||||
int arg_len = data_len - (arg - box_data);
|
||||
|
||||
if (!GetArg(arg, arg_len, cmd.argList))
|
||||
{
|
||||
TraceError(" !! PARSING ERROR - Unknown Arguments : %d, %s\n", arg_len, arg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // 인자가 없으므로 모든 스트링이 명령어다.
|
||||
{
|
||||
cmd.name.assign(box_data);
|
||||
cmd.argList.clear();
|
||||
}
|
||||
|
||||
m_cmdList.push_back(cmd);
|
||||
}
|
||||
}
|
||||
else if (cur == '\r' || cur == '\n')
|
||||
{
|
||||
++str_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
++str_pos;
|
||||
|
||||
{
|
||||
stLetter.assign(1, cur);
|
||||
cmd.name.assign("LETTER");
|
||||
cmd.argList.push_back(TArg("value", stLetter));
|
||||
m_cmdList.push_back(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Group::GetCmd(TCmd & cmd)
|
||||
{
|
||||
if (m_cmdList.empty())
|
||||
return false;
|
||||
|
||||
cmd = m_cmdList.front();
|
||||
m_cmdList.pop_front();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Group::ReadCmd(TCmd & cmd)
|
||||
{
|
||||
if (m_cmdList.empty())
|
||||
return false;
|
||||
|
||||
cmd = m_cmdList.front();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string & Group::GetError()
|
||||
{
|
||||
return m_stError;
|
||||
}
|
||||
|
||||
void Group::SetError(const char * c_pszError)
|
||||
{
|
||||
m_stError.assign(c_pszError);
|
||||
}
|
||||
|
||||
Group::Group()
|
||||
{
|
||||
}
|
||||
|
||||
Group::~Group()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
#ifndef __INC_SCRIPT_PARSER_H__
|
||||
#define __INC_SCRIPT_PARSER_H__
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
namespace script
|
||||
{
|
||||
typedef struct SArgumet
|
||||
{
|
||||
SArgumet(const std::string& c_stName, const std::string& c_stValue)
|
||||
{
|
||||
strName = c_stName;
|
||||
strValue = c_stValue;
|
||||
}
|
||||
SArgumet(const SArgumet& c_arg)
|
||||
{
|
||||
strName = c_arg.strName;
|
||||
strValue = c_arg.strValue;
|
||||
}
|
||||
void operator=(const SArgumet& c_arg)
|
||||
{
|
||||
strName = c_arg.strName;
|
||||
strValue = c_arg.strValue;
|
||||
}
|
||||
std::string strName;
|
||||
std::string strValue;
|
||||
} TArg;
|
||||
|
||||
typedef std::list<TArg> TArgList;
|
||||
|
||||
typedef struct SCmd
|
||||
{
|
||||
std::string name;
|
||||
TArgList argList;
|
||||
|
||||
SCmd()
|
||||
{}
|
||||
SCmd(const SCmd& c_cmd)
|
||||
{
|
||||
name = c_cmd.name;
|
||||
argList = c_cmd.argList;
|
||||
}
|
||||
void operator=(const SCmd& c_cmd)
|
||||
{
|
||||
name = c_cmd.name;
|
||||
argList = c_cmd.argList;
|
||||
}
|
||||
} TCmd;
|
||||
|
||||
class Group
|
||||
{
|
||||
public:
|
||||
Group();
|
||||
~Group();
|
||||
|
||||
public:
|
||||
/** 스트링으로 부터 스크립트 그룹을 만든다.
|
||||
*
|
||||
* 실패하면 GetError 메소드로 확인할 수 있다.
|
||||
*
|
||||
* @param stSource 이 스트링으로 부터 그룹이 만들어 진다.
|
||||
* @return 성공시 true, 실패하면 false
|
||||
*/
|
||||
bool Create(const std::string & stSource);
|
||||
|
||||
/** 명령어를 받는 메소드
|
||||
*
|
||||
* @param cmd 성공시에 이 구조체로 명령어가 복사 된다.
|
||||
* @return 명령어가 남아 있다면 true, 없다면 false
|
||||
*/
|
||||
bool GetCmd(TCmd & cmd);
|
||||
|
||||
/*
|
||||
명령어를 가져오되 꺼내지는 않는다.
|
||||
*/
|
||||
bool ReadCmd(TCmd & cmd);
|
||||
|
||||
/** 에러를 출력 받는 메소드
|
||||
*
|
||||
* @return stError 이 곳으로 에러가 출력 된다.
|
||||
*/
|
||||
std::string & GetError();
|
||||
|
||||
private:
|
||||
void SetError(const char *str);
|
||||
bool GetArg(const char * c_atr_base, int arg_len, TArgList & argList);
|
||||
|
||||
std::string m_stError;
|
||||
std::list<TCmd> m_cmdList;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user