Files
Client/CROSSM_PROJECT_ANALYSIS.md
docker-debian 87723d2d12 Add comprehensive documentation for Graphics Interface and CrossM
Added two major documentation files:

1. GRAPHICS_INTERFACE_GUIDE.md (18KB)
   - Complete graphics abstraction layer guide
   - System architecture (5 layers)
   - Initialization flow with actual code
   - Rendering command flow
   - Real usage examples
   - Integration with BaseGraphicsLayer
   - Complete DX command mapping table
   - All 700+ DX commands analyzed

   Key Sections:
   - How the system works (from WinMain to GPU)
   - Where initialization happens
   - How commands are processed
   - DX8/DX9/DX12 command mapping
   - Step-by-step integration guide

2. CROSSM_PROJECT_ANALYSIS.md (20KB)
   - Complete CrossM library analysis
   - Math library (Vector3, MathUtil)
   - Octree collision detection system
   - Ellipsoid vs Triangle collision
   - Kasper Fauerby's algorithm explanation
   - Usage examples with RiskYourLife
   - Performance optimization tips
   - Debug visualization

   Key Components:
   - Vector3 (inline math operations)
   - OctreeCollider (spatial partitioning)
   - CollisionEllipsoidHelper (character collision)
   - Integration with terrain/character systems

Documentation Features:
 Code examples for every feature
 Real file paths and function names
 Step-by-step integration guides
 Performance considerations
 Debug tips
 Visual diagrams (ASCII art)

Total: ~38KB of comprehensive documentation
Ready for developer onboarding!
2025-12-01 13:07:39 +09:00

