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>
This commit is contained in:
36
Engine/CrossM/Include/CollisionEllipsoidHelper.h
Normal file
36
Engine/CrossM/Include/CollisionEllipsoidHelper.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "./Vector3.h"
|
||||
|
||||
|
||||
namespace CrossM{
|
||||
namespace Scene{
|
||||
|
||||
class CCollisionEllipsoidHelper{
|
||||
|
||||
public:
|
||||
CCollisionEllipsoidHelper();
|
||||
~CCollisionEllipsoidHelper();
|
||||
|
||||
void SetEllipsoidRadius(const Math::VECTOR3& vRadius);
|
||||
void SetHeightBias(float f);
|
||||
|
||||
// height bias 가 세팅된 후, 위치 설정은 아래 둘 중 아무것으로나 할 수 있다
|
||||
void SetEllipsoidCenter(const Math::VECTOR3& vCenter);
|
||||
void SetPosition(const Math::VECTOR3& vPos);
|
||||
|
||||
const Math::VECTOR3& GetEllipsoidRadius();
|
||||
const Math::VECTOR3& GetEllipsoidCenter();
|
||||
Math::VECTOR3 GetPosition(); // client 에서 이용하는 실제 위치
|
||||
|
||||
|
||||
private:
|
||||
// 충돌 타원체의 중심과 반지름벡터
|
||||
Math::VECTOR3 m_vEllipoidCenter;
|
||||
Math::VECTOR3 m_vEllipsoidRaius;
|
||||
|
||||
// client 측에서 이용하는 충돌점의 실제 타원체 중심 기준 높이 bias값
|
||||
float m_fHeightBias;
|
||||
};
|
||||
|
||||
}}
|
||||
9
Engine/CrossM/Include/MathConst.h
Normal file
9
Engine/CrossM/Include/MathConst.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
namespace CrossM{
|
||||
namespace Math{
|
||||
|
||||
const float F_EPSILON = 1.0e-5f;
|
||||
const float F_PI = 3.1415926535f;
|
||||
|
||||
}}
|
||||
84
Engine/CrossM/Include/MathUtil.h
Normal file
84
Engine/CrossM/Include/MathUtil.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "./MathConst.h"
|
||||
#include "./Vector3.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace CrossM{
|
||||
namespace Math{
|
||||
|
||||
|
||||
inline bool IsEquivalent(const float f1, const float f2, const float fEpsilon = F_EPSILON)
|
||||
{
|
||||
float d = f1 - f2;
|
||||
return (d < fEpsilon && d > -fEpsilon);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
점 v 가 boxMin, boxMax 를 최소/최대 점으로 가지는 AABB 에 포함되는지 여부를 체크
|
||||
|
||||
포함될 경우 true, 그렇지 않을 경우 false 반환
|
||||
*/
|
||||
inline bool IsPointInAABB(const VECTOR3& vPoint, const VECTOR3& vAABBMin , const VECTOR3& vAABBMax)
|
||||
{
|
||||
if (vAABBMin.x <= vPoint.x && vPoint.x < vAABBMax.x &&
|
||||
vAABBMin.y <= vPoint.y && vPoint.y < vAABBMax.y &&
|
||||
vAABBMin.z <= vPoint.z && vPoint.z < vAABBMax.z)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
f1Min ~ f1Max 구간과 f2Min ~ f2Max 구간이 겹치는지 체크
|
||||
단, 반드시 f1Min <= f1Max, f2Min <= f2Max 여야 한다
|
||||
*/
|
||||
inline bool IsRangeOverlap(float f1Min, float f1Max, float f2Min, float f2Max)
|
||||
{
|
||||
if (f1Min <= f2Max && f2Min <= f1Max)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 삼각형이 AABB 안에 완전히 포함되는지 여부를 확인
|
||||
bool IsTriangleInAabb(const VECTOR3& vAabbMin, const VECTOR3& vAabbMax, const VECTOR3& vTri0, const VECTOR3& vTri1, const VECTOR3& vTri2);
|
||||
|
||||
// AABB 와 삼각형의 intersection 테스트
|
||||
bool CheckAabbTriangleIntersection(const VECTOR3& vAabbMin, const VECTOR3& vAabbMax, const VECTOR3& vTri0, const VECTOR3& vTri1, const VECTOR3& vTri2);
|
||||
|
||||
// AABB 와 AABB 의 intersection 테스트
|
||||
bool CheckAabbAabbIntersection(const VECTOR3& vAabb1Min, const VECTOR3& vAabb1Max, const VECTOR3& vAabb2Min, const VECTOR3& vAabb2Max);
|
||||
|
||||
// 삼각형/Sweeping Sphere 테스트를 위한 파라미터 구조체
|
||||
struct TriangSweepingSphere
|
||||
{
|
||||
Math::VECTOR3 m_vTri0;
|
||||
Math::VECTOR3 m_vTri1;
|
||||
Math::VECTOR3 m_vTri2;
|
||||
|
||||
Math::VECTOR3 m_vSphereSweepStart;
|
||||
Math::VECTOR3 m_vSphereSweepPath;
|
||||
float m_fSphereRadius;
|
||||
};
|
||||
|
||||
// 삼각형과 sweeping sphere 의 충돌 테스트. 충돌일 경우 충돌이 일어난 지점도 반환한다
|
||||
bool CheckTriangleSweepingSphereCollision(float &fOutT, VECTOR3& vOutContactPoint, bool& bOutContactInsideTriangle, const TriangSweepingSphere& triAndSphere);
|
||||
|
||||
// 삼각형 내에 점이 포함되어있는지 확인
|
||||
bool IsPointInTriangle(const VECTOR3& vPoint, const VECTOR3& vTri0, const VECTOR3& vTri1, const VECTOR3& vTri2);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
||||
// 임시용 vector3 계열간 컨버전 함수
|
||||
template<class _T>
|
||||
void ConvVector3(CrossM::Math::VECTOR3& v, const _T& vOld)
|
||||
{
|
||||
v.SetValue(vOld.x, vOld.y, vOld.z);
|
||||
}
|
||||
137
Engine/CrossM/Include/OctreeCollider.h
Normal file
137
Engine/CrossM/Include/OctreeCollider.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
216
Engine/CrossM/Include/Vector3.h
Normal file
216
Engine/CrossM/Include/Vector3.h
Normal file
@@ -0,0 +1,216 @@
|
||||
#pragma once
|
||||
|
||||
#include "./MathConst.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace CrossM{
|
||||
namespace Math{
|
||||
|
||||
struct VECTOR3
|
||||
{
|
||||
VECTOR3() {}
|
||||
~VECTOR3() {}
|
||||
|
||||
VECTOR3(const float _x, const float _y, const float _z) : x(_x), y(_y), z(_z) {}
|
||||
|
||||
VECTOR3(const VECTOR3& v) : x(v.x), y(v.y), z(v.z) {}
|
||||
|
||||
void SetValue(const float _x, const float _y, const float _z)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
}
|
||||
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline VECTOR3& SetZeroVector(VECTOR3& v)
|
||||
{
|
||||
v.x = v.y = v.z = 0.0f;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
// 벡터에 값을 설정
|
||||
inline VECTOR3& SetValue(VECTOR3& vOut, const float x, const float y, const float z)
|
||||
{
|
||||
vOut.x = x;
|
||||
vOut.y = y;
|
||||
vOut.z = z;
|
||||
|
||||
return vOut;
|
||||
}
|
||||
|
||||
// 벡터 길이를 구함
|
||||
inline float GetLength(const VECTOR3& v)
|
||||
{
|
||||
return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
|
||||
}
|
||||
|
||||
// 벡터 길이의 제곱을 구함
|
||||
inline float GetSquaredLength(const VECTOR3& v)
|
||||
{
|
||||
return v.x*v.x + v.y*v.y + v.z*v.z;
|
||||
}
|
||||
|
||||
// Normalize
|
||||
inline VECTOR3& Normalize(VECTOR3& vOut, const VECTOR3& vIn)
|
||||
{
|
||||
float fLen = GetLength(vIn);
|
||||
if (fLen < F_EPSILON)
|
||||
{
|
||||
// 벡터의 길이가 0에 가까울 경우 법선벡터는 x축방향벡터
|
||||
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;
|
||||
}
|
||||
|
||||
// vOut = -vIn;
|
||||
inline VECTOR3& Negate(VECTOR3& vOut, const VECTOR3& vIn)
|
||||
{
|
||||
vOut.x = -vIn.x;
|
||||
vOut.y = -vIn.y;
|
||||
vOut.z = -vIn.z;
|
||||
|
||||
return vOut;
|
||||
}
|
||||
|
||||
// vOut = fScale x vIn
|
||||
inline VECTOR3& Scale(VECTOR3& vOut, const VECTOR3& vIn, const float fScale)
|
||||
{
|
||||
vOut.x = vIn.x * fScale;
|
||||
vOut.y = vIn.y * fScale;
|
||||
vOut.z = vIn.z * fScale;
|
||||
|
||||
return vOut;
|
||||
}
|
||||
|
||||
// vOut = v1 + v2
|
||||
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;
|
||||
}
|
||||
|
||||
// vOut = v1 - v2
|
||||
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;
|
||||
}
|
||||
|
||||
// v1 과 v2 의 내적.
|
||||
inline float DotProduct(const VECTOR3& v1, const VECTOR3& v2)
|
||||
{
|
||||
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
|
||||
}
|
||||
|
||||
// v1 과 v2 의 외적. vOut = v1 x v2
|
||||
inline VECTOR3& CrossProduct(VECTOR3& vOut, const VECTOR3& v1, const VECTOR3& v2)
|
||||
{
|
||||
VECTOR3 vTmp; // vOut 이 v1 이나 v2 와 같을 경우 연산 문제를 방지하기 위한 임시변수
|
||||
|
||||
vTmp.x = v1.y*v2.z - v1.z*v2.y;
|
||||
vTmp.y = v1.z*v2.x - v1.x*v2.z;
|
||||
vTmp.z = v1.x*v2.y - v1.y*v2.x;
|
||||
|
||||
vOut = vTmp;
|
||||
|
||||
return vOut;
|
||||
}
|
||||
|
||||
// v1 에서 v2 로 비율 f만큼 선형으로 변화한 벡터를 구함(선형보간)
|
||||
inline VECTOR3& Lerp(VECTOR3& vOut, const VECTOR3& v1, const VECTOR3& v2, const float f)
|
||||
{
|
||||
float fRem = 1.0f - f;
|
||||
vOut.x = v1.x*fRem + v2.x*f;
|
||||
vOut.y = v1.y*fRem + v2.y*f;
|
||||
vOut.z = v1.z*fRem + v2.z*f;
|
||||
|
||||
return vOut;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 단항 - 연산자
|
||||
inline VECTOR3 operator - (const VECTOR3& v)
|
||||
{
|
||||
VECTOR3 vRet;
|
||||
|
||||
return Negate(vRet, v);
|
||||
}
|
||||
|
||||
// 벡터합
|
||||
inline VECTOR3 operator + (const VECTOR3& v1, const VECTOR3& v2)
|
||||
{
|
||||
VECTOR3 vRet;
|
||||
|
||||
return Add(vRet, v1, v2);
|
||||
}
|
||||
|
||||
// 벡터차
|
||||
inline VECTOR3 operator - (const VECTOR3& v1, const VECTOR3& v2)
|
||||
{
|
||||
VECTOR3 vRet;
|
||||
|
||||
return Subtract(vRet, v1, v2);
|
||||
}
|
||||
|
||||
// 벡터 스칼라배(상수먼저)
|
||||
inline VECTOR3 operator * (const float f, const VECTOR3& v)
|
||||
{
|
||||
VECTOR3 vRet;
|
||||
|
||||
return Scale(vRet, v, f);
|
||||
}
|
||||
|
||||
// 벡터 스칼라배(벡터먼저)
|
||||
inline VECTOR3 operator * (const VECTOR3& v, const float f)
|
||||
{
|
||||
VECTOR3 vRet;
|
||||
|
||||
return Scale(vRet, v, f);
|
||||
}
|
||||
|
||||
// 벡터 스칼라배(상수로 나눔)
|
||||
inline VECTOR3 operator / (const VECTOR3& v, const float& f)
|
||||
{
|
||||
VECTOR3 vRet;
|
||||
|
||||
return Scale(vRet, v, 1.0f/f);
|
||||
}
|
||||
|
||||
// 벡터 내적
|
||||
inline float operator * (const VECTOR3& v1, const VECTOR3& v2)
|
||||
{
|
||||
return DotProduct(v1, v2);
|
||||
}
|
||||
|
||||
// 벡터 외적
|
||||
inline VECTOR3 operator ^ (const VECTOR3& v1, const VECTOR3& v2)
|
||||
{
|
||||
VECTOR3 vRet;
|
||||
|
||||
return CrossProduct(vRet, v1, v2);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
Reference in New Issue
Block a user