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:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -0,0 +1,419 @@
#include "../Include/MathUtil.h"
#include <algorithm>
namespace CrossM{
namespace Math{
// <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> AABB <20>ȿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǴ<D4B5><C7B4><EFBFBD> <20>˻<EFBFBD>
bool IsTriangleInAabb(const VECTOR3& vAabbMin, const VECTOR3& vAabbMax, const VECTOR3& vTri0, const VECTOR3& vTri1, const VECTOR3& vTri2)
{
if (vAabbMin.x <= vTri0.x && vTri0.x <= vAabbMax.x &&
vAabbMin.y <= vTri0.y && vTri0.y <= vAabbMax.y &&
vAabbMin.z <= vTri0.z && vTri0.z <= vAabbMax.z &&
vAabbMin.x <= vTri1.x && vTri1.x <= vAabbMax.x &&
vAabbMin.y <= vTri1.y && vTri1.y <= vAabbMax.y &&
vAabbMin.z <= vTri1.z && vTri1.z <= vAabbMax.z &&
vAabbMin.x <= vTri2.x && vTri2.x <= vAabbMax.x &&
vAabbMin.y <= vTri2.y && vTri2.y <= vAabbMax.y &&
vAabbMin.z <= vTri2.z && vTri2.z <= vAabbMax.z)
{
return true;
}
return false;
}
// <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> AABB <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˻<EFBFBD>
bool CheckAabbTriangleIntersection(const VECTOR3& vAabbMin, const VECTOR3& vAabbMax, const VECTOR3& vTri0, const VECTOR3& vTri1, const VECTOR3& vTri2)
{
// Separation of Axes <20><> <20><><EFBFBD><EFBFBD> AABB - triangle intersection test <20><><EFBFBD><EFBFBD>
// 6 <20><20><><EFBFBD><EFBFBD> AABB <20><> <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> projection <20><> <20><>, <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD> <20><><EFBFBD>θ<EFBFBD> Ȯ<><C8AE><EFBFBD>Ѵ<EFBFBD>
// <20><><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>°<EFBFBD><C2B0>̰<EFBFBD>, <20><> <20><20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20>ʴ´ٸ<C2B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD>̴<EFBFBD>
float fBoxProjectionMin, fBoxProjectionMax;
float fTriProjectionMin, fTriProjectionMax;
// AABB <20><> <20><> <20><20><><EFBFBD><EFBFBD> projection <20><> <20>˻<EFBFBD>
// X <20><>
fBoxProjectionMin = vAabbMin.x;
fBoxProjectionMax = vAabbMax.x;
fTriProjectionMin = std::min(vTri0.x, std::min(vTri1.x, vTri2.x));
fTriProjectionMax = std::max(vTri0.x, std::max(vTri1.x, vTri2.x));
if (false == IsRangeOverlap(fTriProjectionMin, fTriProjectionMax, fBoxProjectionMin, fBoxProjectionMax))
{
return false;
}
// Y <20><>
fBoxProjectionMin = vAabbMin.y;
fBoxProjectionMax = vAabbMax.y;
fTriProjectionMin = std::min(vTri0.y, std::min(vTri1.y, vTri2.y));
fTriProjectionMax = std::max(vTri0.y, std::max(vTri1.y, vTri2.y));
if (false == IsRangeOverlap(fTriProjectionMin, fTriProjectionMax, fBoxProjectionMin, fBoxProjectionMax))
{
return false;
}
// Z <20><>
fBoxProjectionMin = vAabbMin.z;
fBoxProjectionMax = vAabbMax.z;
fTriProjectionMin = std::min(vTri0.z, std::min(vTri1.z, vTri2.z));
fTriProjectionMax = std::max(vTri0.z, std::max(vTri1.z, vTri2.z));
if (false == IsRangeOverlap(fTriProjectionMin, fTriProjectionMax, fBoxProjectionMin, fBoxProjectionMax))
{
return false;
}
// <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><> <20><> <20><20><><EFBFBD><EFBFBD> projection <20><> <20>˻<EFBFBD>
VECTOR3 avAxis[3]; // <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><> <20>𼭸<EFBFBD>
Math::Subtract(avAxis[0], vTri1, vTri0);
Math::Subtract(avAxis[1], vTri2, vTri0);
Math::Subtract(avAxis[2], vTri2, vTri1);
// <20><EFBFBD><EFB0A2> <20><> <20><><EFBFBD><EFBFBD> <20>࿡ projection <20><> <20><>
float fProjectionTri0, fProjectionTri1, fProjectionTri2;
for (int i = 0; i < 3; ++i)
{
VECTOR3& vAxis = avAxis[i];
// AABB <20><> max/min <20><><EFBFBD><EFBFBD> xyz <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD>/<2F>ּҰ<D6BC><D2B0>̹Ƿ<CCB9>,
// axis <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ밪<D6B4><EBB0AA> <20><><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>
// x,y,z <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ū <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ϸ<EFBFBD> <20>ȴ<EFBFBD>.
// (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> AABB <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> xyz <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD>/<2F>ּҰ<D6BC><D2B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̹Ƿ<CCB9>,
// x,y,z <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ƿ<EFBFBD> <20>ִ<EFBFBD>/<2F>ּҸ<D6BC> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD> <20>ص<EFBFBD> <20><><EFBFBD>h <20><> <20>ȿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǴ<D4B5> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.)
fBoxProjectionMin =
((vAxis.x > 0) ? vAabbMin.x : vAabbMax.x) * vAxis.x +
((vAxis.y > 0) ? vAabbMin.y : vAabbMax.y) * vAxis.y +
((vAxis.z > 0) ? vAabbMin.z : vAabbMax.z) * vAxis.z;
fBoxProjectionMax =
((vAxis.x > 0) ? vAabbMax.x : vAabbMin.x) * vAxis.x +
((vAxis.y > 0) ? vAabbMax.y : vAabbMin.y) * vAxis.y +
((vAxis.z > 0) ? vAabbMax.z : vAabbMin.z) * vAxis.z;
fProjectionTri0 = Math::DotProduct(vTri0, vAxis);
fProjectionTri1 = Math::DotProduct(vTri1, vAxis);
fProjectionTri2 = Math::DotProduct(vTri2, vAxis);
fTriProjectionMin = std::min(fProjectionTri0, std::min(fProjectionTri1, fProjectionTri2));
fTriProjectionMax = std::max(fProjectionTri0, std::max(fProjectionTri1, fProjectionTri2));
if (false == IsRangeOverlap(fTriProjectionMin, fTriProjectionMax, fBoxProjectionMin, fBoxProjectionMax))
{
return false;
}
}
return true;
}
// <20><> AABB <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˻<EFBFBD>
bool CheckAabbAabbIntersection(const VECTOR3& vAabb1Min, const VECTOR3& vAabb1Max, const VECTOR3& vAabb2Min, const VECTOR3& vAabb2Max)
{
if (false ==IsRangeOverlap(vAabb1Min.x, vAabb1Max.x, vAabb2Min.x, vAabb2Max.x)) return false;
if (false ==IsRangeOverlap(vAabb1Min.y, vAabb1Max.y, vAabb2Min.y, vAabb2Max.y)) return false;
if (false ==IsRangeOverlap(vAabb1Min.z, vAabb1Max.z, vAabb2Min.z, vAabb2Max.z)) return false;
return true;
}
// CheckTriangleSweepingSphereCollision <20><> <20>μ<EFBFBD> <20>Լ<EFBFBD>.
// ax^2 + bx + c <20><> <20><> <20><> min~max <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ظ<EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>ذ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> false <20><>ȯ
static bool GetLowestRootInRange(const float a, const float b, const float c, const float fMinRoot, const float fMaxRoot, float& fRoot)
{
// <20>Ǽ<EFBFBD><C7BC>ذ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> <20>Ǻ<EFBFBD><C7BA><EFBFBD> <20><><EFBFBD><EFBFBD>
float fDeterminant = b*b - 4.0f*a*c;
// <20>Ǽ<EFBFBD><C7BC>ذ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
if (fDeterminant < 0.0f) return false;
// <20>ΰ<EFBFBD><CEB0><EFBFBD> <20>ظ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>
float fSqrtD = sqrtf(fDeterminant);
float r1 = (-b - fSqrtD) / (2*a);
float r2 = (-b + fSqrtD) / (2*a);
// r1 < r2 <20><> ũ<><20>ǵ<EFBFBD><C7B5><EFBFBD> <20><><EFBFBD><EFBFBD>
if (r1 > r2) std::swap(r1, r2);
// <20><><EFBFBD><EFBFBD><EFBFBD>ʺ<EFBFBD><CABA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǻ<EFBFBD><C7BA><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD><CFB0><EFBFBD> <20>طμ<D8B7> <20><><EFBFBD><EFBFBD>
if (r1 > fMinRoot && r1 < fMaxRoot)
{
fRoot = r1;
return true;
}
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ū <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˻<EFBFBD><CBBB>Ѵ<EFBFBD>
if (r2 > fMinRoot && r2 < fMaxRoot)
{
fRoot = r2;
return true;
}
return false;
}
bool CheckTriangleSweepingSphereCollision(float &fOutT, VECTOR3& vOutContactPoint, bool& bOutContactInsideTriangle, const TriangSweepingSphere& triAndSphere)
{
// <20><EFBFBD><E0B0A3> alias
const Math::VECTOR3 &vBasePoint = triAndSphere.m_vSphereSweepStart;
const Math::VECTOR3 &vTri0 = triAndSphere.m_vTri0;
const Math::VECTOR3 &vTri1 = triAndSphere.m_vTri1;
const Math::VECTOR3 &vTri2 = triAndSphere.m_vTri2;
const Math::VECTOR3 &vPath = triAndSphere.m_vSphereSweepPath;
// <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><> <20>𼭸<EFBFBD>
Math::VECTOR3 vTriEdge01, vTriEdge02, vTriEdge12;
// <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> plane Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>
Math::VECTOR3 vTriPlaneNormal;
float fTriPlaneConstant;
// <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><> <20>𼭸<EFBFBD> <20><><EFBFBD>͸<EFBFBD> <20><><EFBFBD>ϰ<EFBFBD>..
Math::Subtract(vTriEdge01, vTri1, vTri0);
Math::Subtract(vTriEdge02, vTri2, vTri0);
Math::Subtract(vTriEdge12, vTri2, vTri1);
// <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><><EFBFBD>Ե<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD> <20><><EFBFBD><EFBFBD>
Math::CrossProduct(vTriPlaneNormal, vTriEdge01, vTriEdge02);
Math::Normalize(vTriPlaneNormal, vTriPlaneNormal);
fTriPlaneConstant = -Math::DotProduct(vTriPlaneNormal, vTri0);
// sweeping path <20><> <20><EFBFBD><E6B5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
float fNormalDotPath = Math::DotProduct(vTriPlaneNormal, vPath);
// sphere <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> üũ<C3BC><C5A9><EFBFBD><EFBFBD>
if (fNormalDotPath > 0.0f)
{
return false;
}
float t0, t1;
bool bEmbededInPlane = false;
float fSignedDistBaseToTriPlane = Math::DotProduct(vTriPlaneNormal, vBasePoint) + fTriPlaneConstant;
if (0.0f == fNormalDotPath)
{
// sphere <20><> <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD>
if (fabs(fSignedDistBaseToTriPlane) >= triAndSphere.m_fSphereRadius)
{
return false; // <20><EFBFBD><EFB0A2><EFBFBD><EFBFBD><E9BFA1> <20>ָ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5><EFBFBD>
}
else
{
bEmbededInPlane = true;
t0 = 0.0f;
t1 = 1.0f;
}
}
else
{
t0 = (-triAndSphere.m_fSphereRadius-fSignedDistBaseToTriPlane)/fNormalDotPath;
t1 = (triAndSphere.m_fSphereRadius-fSignedDistBaseToTriPlane)/fNormalDotPath;
// t0 < t1 <20><><EFBFBD><EFBFBD> <20><>Ʈ
if (t0 > t1)
{
std::swap(t0, t1);
}
// t <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> sphere <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ<EFBFBD>
if (t0 > 1.0f || t1 <0.0f)
{
return false;
}
// t <20><><EFBFBD><EFBFBD> 0~1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
t0 = std::max(t0, 0.0f);
t1 = std::min(t1, 1.0f);
}
VECTOR3 vContactPoint;
bool bFoundCollision = false;
float t = 1.0f;
// <20><EFBFBD><EFB0A2> <20><><EFBFBD>ο<EFBFBD> üũ
if (!bEmbededInPlane)
{
vContactPoint = vBasePoint + (vPath*t0) - vTriPlaneNormal;
if (IsPointInTriangle(vContactPoint, vTri0, vTri1, vTri2))
{
bFoundCollision = true;
t = t0;
}
}
// <20><><EFBFBD><EFBFBD> <20><EFBFBD><E6B5B9><EFBFBD><EFBFBD> ã<><C3A3> <20><><EFBFBD>ߴٸ<DFB4> <20>𼭸<EFBFBD><F0BCADB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>׽<EFBFBD>Ʈ<EFBFBD><C6AE> <20>ؾ<EFBFBD><D8BE>Ѵ<EFBFBD>
if (!bFoundCollision)
{
float fSQuaredPathLength = GetSquaredLength(vPath);
float a, b, c;
float newT;
float fSquaredRadius = triAndSphere.m_fSphereRadius*triAndSphere.m_fSphereRadius;
a = fSQuaredPathLength;
// vTri0
b = 2.0f * (DotProduct(vPath, vBasePoint - vTri0));
c = (Math::GetSquaredLength(vTri0 - vBasePoint) - fSquaredRadius);
if (GetLowestRootInRange(a, b, c, 0.0f, t, newT))
{
t = newT;
bFoundCollision = true;
vContactPoint = vTri0;
}
// vTri1
if (bFoundCollision)
{
b = 2.0f * (DotProduct(vPath, vBasePoint - vTri1));
c = (Math::GetSquaredLength(vTri1 - vBasePoint) - fSquaredRadius);
if (GetLowestRootInRange(a, b, c, 0.0f, t, newT))
{
t = newT;
bFoundCollision = true;
vContactPoint = vTri1;
}
}
// vTri2
if (bFoundCollision)
{
b = 2.0f * (DotProduct(vPath, vBasePoint - vTri2));
c = (Math::GetSquaredLength(vTri2 - vBasePoint) - fSquaredRadius);
if (GetLowestRootInRange(a, b, c, 0.0f, t, newT))
{
t = newT;
bFoundCollision = true;
vContactPoint = vTri0;
}
}
// <20>𼭸<EFBFBD><F0BCADB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>׽<EFBFBD>Ʈ
VECTOR3 vBaseToVertex;
float fEdgeSquaredLength;
float fEdgeDotPath;
float fEdgeDotBaseToVertex;
// vTri0 ~ vTri1
vBaseToVertex = vTri0 - vBasePoint;
fEdgeSquaredLength = GetSquaredLength(vTriEdge01);
fEdgeDotPath = DotProduct(vTriEdge01, vPath);
fEdgeDotBaseToVertex = DotProduct(vTriEdge01, vBaseToVertex);
a = fEdgeSquaredLength* -fSQuaredPathLength +
fEdgeDotPath*fEdgeDotPath;
b = fEdgeSquaredLength* (2.0f*Math::DotProduct(vPath, vBaseToVertex)) -
2.0f*fEdgeDotPath*fEdgeDotBaseToVertex;
c = (fEdgeSquaredLength* (1.0f - Math::GetSquaredLength(vBaseToVertex)) +
fEdgeDotBaseToVertex*fEdgeDotBaseToVertex);
if (GetLowestRootInRange(a, b, c, 0.0f, t, newT))
{
float f = (fEdgeDotPath*t - fEdgeDotBaseToVertex) / fEdgeSquaredLength;
if (f >= 0.0f && f <= 1.0f)
{
t = newT;
bFoundCollision = true;
vContactPoint = vTri0 + vTriEdge01*f;
}
}
// vTri0 ~ vTri2
vBaseToVertex = vTri0 - vBasePoint;
fEdgeSquaredLength = GetSquaredLength(vTriEdge02);
fEdgeDotPath = DotProduct(vTriEdge02, vPath);
fEdgeDotBaseToVertex = DotProduct(vTriEdge02, vBaseToVertex);
a = fEdgeSquaredLength* -fSQuaredPathLength +
fEdgeDotPath*fEdgeDotPath;
b = fEdgeSquaredLength* (2.0f*Math::DotProduct(vPath, vBaseToVertex)) -
2.0f*fEdgeDotPath*fEdgeDotBaseToVertex;
c = (fEdgeSquaredLength* (1.0f - Math::GetSquaredLength(vBaseToVertex)) +
fEdgeDotBaseToVertex*fEdgeDotBaseToVertex);
if (GetLowestRootInRange(a, b, c, 0.0f, t, newT))
{
float f = (fEdgeDotPath*t - fEdgeDotBaseToVertex) / fEdgeSquaredLength;
if (f >= 0.0f && f <= 1.0f)
{
t = newT;
bFoundCollision = true;
vContactPoint = vTri0 + vTriEdge02*f;
}
}
// vTri1 ~ vTri2
vBaseToVertex = vTri1 - vBasePoint;
fEdgeSquaredLength = GetSquaredLength(vTriEdge12);
fEdgeDotPath = DotProduct(vTriEdge12, vPath);
fEdgeDotBaseToVertex = DotProduct(vTriEdge12, vBaseToVertex);
a = fEdgeSquaredLength* -fSQuaredPathLength +
fEdgeDotPath*fEdgeDotPath;
b = fEdgeSquaredLength* (2.0f*Math::DotProduct(vPath, vBaseToVertex)) -
2.0f*fEdgeDotPath*fEdgeDotBaseToVertex;
c = (fEdgeSquaredLength* (1.0f - Math::GetSquaredLength(vBaseToVertex)) +
fEdgeDotBaseToVertex*fEdgeDotBaseToVertex);
if (GetLowestRootInRange(a, b, c, 0.0f, t, newT))
{
float f = (fEdgeDotPath*t - fEdgeDotBaseToVertex) / fEdgeSquaredLength;
if (f >= 0.0f && f <= 1.0f)
{
t = newT;
bFoundCollision = true;
vContactPoint = vTri1 + vTriEdge12*f;
}
}
}
if (bFoundCollision)
{
fOutT = t;
vOutContactPoint = vContactPoint;
return true;
}
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><EFB0A2> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǴ<D4B5><C7B4><EFBFBD> Ȯ<><C8AE><EFBFBD>ϴ<EFBFBD> <20>ڵ<EFBFBD>
// Fauerby <20><> <20>ۿ<EFBFBD> Keidy <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ƾ<EFBFBD>̶<EFBFBD><CCB6><EFBFBD> <20>Ѵ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.. <20>𸣰ڴ<F0B8A3B0>-_- <20>ϴ<EFBFBD> <20>̿<EFBFBD>
bool IsPointInTriangle(const VECTOR3& p, const VECTOR3& vTri0, const VECTOR3& vTri1, const VECTOR3& vTri2)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20><EFBFBD><EFB0A2> <20>𼭸<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> p <20><> <20><>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD>
VECTOR3 vEdge1, vEdge2, pTri;
Math::Subtract(vEdge1, vTri1, vTri0);
Math::Subtract(vEdge2, vTri2, vTri0);
Math::Subtract(pTri, p, vTri0);
float a = Math::DotProduct(vEdge1, vEdge1);
float b = Math::DotProduct(vEdge1, vEdge2);
float c = Math::DotProduct(vEdge2, vEdge2);
float d = Math::DotProduct(pTri, vEdge1);
float e = Math::DotProduct(pTri, vEdge2);
float x = d*c - e*b;
float y = e*a - d*b;
float z = x + y - (a*c - b*b);
return ( ((unsigned int&)z) & ~ ( ((unsigned int&)x) | ((unsigned int&)y) ) & 0x80000000) != 0 ? true : false;
}
}}