Files
Client/Engine/CrossM/Include/OctreeCollider.h
LGram16 e067522598 Initial commit: ROW Client source code
Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:24:34 +09:00

137 lines
3.7 KiB
C++

/*
Collision detection + response 를 처리하는 클래스
충돌 삼각형의 culling 은 octree 를 이용
collision detection 과 response 알고리즘은 Kasper Fauerby 의
'Improved Collision detection and Response' 에 기초하는 코드이다
*/
#pragma once
#include "./Vector3.h"
#include <vector>
// forward decl.
struct IDirect3DDevice8;
namespace CrossM{
namespace Scene{
struct CollisionTriangleInfo
{
Math::VECTOR3 m_avVertex[3];
// 부가적 정보..이를테면 이 삼각형이 속한 오브젝트의 id 라던가. 그런것이 필요할듯
// 오브젝트 클래스(지형/하우스/오브젝트)+한 클래스 내에서의 오브젝트ID(각 하우스별 고유번호)
// 같은 식의 자료형이 될지도?
Math::VECTOR3 m_vFaceNormal;
};
// octree 의 node. 리프 노드뿐 아니라 줄기 노드도 삼각형의 인덱스를 가질 수 있다.
// 바운딩 박스 내에 삼각형의 세 점이 완전히 포함되는 삼각형만 그 노드의 삼각형 인덱스 리스트에 기록된다.
// (경계에 걸치는 그 삼각형의 세 점을 다 포함하는 상위 노드에 기록됨)
class COctreeCollisionNode
{
public:
COctreeCollisionNode();
~COctreeCollisionNode();
// 현 노드의 하위 노드들을 재귀적으로 모두 해제
void ReleaseSubNode();
// leaf node 인지 체크
bool IsLeafNode();
// 자식 노드들을 생성하고, 자신의 노드에 포함된 삼각형의 인덱스들을 자식 노드로 분산시킨다.
// 자기 자신의 노드에는 바운딩박스 값이 세팅된 상태여야 한다.
void BuildSubNode(
const std::vector< CollisionTriangleInfo >& vecTriangle,
const size_t nMaximumRecursion, const size_t nMinPolyCount,
size_t nCurrentRecursionLevel);
// 충돌 객체의 swept volume 에 걸리는 충돌 노드들의 리스트를 vecCollidableNode 에 저장
void CollectCollidableNodes(
const Math::VECTOR3& vSweptVolumeMin, const Math::VECTOR3& vSweptVolumeMax,
std::vector< COctreeCollisionNode* >& vecCollidableNode);
Math::VECTOR3 m_vBoundingMin;
Math::VECTOR3 m_vBoundingMax;
std::vector< size_t > m_vecTriangleIndex;
COctreeCollisionNode* m_apSubNode[8];
};
class COctreeCollider
{
public:
COctreeCollider();
~COctreeCollider();
//////////////////////////////////////////////////////////////////////////
//
// Octree Build 관련 메소드
/*
충돌 삼각형 갯수를 설정.
충돌 삼각형이 내부적으로 저장될 공간이 할당되고, octree 정보가 파괴된다.
BuildOctree() 가 호출되기 전까지 COctreeCollider 는 정상작동하지 않는다
*/
void SetTriangleCount(unsigned int uiTriangleCount);
/*
삼각형 데이터 저장소의 포인터를 반환.
이 메소드를 호출하면 삼각형 데이터가 변형된것으로 간주, octree 정보가 파괴된다.
BuildOctree() 가 호출되기 전까지 COctreeCollider 는 정상작동하지 않는다
*/
void GetTriangleDataPtr(CollisionTriangleInfo*& pTriangleData);
// 세팅된 삼각형 정보를 기초로 octree 정보를 구축
bool BuildOctree(const size_t nMaximumRecursion, const size_t nMinPolyCount);
//////////////////////////////////////////////////////////////////////////
//
// 충돌검출 및 반응 메소드
/*
주어진 타원체의 이전 위치(prevPos)와 이동할 위치(nextPos) 를 파라미터로 넘기면,
충돌을 체크하고 충돌이 일어났을 경우 적절한 위치로 수정된 이동 위치를 반환한다.
*/
void GetCollisionRespondingPosition(
Math::VECTOR3& vRespondingPos,
const Math::VECTOR3& vPrevPos, const Math::VECTOR3& vNewPos,
const Math::VECTOR3& vEllipsoidRadius,
const unsigned int nRecursionLevel = 1);
// 테스트용 메소드, 충돌이 일어날 수 있는것으로 확인된 노드의 삼각형들을 렌더
void RenderCollidableNodeTriangles(IDirect3DDevice8* pDevice);
private:
std::vector< CollisionTriangleInfo > m_vecCollisionTriangle;
Math::VECTOR3 m_vCollisionBoundingMin;
Math::VECTOR3 m_vCollisionBoundingMax;
COctreeCollisionNode m_octreeRootNode;
// 임시용, 충돌이 일어날 수 있는것으로 확인된 leaf 노드들
std::vector< COctreeCollisionNode* > m_vecpCollidableNode;
// 임시용, 렌더용 버텍스 데이터
std::vector< Math::VECTOR3 > m_vecRenderVertex;
// 임시용. 충돌이 일어난 삼각형의 인덱스
size_t m_nColTriIndex;
};
}}