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:
541
Engine/CrossM/Src/OctreeCollider.cpp
Normal file
541
Engine/CrossM/Src/OctreeCollider.cpp
Normal file
@@ -0,0 +1,541 @@
|
||||
#include "../Include/OctreeCollider.h"
|
||||
#include "../Include/MathUtil.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d8.h>
|
||||
#include <d3dx8.h>
|
||||
|
||||
|
||||
namespace CrossM{
|
||||
namespace Scene{
|
||||
|
||||
|
||||
|
||||
COctreeCollisionNode::COctreeCollisionNode()
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
m_apSubNode[i] = NULL;
|
||||
}
|
||||
|
||||
m_vBoundingMin.SetValue(0,0,0);
|
||||
m_vBoundingMax.SetValue(0,0,0);
|
||||
}
|
||||
|
||||
COctreeCollisionNode::~COctreeCollisionNode()
|
||||
{
|
||||
ReleaseSubNode();
|
||||
}
|
||||
|
||||
void COctreeCollisionNode::ReleaseSubNode()
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
if (NULL != m_apSubNode[i])
|
||||
{
|
||||
delete m_apSubNode[i];
|
||||
m_apSubNode[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20>ڽij<DABD><C4B3>尡 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
bool COctreeCollisionNode::IsLeafNode()
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
if (NULL != m_apSubNode[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void COctreeCollisionNode::BuildSubNode(
|
||||
const std::vector< CollisionTriangleInfo >& vecTriangle,
|
||||
const size_t nMaximumRecursion, const size_t nMinPolyCount,
|
||||
size_t nCurrentRecursionLevel)
|
||||
{
|
||||
static size_t nProcessedTri = 0;
|
||||
|
||||
unsigned int i, j;
|
||||
|
||||
// recursion level <20><> <20>ʹ<EFBFBD> <20><><EFBFBD>ų<EFBFBD>, <20><><EFBFBD>Ե<EFBFBD> face <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD>̻<EFBFBD> sub node <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4> (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||||
if (nCurrentRecursionLevel >= nMaximumRecursion ||
|
||||
m_vecTriangleIndex.size() <= nMinPolyCount)
|
||||
{
|
||||
nProcessedTri += m_vecTriangleIndex.size();
|
||||
printf("\r%d / %d", nProcessedTri, vecTriangle.size());
|
||||
return;
|
||||
}
|
||||
|
||||
// <20>ڽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bounding box min/max
|
||||
Math::VECTOR3 aSubNodeBoundingMin[8];
|
||||
Math::VECTOR3 aSubNodeBoundingMax[8];
|
||||
|
||||
Math::VECTOR3 vMedian = (m_vBoundingMin + m_vBoundingMax)/2.0f;
|
||||
|
||||
// <20>ٿ<EFBFBD><D9BF><EFBFBD> <20>ڽ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
if (0 == (i & 1))
|
||||
{
|
||||
aSubNodeBoundingMin[i].x = m_vBoundingMin.x;
|
||||
aSubNodeBoundingMax[i].x = vMedian.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
aSubNodeBoundingMin[i].x = vMedian.x;
|
||||
aSubNodeBoundingMax[i].x = m_vBoundingMax.x;
|
||||
}
|
||||
if (0 == (i & 2))
|
||||
{
|
||||
aSubNodeBoundingMin[i].y = m_vBoundingMin.y;
|
||||
aSubNodeBoundingMax[i].y = vMedian.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
aSubNodeBoundingMin[i].y = vMedian.y;
|
||||
aSubNodeBoundingMax[i].y = m_vBoundingMax.y;
|
||||
}
|
||||
if (0 == (i & 4))
|
||||
{
|
||||
aSubNodeBoundingMin[i].z = m_vBoundingMin.z;
|
||||
aSubNodeBoundingMax[i].z = vMedian.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
aSubNodeBoundingMin[i].z = vMedian.z;
|
||||
aSubNodeBoundingMax[i].z = m_vBoundingMax.z;
|
||||
}
|
||||
}
|
||||
|
||||
// <20>Ѱܹ<D1B0><DCB9><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ϻ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD> <20><> <20><><EFBFBD>忡 <20><><EFBFBD><EFBFBD><EFBFBD>ɰ͵<C9B0><CDB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>س<EFBFBD><D8B3><EFBFBD>
|
||||
for (j = 0; j < m_vecTriangleIndex.size(); ++j)
|
||||
{
|
||||
// <20>ﰢ<EFBFBD><EFB0A2> <20><> <20><> <20><><EFBFBD><EFBFBD>
|
||||
const CollisionTriangleInfo &tri = vecTriangle[ m_vecTriangleIndex[j] ];
|
||||
const Math::VECTOR3 &vTri0 = tri.m_avVertex[0];
|
||||
const Math::VECTOR3 &vTri1 = tri.m_avVertex[1];
|
||||
const Math::VECTOR3 &vTri2 = tri.m_avVertex[2];
|
||||
|
||||
// <20><> <20>ڽij<DABD><C4B3><EFBFBD><EFBFBD>鿡 <20><><EFBFBD><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǴ<D4B5><C7B4><EFBFBD> üũ<C3BC>Ѵ<EFBFBD>
|
||||
bool bIncludedInSubNode = false; // <20>ڽ<EFBFBD> <20><><EFBFBD>忡 <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǴ<D4B5><C7B4><EFBFBD> <20><><EFBFBD>θ<EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
if (Math::IsTriangleInAabb(aSubNodeBoundingMin[i], aSubNodeBoundingMax[i], vTri0, vTri1, vTri2))
|
||||
{
|
||||
// <20><><EFBFBD>尡 <20>Ҵ<EFBFBD><D2B4><EFBFBD><EFBFBD><EFBFBD> <20>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD> <20>Ҵ<EFBFBD>
|
||||
COctreeCollisionNode* &pNode = m_apSubNode[i];
|
||||
if (NULL == pNode)
|
||||
{
|
||||
pNode = new COctreeCollisionNode;
|
||||
pNode->m_vBoundingMin = aSubNodeBoundingMin[i];
|
||||
pNode->m_vBoundingMax = aSubNodeBoundingMax[i];
|
||||
}
|
||||
|
||||
// <20>ڽij<DABD><C4B3>忡 <20>Ѱ<EFBFBD><D1B0><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
pNode->m_vecTriangleIndex.push_back(m_vecTriangleIndex[j]);
|
||||
bIncludedInSubNode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bIncludedInSubNode)
|
||||
{
|
||||
// <20><> <20><><EFBFBD>忡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǴ°<C7B4><C2B0><EFBFBD> <20>ƴ϶<C6B4> <20>ټ<EFBFBD> <20><><EFBFBD>尣<EFBFBD><E5B0A3> <20><>ġ<EFBFBD><C4A1> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD>̹Ƿ<CCB9>,
|
||||
// triangle - AABB intersection <20><EFBFBD>Ʈ<EFBFBD><C6AE> <20>Ѵ<EFBFBD>
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
if (Math::CheckAabbTriangleIntersection(aSubNodeBoundingMin[i], aSubNodeBoundingMax[i], vTri0, vTri1, vTri2))
|
||||
{
|
||||
// <20><><EFBFBD>尡 <20>Ҵ<EFBFBD><D2B4><EFBFBD><EFBFBD><EFBFBD> <20>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD> <20>Ҵ<EFBFBD>
|
||||
COctreeCollisionNode* &pNode = m_apSubNode[i];
|
||||
if (NULL == pNode)
|
||||
{
|
||||
pNode = new COctreeCollisionNode;
|
||||
pNode->m_vBoundingMin = aSubNodeBoundingMin[i];
|
||||
pNode->m_vBoundingMax = aSubNodeBoundingMax[i];
|
||||
}
|
||||
|
||||
// <20>ڽij<DABD><C4B3>忡 <20>Ѱ<EFBFBD><D1B0><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
pNode->m_vecTriangleIndex.push_back(m_vecTriangleIndex[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20>ﰢ<EFBFBD><EFB0A2> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>ڽ<EFBFBD> <20><><EFBFBD>忡 <20><><EFBFBD><EFBFBD> <20>Ѱ<EFBFBD><D1B0>־<EFBFBD><D6BE><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><> <20>̻<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʿ䰡 <20><><EFBFBD><EFBFBD>
|
||||
m_vecTriangleIndex.clear();
|
||||
|
||||
// <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>ڽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BuildSubNode <20><> ȣ<><C8A3><EFBFBD>Ѵ<EFBFBD>
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
if (NULL != m_apSubNode[i])
|
||||
{
|
||||
m_apSubNode[i]->BuildSubNode(vecTriangle, nMaximumRecursion, nMinPolyCount, nCurrentRecursionLevel+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void COctreeCollisionNode::CollectCollidableNodes(
|
||||
const Math::VECTOR3& vSweptVolumeMin, const Math::VECTOR3& vSweptVolumeMax,
|
||||
std::vector< COctreeCollisionNode* >& vecCollidableNode)
|
||||
{
|
||||
if(!Math::CheckAabbAabbIntersection(vSweptVolumeMin, vSweptVolumeMax, m_vBoundingMin, m_vBoundingMax))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsLeafNode())
|
||||
{
|
||||
vecCollidableNode.push_back(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
if (NULL != m_apSubNode[i])
|
||||
{
|
||||
m_apSubNode[i]->CollectCollidableNodes(vSweptVolumeMin, vSweptVolumeMax, vecCollidableNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
COctreeCollider::COctreeCollider()
|
||||
{
|
||||
m_nColTriIndex = 0;
|
||||
}
|
||||
|
||||
COctreeCollider::~COctreeCollider()
|
||||
{
|
||||
}
|
||||
|
||||
void COctreeCollider::SetTriangleCount(unsigned int uiTriangleCount)
|
||||
{
|
||||
m_vecCollisionTriangle.resize(uiTriangleCount);
|
||||
}
|
||||
|
||||
void COctreeCollider::GetTriangleDataPtr(CollisionTriangleInfo*& pTriangleData)
|
||||
{
|
||||
if (m_vecCollisionTriangle.size() > 0)
|
||||
{
|
||||
pTriangleData = &(m_vecCollisionTriangle[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pTriangleData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool COctreeCollider::BuildOctree(const size_t nMaximumRecursion, const size_t nMinPolyCount)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
if (0 == m_vecCollisionTriangle.size())
|
||||
{
|
||||
m_vCollisionBoundingMin.SetValue(0,0,0);
|
||||
m_vCollisionBoundingMax.SetValue(0,0,0);
|
||||
|
||||
return true; // <20><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>־ <20>ϴ<EFBFBD><CFB4><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
|
||||
}
|
||||
|
||||
// <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
m_octreeRootNode.ReleaseSubNode();
|
||||
|
||||
// bounding min/max <20><><EFBFBD>ϱ<EFBFBD>
|
||||
m_vCollisionBoundingMin = m_vecCollisionTriangle[0].m_avVertex[0];
|
||||
m_vCollisionBoundingMax = m_vecCollisionTriangle[0].m_avVertex[0];
|
||||
|
||||
for (i = 0; i < m_vecCollisionTriangle.size(); ++i)
|
||||
{
|
||||
for (j = 0; j < 3; ++j)
|
||||
{
|
||||
CrossM::Math::VECTOR3& v = m_vecCollisionTriangle[i].m_avVertex[j];
|
||||
|
||||
if (v.x < m_vCollisionBoundingMin.x) m_vCollisionBoundingMin.x = v.x;
|
||||
if (v.y < m_vCollisionBoundingMin.y) m_vCollisionBoundingMin.y = v.y;
|
||||
if (v.z < m_vCollisionBoundingMin.z) m_vCollisionBoundingMin.z = v.z;
|
||||
|
||||
if (v.x > m_vCollisionBoundingMax.x) m_vCollisionBoundingMax.x = v.x;
|
||||
if (v.y > m_vCollisionBoundingMax.y) m_vCollisionBoundingMax.y = v.y;
|
||||
if (v.z > m_vCollisionBoundingMax.z) m_vCollisionBoundingMax.z = v.z;
|
||||
}
|
||||
}
|
||||
|
||||
// octree root node <20><> <20>ٿ<EFBFBD><D9BF><EFBFBD> <20>ڽ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||||
m_octreeRootNode.m_vBoundingMin = m_vCollisionBoundingMin;
|
||||
m_octreeRootNode.m_vBoundingMax = m_vCollisionBoundingMax;
|
||||
|
||||
// octree root node <20><> <20><><EFBFBD>Ե<EFBFBD> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>(<28><>ü)<29><> <20><><EFBFBD><EFBFBD>
|
||||
m_octreeRootNode.m_vecTriangleIndex.resize(m_vecCollisionTriangle.size());
|
||||
for (i = 0; i < m_octreeRootNode.m_vecTriangleIndex.size(); ++i)
|
||||
{
|
||||
m_octreeRootNode.m_vecTriangleIndex[i] = i;
|
||||
}
|
||||
|
||||
// DWORD dwTime = timeGetTime();
|
||||
// for (i = 0; i < m_vecCollisionTriangle.size(); ++i)
|
||||
// {
|
||||
// CollisionTriangleInfo& tri = m_vecCollisionTriangle[i];
|
||||
// Math::VECTOR3& vTri0 = m_vecCollisionVertex[ tri.m_lIndex[0] ];
|
||||
// Math::VECTOR3& vTri1 = m_vecCollisionVertex[ tri.m_lIndex[1] ];
|
||||
// Math::VECTOR3& vTri2 = m_vecCollisionVertex[ tri.m_lIndex[2] ];
|
||||
//
|
||||
// Math::CheckAabbTriangleIntersection(m_vCollisionBoundingMin, m_vCollisionBoundingMax, vTri0, vTri1, vTri2);
|
||||
// }
|
||||
// DWORD dwElapsed = timeGetTime() - dwTime;
|
||||
//
|
||||
// dwTime = timeGetTime();
|
||||
// for (i = 0; i < m_vecCollisionTriangle.size(); ++i)
|
||||
// {
|
||||
// CollisionTriangleInfo& tri = m_vecCollisionTriangle[i];
|
||||
// Math::VECTOR3& vTri0 = m_vecCollisionVertex[ tri.m_lIndex[0] ];
|
||||
// Math::VECTOR3& vTri1 = m_vecCollisionVertex[ tri.m_lIndex[1] ];
|
||||
// Math::VECTOR3& vTri2 = m_vecCollisionVertex[ tri.m_lIndex[2] ];
|
||||
//
|
||||
// Math::IsTriangleInAabb(m_vCollisionBoundingMin, m_vCollisionBoundingMax, vTri0, vTri1, vTri2);
|
||||
// }
|
||||
// DWORD dwElapsed2 = timeGetTime() - dwTime;
|
||||
|
||||
// <20>Ϻ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
m_octreeRootNode.BuildSubNode(m_vecCollisionTriangle, nMaximumRecursion, nMinPolyCount, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void COctreeCollider::GetCollisionRespondingPosition(
|
||||
Math::VECTOR3& vOutRespondingPos,
|
||||
const Math::VECTOR3& vPrevPos, const Math::VECTOR3& vNewPos,
|
||||
const Math::VECTOR3& vEllipsoidRadius,
|
||||
const unsigned int nRecursionLevel)
|
||||
{
|
||||
size_t i, j, nMinCollisionTriangleIndex;
|
||||
|
||||
// ellipsoid <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ŀ<><C4BF><EFBFBD>ϴ<EFBFBD> <20>簢<EFBFBD><E7B0A2>(AABB)<29><> min/max <20><>
|
||||
Math::VECTOR3 vSweptVolumeMin, vSweptVolumeMax;
|
||||
|
||||
vSweptVolumeMin.x = min(vPrevPos.x, vNewPos.x) - vEllipsoidRadius.x;
|
||||
vSweptVolumeMax.x = max(vPrevPos.x, vNewPos.x) + vEllipsoidRadius.x;
|
||||
vSweptVolumeMin.y = min(vPrevPos.y, vNewPos.y) - vEllipsoidRadius.y;
|
||||
vSweptVolumeMax.y = max(vPrevPos.y, vNewPos.y) + vEllipsoidRadius.y;
|
||||
vSweptVolumeMin.z = min(vPrevPos.z, vNewPos.z) - vEllipsoidRadius.z;
|
||||
vSweptVolumeMax.z = max(vPrevPos.z, vNewPos.z) + vEllipsoidRadius.z;
|
||||
|
||||
m_vecpCollidableNode.clear();
|
||||
m_octreeRootNode.CollectCollidableNodes(vSweptVolumeMin, vSweptVolumeMax, m_vecpCollidableNode);
|
||||
|
||||
if (0 == m_vecpCollidableNode.size())
|
||||
{
|
||||
// <20>浹 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
vOutRespondingPos = vNewPos;
|
||||
return;
|
||||
}
|
||||
|
||||
// ellipsoid <20><>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. sweep <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> sweep <20><><EFBFBD>⺤<EFBFBD><E2BAA4>, sweep <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
Math::VECTOR3 vESweepStart, vESweepEnd, vESweepPath;
|
||||
float fESweepLength;
|
||||
|
||||
vESweepStart.SetValue(vPrevPos.x/vEllipsoidRadius.x, vPrevPos.y/vEllipsoidRadius.y, vPrevPos.z/vEllipsoidRadius.z);
|
||||
vESweepEnd.SetValue(vNewPos.x/vEllipsoidRadius.x, vNewPos.y/vEllipsoidRadius.y, vNewPos.z/vEllipsoidRadius.z);
|
||||
Math::Subtract(vESweepPath, vESweepEnd, vESweepStart);
|
||||
fESweepLength = Math::GetLength(vESweepPath);
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
if (fESweepLength < Math::F_EPSILON)
|
||||
{
|
||||
vOutRespondingPos = vPrevPos;
|
||||
return;
|
||||
}
|
||||
|
||||
// sweeping sphere <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
Math::TriangSweepingSphere triAndSphere;
|
||||
triAndSphere.m_vSphereSweepStart = vESweepStart;
|
||||
triAndSphere.m_vSphereSweepPath = vESweepPath;
|
||||
triAndSphere.m_fSphereRadius = 1.0f; // ellipsoid <20><>ǥ<EFBFBD><C7A5><EFBFBD>̹Ƿ<CCB9> <20>浹Ÿ<E6B5B9><C5B8>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><>ȯ<EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD>
|
||||
|
||||
bool bCollision = false; // <20><><EFBFBD>õ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>鿡<EFBFBD><E9BFA1> <20>浹<EFBFBD><E6B5B9> <20>Ͼ <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20><><EFBFBD>θ<EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
|
||||
float fMinCollisionDistFactor = 9999.0f;// collision <20><> <20>Ͼ <20><><EFBFBD><EFBFBD> sweeping path <20><> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
// 0 <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 1 <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Math::VECTOR3 vMinContactPoint; // fMinCollisionDistFactor <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ǥ. ellipsoid <20><>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD>
|
||||
bool bMinContactInsideTriangle; // fMinCollisionDistFactor <20><><EFBFBD><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><EFBFBD><F0BCADB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴ<EFBFBD>) <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
|
||||
for (i = 0; i < m_vecpCollidableNode.size(); ++i)
|
||||
{
|
||||
COctreeCollisionNode& node = *(m_vecpCollidableNode[i]);
|
||||
for (j = 0; j < node.m_vecTriangleIndex.size(); ++j)
|
||||
{
|
||||
CollisionTriangleInfo& tri = m_vecCollisionTriangle[ node.m_vecTriangleIndex[j] ];
|
||||
|
||||
// <20>ﰢ<EFBFBD><EFB0A2> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
Math::VECTOR3& vTri0 = tri.m_avVertex[0];
|
||||
Math::VECTOR3& vTri1 = tri.m_avVertex[1];
|
||||
Math::VECTOR3& vTri2 = tri.m_avVertex[2];
|
||||
// <20>ﰢ<EFBFBD><EFB0A2> <20><><EFBFBD><EFBFBD> ellipsoid <20><>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><>-
|
||||
triAndSphere.m_vTri0.SetValue(vTri0.x/vEllipsoidRadius.x, vTri0.y/vEllipsoidRadius.y, vTri0.z/vEllipsoidRadius.z);
|
||||
triAndSphere.m_vTri1.SetValue(vTri1.x/vEllipsoidRadius.x, vTri1.y/vEllipsoidRadius.y, vTri1.z/vEllipsoidRadius.z);
|
||||
triAndSphere.m_vTri2.SetValue(vTri2.x/vEllipsoidRadius.x, vTri2.y/vEllipsoidRadius.y, vTri2.z/vEllipsoidRadius.z);
|
||||
|
||||
float fCollisionDistFactor;
|
||||
Math::VECTOR3 vContactPoint;
|
||||
bool bContactInside;
|
||||
// <20>ﰢ<EFBFBD><EFB0A2> - sweeping sphere <20>浹 <20>˻<EFBFBD>
|
||||
if (Math::CheckTriangleSweepingSphereCollision(fCollisionDistFactor, vContactPoint, bContactInside, triAndSphere))
|
||||
{
|
||||
// <20>浹<EFBFBD≯<EFBFBD>
|
||||
bCollision = true;
|
||||
|
||||
if(fCollisionDistFactor < fMinCollisionDistFactor)
|
||||
{
|
||||
vMinContactPoint = vContactPoint;
|
||||
fMinCollisionDistFactor = fCollisionDistFactor;
|
||||
nMinCollisionTriangleIndex = node.m_vecTriangleIndex[j];
|
||||
bMinContactInsideTriangle = bContactInside;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bCollision)
|
||||
{
|
||||
// <20>浹 <20><><EFBFBD><EFBFBD>
|
||||
vOutRespondingPos = vNewPos;
|
||||
return;
|
||||
}
|
||||
|
||||
m_nColTriIndex = nMinCollisionTriangleIndex;
|
||||
|
||||
// collision response phase
|
||||
Math::VECTOR3 vMovedPos; // <20>ϴ<EFBFBD> <20>浹<EFBFBD><E6B5B9> <20>Ͼ<CFBE><EEB3AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD> <20><>ġ
|
||||
Math::Lerp(vMovedPos, vPrevPos, vNewPos, fMinCollisionDistFactor); // <20>ϴ<EFBFBD> <20>̵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20>Űܳ<C5B0><DCB3><EFBFBD> <20><>..
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5>Ϸ<EFBFBD><CFB7><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> 90% <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>߰ų<DFB0>, recursion <20><> 4<><34> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
if (fMinCollisionDistFactor > 0.9f || nRecursionLevel >= 4)
|
||||
{
|
||||
vOutRespondingPos = vMovedPos;
|
||||
return;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5> ellipsoid <20><>ǥ<EFBFBD>迡<EFBFBD><E8BFA1> <20><><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD> ȯ<><C8AF>
|
||||
vMinContactPoint.x *= vEllipsoidRadius.x;
|
||||
vMinContactPoint.y *= vEllipsoidRadius.y;
|
||||
vMinContactPoint.z *= vEllipsoidRadius.z;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
Math::VECTOR3 vTangentPlaneNormal;
|
||||
if (bMinContactInsideTriangle)
|
||||
{
|
||||
// <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>浹<EFBFBD><E6B5B9> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> normal <20><> <20>״<EFBFBD><D7B4><EFBFBD> <20>̿<EFBFBD><CCBF>Ѵ<EFBFBD>
|
||||
CollisionTriangleInfo& colTriInfo = m_vecCollisionTriangle[nMinCollisionTriangleIndex];
|
||||
Math::VECTOR3& vCollTri0 = colTriInfo.m_avVertex[0];
|
||||
Math::VECTOR3& vCollTri1 = colTriInfo.m_avVertex[1];
|
||||
Math::VECTOR3& vCollTri2 = colTriInfo.m_avVertex[2];
|
||||
vTangentPlaneNormal = ((vCollTri1 - vCollTri0) ^ (vCollTri2 - vCollTri0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// <20><EFBFBD><F0BCADB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>浹<EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD>, Ÿ<><C5B8>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> normal <20><> <20><><EFBFBD>Ѵ<EFBFBD>
|
||||
Math::Subtract(vTangentPlaneNormal, vMovedPos, vMinContactPoint);
|
||||
vTangentPlaneNormal.x /= (vEllipsoidRadius.x*vEllipsoidRadius.x);
|
||||
vTangentPlaneNormal.y /= (vEllipsoidRadius.y*vEllipsoidRadius.y);
|
||||
vTangentPlaneNormal.z /= (vEllipsoidRadius.z*vEllipsoidRadius.z);
|
||||
Math::Normalize(vTangentPlaneNormal, vTangentPlaneNormal);
|
||||
}
|
||||
Math::Normalize(vTangentPlaneNormal, vTangentPlaneNormal);
|
||||
|
||||
// <20>浹<EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
Math::VECTOR3 vRemainder;
|
||||
Math::Subtract(vRemainder, vNewPos, vMovedPos);
|
||||
|
||||
// <20>浹<EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
float fVanishingComponentFactor = Math::DotProduct(vTangentPlaneNormal, vRemainder);
|
||||
Math::VECTOR3 vVanishingComponent;
|
||||
Math::Scale(vVanishingComponent, vTangentPlaneNormal, fVanishingComponentFactor);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD>п<EFBFBD><D0BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
Math::Subtract(vRemainder, vRemainder, vVanishingComponent);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD>ŭ<EFBFBD><C5AD> <20>̵<EFBFBD><CCB5><EFBFBD> <20><><EFBFBD><EFBFBD> <20>浹üũ <20><><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3>
|
||||
GetCollisionRespondingPosition(vOutRespondingPos, vMovedPos, vMovedPos+vRemainder, vEllipsoidRadius, nRecursionLevel+1);
|
||||
}
|
||||
|
||||
|
||||
void COctreeCollider::RenderCollidableNodeTriangles(IDirect3DDevice8* pDevice)
|
||||
{
|
||||
size_t nRenderTriCount; //j, i, nTriFilled;
|
||||
|
||||
if (0 == m_vecpCollidableNode.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ﰢ<EFBFBD><EFB0A2><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
// nRenderTriCount = 0;
|
||||
// for (i = 0; i < m_vecpCollidableNode.size(); ++i)
|
||||
// {
|
||||
// nRenderTriCount += m_vecpCollidableNode[i]->m_vecTriangleIndex.size();
|
||||
// }
|
||||
//
|
||||
// // <20><><EFBFBD>ؽ<EFBFBD> <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
|
||||
// m_vecRenderVertex.resize(nRenderTriCount*3);
|
||||
//
|
||||
// nTriFilled = 0;
|
||||
// for (i = 0; i < m_vecpCollidableNode.size(); ++i)
|
||||
// {
|
||||
// COctreeCollisionNode& node = *(m_vecpCollidableNode[i]);
|
||||
//
|
||||
// for (j = 0; j < node.m_vecTriangleIndex.size(); ++j)
|
||||
// {
|
||||
// size_t nTriIndex = node.m_vecTriangleIndex[j];
|
||||
// CollisionTriangleInfo& tri = m_vecCollisionTriangle[nTriIndex];
|
||||
//
|
||||
// m_vecRenderVertex[nTriFilled*3] = tri.m_avVertex[0];
|
||||
// m_vecRenderVertex[nTriFilled*3 + 1] = tri.m_avVertex[1];
|
||||
// m_vecRenderVertex[nTriFilled*3 + 2] = tri.m_avVertex[2];
|
||||
// ++nTriFilled;
|
||||
// }
|
||||
// }
|
||||
|
||||
nRenderTriCount = 1; // <20>浹<EFBFBD>ﰢ<EFBFBD><EFB0A2> 1<><31><EFBFBD><EFBFBD>
|
||||
m_vecRenderVertex.resize(nRenderTriCount*3);
|
||||
CollisionTriangleInfo& tri = m_vecCollisionTriangle[m_nColTriIndex];
|
||||
|
||||
m_vecRenderVertex[0] = tri.m_avVertex[0];
|
||||
m_vecRenderVertex[1] = tri.m_avVertex[1];
|
||||
m_vecRenderVertex[2] = tri.m_avVertex[2];
|
||||
|
||||
D3DXMATRIX mTmp;
|
||||
D3DXMatrixIdentity(&mTmp);
|
||||
pDevice->SetTransform(D3DTS_WORLD, &mTmp);
|
||||
|
||||
DWORD dwFillMode, dwZFunc;
|
||||
pDevice->GetRenderState(D3DRS_FILLMODE, &dwFillMode);
|
||||
pDevice->GetRenderState(D3DRS_ZFUNC, &dwZFunc);
|
||||
pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||
pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
|
||||
pDevice->SetVertexShader(D3DFVF_XYZ);
|
||||
pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, (UINT)nRenderTriCount, &(m_vecRenderVertex[0]), sizeof(Math::VECTOR3));
|
||||
pDevice->SetRenderState(D3DRS_FILLMODE, dwFillMode);
|
||||
pDevice->SetRenderState(D3DRS_ZFUNC, dwZFunc);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
Reference in New Issue
Block a user