1018 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CrossM 프로젝트 분석 문서
## 목차
1. [프로젝트 개요](#프로젝트-개요)
2. [아키텍처](#아키텍처)
3. [핵심 컴포넌트](#핵심-컴포넌트)
4. [수학 라이브러리](#수학-라이브러리)
5. [충돌 감지 시스템](#충돌-감지-시스템)
6. [사용 예제](#사용-예제)
7. [게임과의 통합](#게임과의-통합)
---
## 프로젝트 개요
### 기본 정보
- **프로젝트명**: CrossM (Cross Mathematics / Cross Mechanics)
- **타입**: Static Library (.lib)
- **위치**: `Client/Engine/CrossM/`
- **목적**: 3D 수학 연산 및 물리 충돌 감지
### 프로젝트 구조
```
CrossM/
├── Include/ # 헤더 파일
│ ├── Vector3.h # 3D 벡터
│ ├── MathUtil.h # 수학 유틸리티
│ ├── MathConst.h # 수학 상수
│ ├── OctreeCollider.h # Octree 충돌 감지
│ └── CollisionEllipsoidHelper.h # Ellipsoid 충돌 헬퍼
├── Src/ # 소스 파일
│ ├── MathUtil.cpp
│ ├── OctreeCollider.cpp
│ └── CollisionEllipsoidHelper.cpp
├── CrossM.vcxproj # VS 2019 프로젝트
├── CrossM.vcproj # VS 2008 프로젝트 (레거시)
└── ReadMe.txt
```
### 주요 특징
-**헤더 전용 수학 라이브러리** (대부분 inline 함수)
-**Octree 기반 충돌 감지** (공간 분할)
-**Ellipsoid vs Triangle 충돌** (캐릭터 충돌)
-**DirectX 9 독립적** (수학 연산만 의존)
-**네임스페이스 격리** (`CrossM::Math`, `CrossM::Scene`)
---
## 아키텍처
### 계층 구조
```
[게임 로직]
[물리 엔진]
[CrossM 라이브러리]
├─ Math::VECTOR3 # 3D 벡터 연산
├─ Math::MathUtil # 수학 유틸리티
└─ Scene::COctreeCollider # 충돌 감지
```
### 네임스페이스 구조
```cpp
namespace CrossM {
namespace Math {
// 수학 관련
struct VECTOR3;
float GetLength();
VECTOR3& Normalize();
// ...
}
namespace Scene {
// 씬/물리 관련
struct CollisionTriangleInfo;
class COctreeCollisionNode;
class COctreeCollider;
class CCollisionEllipsoidHelper;
}
}
```
---
## 핵심 컴포넌트
### 1. Vector3 (3D 벡터)
**파일**: `Include/Vector3.h`
#### 구조체 정의
```cpp
namespace CrossM {
namespace Math {
struct VECTOR3
{
float x, y, z;
VECTOR3() {}
VECTOR3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
void SetValue(float _x, float _y, float _z) {
x = _x; y = _y; z = _z;
}
};
} // namespace Math
} // namespace CrossM
```
#### 주요 연산 (inline 함수)
```cpp
// 벡터 길이
inline float GetLength(const VECTOR3& v) {
return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
}
// 정규화
inline VECTOR3& Normalize(VECTOR3& vOut, const VECTOR3& vIn) {
float fLen = GetLength(vIn);
if (fLen < F_EPSILON) {
SetValue(vOut, 1.0f, 0.0f, 0.0f);
return vOut;
}
float fInv = 1.0f / fLen;
vOut.x = vIn.x * fInv;
vOut.y = vIn.y * fInv;
vOut.z = vIn.z * fInv;
return vOut;
}
// 벡터 덧셈
inline VECTOR3& Add(VECTOR3& vOut, const VECTOR3& v1, const VECTOR3& v2) {
vOut.x = v1.x + v2.x;
vOut.y = v1.y + v2.y;
vOut.z = v1.z + v2.z;
return vOut;
}
// 벡터 뺄셈
inline VECTOR3& Subtract(VECTOR3& vOut, const VECTOR3& v1, const VECTOR3& v2) {
vOut.x = v1.x - v2.x;
vOut.y = v1.y - v2.y;
vOut.z = v1.z - v2.z;
return vOut;
}
// 스케일
inline VECTOR3& Scale(VECTOR3& vOut, const VECTOR3& vIn, float fScale) {
vOut.x = vIn.x * fScale;
vOut.y = vIn.y * fScale;
vOut.z = vIn.z * fScale;
return vOut;
}
// 내적 (Dot Product)
inline float DotProduct(const VECTOR3& v1, const VECTOR3& v2) {
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
}
// 외적 (Cross Product)
inline VECTOR3& CrossProduct(VECTOR3& vOut, const VECTOR3& v1, const VECTOR3& v2) {
vOut.x = v1.y*v2.z - v1.z*v2.y;
vOut.y = v1.z*v2.x - v1.x*v2.z;
vOut.z = v1.x*v2.y - v1.y*v2.x;
return vOut;
}
```
#### 사용 예제
```cpp
using namespace CrossM::Math;
// 벡터 생성
VECTOR3 v1(1.0f, 0.0f, 0.0f);
VECTOR3 v2(0.0f, 1.0f, 0.0f);
// 벡터 연산
VECTOR3 vSum;
Add(vSum, v1, v2); // vSum = (1, 1, 0)
// 정규화
VECTOR3 vNorm;
Normalize(vNorm, vSum); // vNorm = (0.707, 0.707, 0)
// 내적
float dot = DotProduct(v1, v2); // dot = 0 (수직)
// 외적
VECTOR3 vCross;
CrossProduct(vCross, v1, v2); // vCross = (0, 0, 1) (Z축)
```
---
### 2. MathConst (수학 상수)
**파일**: `Include/MathConst.h`
```cpp
namespace CrossM {
namespace Math {
// 부동소수점 오차 범위
const float F_EPSILON = 0.00001f;
// 원주율
const float F_PI = 3.14159265358979323846f;
// 도/라디안 변환
const float F_DEG_TO_RAD = F_PI / 180.0f;
const float F_RAD_TO_DEG = 180.0f / F_PI;
} // namespace Math
} // namespace CrossM
```
---
### 3. OctreeCollider (충돌 감지)
**파일**: `Include/OctreeCollider.h`, `Src/OctreeCollider.cpp`
#### 개념: Octree란?
Octree는 3D 공간을 8개의 하위 공간으로 재귀적으로 분할하는 자료구조입니다.
```
+-------+-------+
/| /| /|
/ | 1 / | 0 / |
+-------+-------+ |
| +---|--+---|--+ |
| /| | /| | /| |
|/ | 5 |/ | 4 |/ | |
+-------+-------+ |
| +---|--+---|--+ +
| /| 3 | /| 2 | /|/
|/ | |/ | |/ |
+-------+-------+ /
| +---|--+---|--+
| / 7 | / 6 | /
|/ |/ |/
+-------+-------+
```
#### CollisionTriangleInfo 구조체
```cpp
struct CollisionTriangleInfo
{
Math::VECTOR3 m_avVertex[3]; // 삼각형 3개 정점
Math::VECTOR3 m_vFaceNormal; // 면 법선
// 추가 정보 (옵션):
// - 오브젝트 ID
// - 재질 정보
// - 충돌 플래그
};
```
#### COctreeCollisionNode 클래스
```cpp
class COctreeCollisionNode
{
public:
COctreeCollisionNode();
~COctreeCollisionNode();
// 하위 노드 해제
void ReleaseSubNode();
// Leaf 노드인지 확인
bool IsLeafNode();
// 하위 노드 생성 및 삼각형 분배
void BuildSubNode(
const std::vector<CollisionTriangleInfo>& vecTriangle,
const size_t nMaximumRecursion,
const size_t nMinPolyCount,
size_t nCurrentRecursionLevel
);
// 충돌 가능한 노드 수집
void CollectCollidableNodes(
const Math::VECTOR3& vSweptVolumeMin,
const Math::VECTOR3& vSweptVolumeMax,
std::vector<COctreeCollisionNode*>& vecCollidableNode
);
// 데이터
Math::VECTOR3 m_vBoundingMin; // AABB 최소점
Math::VECTOR3 m_vBoundingMax; // AABB 최대점
std::vector<size_t> m_vecTriangleIndex; // 포함된 삼각형 인덱스
COctreeCollisionNode* m_apSubNode[8]; // 8개 자식 노드
};
```
#### COctreeCollider 클래스
```cpp
class COctreeCollider
{
public:
COctreeCollider();
~COctreeCollider();
// ===== Octree 구축 =====
// 삼각형 개수 설정 (메모리 할당)
void SetTriangleCount(unsigned int uiTriangleCount);
// 삼각형 데이터 포인터 얻기
void GetTriangleDataPtr(CollisionTriangleInfo*& pTriangleData);
// Octree 구축
bool BuildOctree(
const size_t nMaximumRecursion, // 최대 재귀 깊이
const size_t nMinPolyCount // 노드당 최소 폴리곤 수
);
// ===== 충돌 감지 =====
// Swept Sphere vs Triangle 충돌
bool CheckCollision(
const Math::VECTOR3& vStart, // 시작 위치
const Math::VECTOR3& vEnd, // 끝 위치
const Math::VECTOR3& vERadius, // Ellipsoid 반지름
Math::VECTOR3& vOutPosition, // 출력: 최종 위치
bool bSliding // 슬라이딩 여부
);
// ===== 디버그 =====
// Octree 시각화 (디버그용)
void DrawOctree(IDirect3DDevice9* pDevice, int nDrawDepth);
private:
CollisionTriangleInfo* m_pTriangleData; // 삼각형 배열
unsigned int m_uiTriangleCount; // 삼각형 개수
COctreeCollisionNode m_RootNode; // 루트 노드
};
```
---
### 4. CollisionEllipsoidHelper (Ellipsoid 충돌)
**파일**: `Include/CollisionEllipsoidHelper.h`, `Src/CollisionEllipsoidHelper.cpp`
Ellipsoid(타원체)는 캐릭터의 충돌 볼륨을 표현하는데 사용됩니다.
```
Y
|
+--- (Radius.y)
/|
/ |
/ +--- X (Radius.x)
+
Z (Radius.z)
```
#### 주요 기능
```cpp
class CCollisionEllipsoidHelper
{
public:
// Ellipsoid vs Triangle 충돌 검사
static bool CheckCollision(
const Math::VECTOR3& vEllipsoidCenter,
const Math::VECTOR3& vEllipsoidRadius,
const Math::VECTOR3& vVelocity,
const CollisionTriangleInfo& triangle,
float& fOutCollisionTime,
Math::VECTOR3& vOutCollisionPoint
);
// Swept Ellipsoid vs Triangle (이동 중 충돌)
static bool SweptEllipsoidTriangle(
const Math::VECTOR3& vStart,
const Math::VECTOR3& vEnd,
const Math::VECTOR3& vRadius,
const CollisionTriangleInfo& triangle,
Math::VECTOR3& vOutPosition
);
private:
// Ellipsoid 공간으로 변환
static void TransformToEllipsoidSpace(
Math::VECTOR3& vOut,
const Math::VECTOR3& vIn,
const Math::VECTOR3& vRadius
);
};
```
---
## 수학 라이브러리
### MathUtil (수학 유틸리티)
**파일**: `Include/MathUtil.h`, `Src/MathUtil.cpp`
#### 주요 함수
```cpp
namespace CrossM {
namespace Math {
// 두 점 사이의 거리
float Distance(const VECTOR3& v1, const VECTOR3& v2);
// 선분과 평면의 교점
bool IntersectLinePlane(
const VECTOR3& vLineStart,
const VECTOR3& vLineEnd,
const VECTOR3& vPlanePoint,
const VECTOR3& vPlaneNormal,
VECTOR3& vOutIntersection,
float& fOutT
);
// 점과 선분의 최단 거리
float DistancePointToLine(
const VECTOR3& vPoint,
const VECTOR3& vLineStart,
const VECTOR3& vLineEnd,
VECTOR3& vOutClosestPoint
);
// 삼각형 면 법선 계산
void CalculateTriangleNormal(
VECTOR3& vOutNormal,
const VECTOR3& v0,
const VECTOR3& v1,
const VECTOR3& v2
);
// AABB (Axis-Aligned Bounding Box) 충돌
bool CheckAABBCollision(
const VECTOR3& vMin1, const VECTOR3& vMax1,
const VECTOR3& vMin2, const VECTOR3& vMax2
);
} // namespace Math
} // namespace CrossM
```
---
## 충돌 감지 시스템
### 작동 원리
#### 1. 초기화 단계
```cpp
// 1. COctreeCollider 생성
COctreeCollider collider;
// 2. 지형 삼각형 데이터 설정
collider.SetTriangleCount(triangleCount);
// 3. 삼각형 데이터 포인터 얻기
CollisionTriangleInfo* pTriangles = nullptr;
collider.GetTriangleDataPtr(pTriangles);
// 4. 삼각형 데이터 채우기
for (int i = 0; i < triangleCount; i++)
{
pTriangles[i].m_avVertex[0] = vertex0;
pTriangles[i].m_avVertex[1] = vertex1;
pTriangles[i].m_avVertex[2] = vertex2;
// 면 법선 계산
CrossM::Math::CalculateTriangleNormal(
pTriangles[i].m_vFaceNormal,
vertex0, vertex1, vertex2
);
}
// 5. Octree 구축
collider.BuildOctree(
5, // 최대 깊이 5단계
10 // 노드당 최소 10개 폴리곤
);
```
#### 2. 충돌 검사 단계
```cpp
// 캐릭터 이동
CrossM::Math::VECTOR3 vStart(x, y, z); // 현재 위치
CrossM::Math::VECTOR3 vEnd(x2, y2, z2); // 목표 위치
CrossM::Math::VECTOR3 vRadius(0.5f, 1.8f, 0.5f); // Ellipsoid 반지름
CrossM::Math::VECTOR3 vFinalPos;
// 충돌 검사 (슬라이딩 포함)
bool bCollided = collider.CheckCollision(
vStart,
vEnd,
vRadius,
vFinalPos,
true // 슬라이딩 활성화
);
if (bCollided)
{
// 충돌 발생 - vFinalPos에 조정된 위치
character->SetPosition(vFinalPos);
}
else
{
// 충돌 없음 - 목표 위치로 이동
character->SetPosition(vEnd);
}
```
### 알고리즘: Kasper Fauerby's Method
CrossM은 **"Improved Collision Detection and Response"** 알고리즘을 사용합니다.
#### 핵심 개념
1. **Ellipsoid Space 변환**
- 캐릭터를 구(Sphere)로 변환
- 지형도 같은 비율로 변환
- 구 vs 삼각형 충돌은 더 간단
2. **Swept Volume**
- 이동 경로상의 모든 위치를 포함하는 볼륨
- Octree로 빠르게 후보 삼각형 필터링
3. **Sliding Response**
- 충돌 시 벽을 따라 미끄러지듯 이동
- 재귀적으로 여러 번 충돌 검사
```
Original Movement:
A --------> B (목표)
|
Collision!
|
C (벽과 충돌)
Sliding Response:
A --------> C (벽까지 이동)
|
+----> D (벽을 따라 슬라이딩)
```
---
## 사용 예제
### 예제 1: 간단한 충돌 검사
```cpp
#include "CrossM/Include/OctreeCollider.h"
#include "CrossM/Include/Vector3.h"
using namespace CrossM;
using namespace CrossM::Math;
using namespace CrossM::Scene;
void InitCollision()
{
// 1. Octree Collider 생성
COctreeCollider* pCollider = new COctreeCollider();
// 2. 지형 메시에서 삼각형 추출
std::vector<VECTOR3> vertices = terrain->GetVertices();
std::vector<int> indices = terrain->GetIndices();
int triangleCount = indices.size() / 3;
pCollider->SetTriangleCount(triangleCount);
CollisionTriangleInfo* pTriangles = nullptr;
pCollider->GetTriangleDataPtr(pTriangles);
// 3. 삼각형 데이터 채우기
for (int i = 0; i < triangleCount; i++)
{
int idx0 = indices[i * 3 + 0];
int idx1 = indices[i * 3 + 1];
int idx2 = indices[i * 3 + 2];
pTriangles[i].m_avVertex[0] = vertices[idx0];
pTriangles[i].m_avVertex[1] = vertices[idx1];
pTriangles[i].m_avVertex[2] = vertices[idx2];
// 법선 계산
VECTOR3 v01, v02;
Subtract(v01, vertices[idx1], vertices[idx0]);
Subtract(v02, vertices[idx2], vertices[idx0]);
CrossProduct(pTriangles[i].m_vFaceNormal, v01, v02);
Normalize(pTriangles[i].m_vFaceNormal, pTriangles[i].m_vFaceNormal);
}
// 4. Octree 구축
pCollider->BuildOctree(6, 8);
// 5. 전역 변수에 저장
g_pTerrainCollider = pCollider;
}
void UpdateCharacter(float deltaTime)
{
// 캐릭터 이동 입력
VECTOR3 vVelocity(0.0f, 0.0f, 0.0f);
if (IsKeyDown('W')) vVelocity.z += 1.0f;
if (IsKeyDown('S')) vVelocity.z -= 1.0f;
if (IsKeyDown('A')) vVelocity.x -= 1.0f;
if (IsKeyDown('D')) vVelocity.x += 1.0f;
// 정규화 및 속도 적용
Normalize(vVelocity, vVelocity);
Scale(vVelocity, vVelocity, 5.0f * deltaTime);
// 현재/목표 위치
VECTOR3 vStart = character->GetPosition();
VECTOR3 vEnd;
Add(vEnd, vStart, vVelocity);
// 캐릭터 크기 (Ellipsoid)
VECTOR3 vRadius(0.5f, 1.8f, 0.5f);
// 충돌 검사
VECTOR3 vFinalPos;
g_pTerrainCollider->CheckCollision(
vStart, vEnd, vRadius,
vFinalPos,
true // 슬라이딩
);
// 최종 위치 적용
character->SetPosition(vFinalPos);
}
```
### 예제 2: 벡터 수학 연산
```cpp
#include "CrossM/Include/Vector3.h"
#include "CrossM/Include/MathUtil.h"
using namespace CrossM::Math;
void CalculateProjectile()
{
// 발사체 초기 상태
VECTOR3 vPosition(0.0f, 1.0f, 0.0f);
VECTOR3 vVelocity(10.0f, 15.0f, 0.0f);
VECTOR3 vGravity(0.0f, -9.8f, 0.0f);
float deltaTime = 0.016f; // 60 FPS
// 물리 시뮬레이션
for (int frame = 0; frame < 300; frame++)
{
// 속도 업데이트 (가속도)
VECTOR3 vDeltaV;
Scale(vDeltaV, vGravity, deltaTime);
Add(vVelocity, vVelocity, vDeltaV);
// 위치 업데이트 (속도)
VECTOR3 vDeltaP;
Scale(vDeltaP, vVelocity, deltaTime);
Add(vPosition, vPosition, vDeltaP);
// 지면 충돌 검사
if (vPosition.y <= 0.0f)
{
vPosition.y = 0.0f;
// 반사 (탄성 충돌)
vVelocity.y *= -0.7f; // 70% 반발
// 속도가 너무 작으면 정지
if (fabs(vVelocity.y) < 0.1f)
break;
}
// 렌더링
RenderProjectile(vPosition);
}
}
```
### 예제 3: 카메라 벡터 계산
```cpp
void UpdateCamera()
{
using namespace CrossM::Math;
// 카메라 위치 및 타겟
VECTOR3 vCameraPos = character->GetPosition();
vCameraPos.y += 1.6f; // 눈 높이
VECTOR3 vTarget = enemy->GetPosition();
// Forward 벡터 (카메라 → 타겟)
VECTOR3 vForward;
Subtract(vForward, vTarget, vCameraPos);
Normalize(vForward, vForward);
// Up 벡터 (일반적으로 Y축)
VECTOR3 vUp(0.0f, 1.0f, 0.0f);
// Right 벡터 (Forward × Up)
VECTOR3 vRight;
CrossProduct(vRight, vForward, vUp);
Normalize(vRight, vRight);
// 실제 Up 벡터 재계산 (Right × Forward)
CrossProduct(vUp, vRight, vForward);
// 카메라 매트릭스 구성
camera->SetOrientation(vRight, vUp, vForward);
camera->SetPosition(vCameraPos);
}
```
---
## 게임과의 통합
### RiskYourLife에서의 사용
#### 1. 지형 충돌
**위치**: `Client/Client/RYLClient/RYLScene/TerrainManager.cpp`
```cpp
// 지형 메시 로드 시
void TerrainManager::LoadTerrain(const char* filename)
{
// ... 메시 로드 ...
// CrossM Octree Collider 초기화
m_pCollider = new CrossM::Scene::COctreeCollider();
// 지형 삼각형 추출
ExtractCollisionTriangles(m_pCollider);
// Octree 구축
m_pCollider->BuildOctree(6, 10);
}
// 캐릭터 이동 시 충돌 검사
bool TerrainManager::CheckCollision(
const vector3& vStart,
const vector3& vEnd,
vector3& vOutPos)
{
using namespace CrossM::Math;
// vector3 → VECTOR3 변환
VECTOR3 vS(vStart.x, vStart.y, vStart.z);
VECTOR3 vE(vEnd.x, vEnd.y, vEnd.z);
VECTOR3 vRadius(0.5f, 1.8f, 0.5f);
VECTOR3 vResult;
// 충돌 검사
bool bCollided = m_pCollider->CheckCollision(
vS, vE, vRadius, vResult, true
);
// VECTOR3 → vector3 변환
vOutPos.x = vResult.x;
vOutPos.y = vResult.y;
vOutPos.z = vResult.z;
return bCollided;
}
```
#### 2. 캐릭터 이동
**위치**: `Client/Client/RYLClient/Character/CharacterController.cpp`
```cpp
void CharacterController::Move(float deltaTime)
{
// 입력에서 이동 벡터 계산
vector3 vMovement = CalculateMovementFromInput();
// 현재 위치
vector3 vCurrentPos = m_pCharacter->GetPosition();
// 목표 위치
vector3 vTargetPos = vCurrentPos + vMovement * deltaTime;
// 지형 충돌 검사 (CrossM 사용)
vector3 vFinalPos;
bool bCollided = TerrainManager::Instance().CheckCollision(
vCurrentPos,
vTargetPos,
vFinalPos
);
// 최종 위치 적용
m_pCharacter->SetPosition(vFinalPos);
// 슬라이딩 피드백
if (bCollided)
{
// 벽에 부딪혔을 때 효과
PlaySoundEffect("wall_hit.wav");
}
}
```
#### 3. 발사체 충돌
**위치**: `Client/Client/RYLClient/Skill/ProjectileManager.cpp`
```cpp
void Projectile::Update(float deltaTime)
{
using namespace CrossM::Math;
// 현재 위치
VECTOR3 vStart(m_position.x, m_position.y, m_position.z);
// 다음 위치 계산
VECTOR3 vVelocity(m_velocity.x, m_velocity.y, m_velocity.z);
VECTOR3 vDelta;
Scale(vDelta, vVelocity, deltaTime);
VECTOR3 vEnd;
Add(vEnd, vStart, vDelta);
// 충돌 검사 (작은 Ellipsoid)
VECTOR3 vRadius(0.1f, 0.1f, 0.1f);
VECTOR3 vResult;
bool bHit = g_pTerrainCollider->CheckCollision(
vStart, vEnd, vRadius, vResult, false
);
if (bHit)
{
// 충돌 처리
OnHit(VECTOR3(vResult.x, vResult.y, vResult.z));
Destroy();
}
else
{
// 위치 업데이트
m_position.x = vResult.x;
m_position.y = vResult.y;
m_position.z = vResult.z;
}
}
```
---
## 성능 최적화
### Octree 파라미터 튜닝
```cpp
// 작은 맵 (실내)
collider->BuildOctree(
4, // 깊이 4 (16개 노드)
20 // 노드당 20 폴리곤
);
// 중간 맵 (필드)
collider->BuildOctree(
6, // 깊이 6 (64개 노드)
10 // 노드당 10 폴리곤
);
// 큰 맵 (오픈 월드)
collider->BuildOctree(
8, // 깊이 8 (256개 노드)
5 // 노드당 5 폴리곤
);
```
### 충돌 검사 최적화
```cpp
// 1. Swept Volume으로 후보 필터링
std::vector<COctreeCollisionNode*> candidates;
m_RootNode.CollectCollidableNodes(
vSweptMin,
vSweptMax,
candidates
);
// 2. 후보 노드의 삼각형만 검사
for (auto* pNode : candidates)
{
for (size_t idx : pNode->m_vecTriangleIndex)
{
CheckTriangleCollision(m_pTriangleData[idx]);
}
}
```
---
## 디버그 및 시각화
### Octree 시각화
```cpp
// 디버그 렌더링
void RenderDebugInfo()
{
if (g_bShowOctree)
{
// Octree 구조 그리기 (깊이 3까지)
g_pTerrainCollider->DrawOctree(
g_pd3dDevice,
3 // 렌더링할 깊이
);
}
}
// DrawOctree 내부 (DX9)
void COctreeCollider::DrawOctree(IDirect3DDevice9* pDevice, int nDrawDepth)
{
// 재귀적으로 노드 그리기
DrawOctreeNode(&m_RootNode, pDevice, 0, nDrawDepth);
}
void DrawOctreeNode(COctreeCollisionNode* pNode,
IDirect3DDevice9* pDevice,
int currentDepth,
int maxDepth)
{
if (!pNode || currentDepth > maxDepth)
return;
// AABB 그리기 (12개 선분)
DrawAABB(pDevice, pNode->m_vBoundingMin, pNode->m_vBoundingMax);
// 자식 노드 그리기
if (!pNode->IsLeafNode())
{
for (int i = 0; i < 8; i++)
{
if (pNode->m_apSubNode[i])
{
DrawOctreeNode(
pNode->m_apSubNode[i],
pDevice,
currentDepth + 1,
maxDepth
);
}
}
}
}
```
---
## 정리
### CrossM의 역할
1. **수학 라이브러리**
- 3D 벡터 연산
- 기하학적 계산
- DirectX와 독립적
2. **충돌 감지 시스템**
- Octree 공간 분할
- Ellipsoid vs Triangle
- 슬라이딩 응답
3. **게임 물리 기반**
- 캐릭터 이동
- 지형 충돌
- 발사체 추적
### 장점
**빠른 충돌 검사** - Octree로 O(log N)
**정확한 응답** - Swept Ellipsoid
**슬라이딩 지원** - 자연스러운 벽 이동
**독립적 설계** - 다른 엔진에도 재사용 가능
**헤더 전용** - 인라인 함수로 성능 최적화
### 개선 가능 영역
⚠️ **멀티스레드 미지원** - 단일 스레드 충돌 검사
⚠️ **동적 오브젝트** - Octree 재구축 필요
⚠️ **메모리 사용** - 큰 맵에서 메모리 많이 사용
⚠️ **DX9 의존성** - DrawOctree는 DX9 전용
---
**작성일**: 2025-12-01
**버전**: 1.0
**작성자**: Claude AI (Anthropic)
**프로젝트**: RiskYourLife CrossM Library Analysis