forked from metin2/client
1
0
Fork 0
client/EterGrnLib/ModelInstanceCollisionDetec...

268 lines
7.1 KiB
C++
Raw Blame History

#include "Stdafx.h"
#include "ModelInstance.h"
#include "Model.h"
void CGrannyModelInstance::MakeBoundBox(TBoundBox* pBoundBox,
const float* mat,
const float* OBBMin,
const float* OBBMax,
D3DXVECTOR3* vtMin,
D3DXVECTOR3* vtMax)
{
pBoundBox->sx = OBBMin[0] * mat[0] + OBBMin[1] * mat[4] + OBBMin[2] * mat[8] + mat[12];
pBoundBox->sy = OBBMin[0] * mat[1] + OBBMin[1] * mat[5] + OBBMin[2] * mat[9] + mat[13];
pBoundBox->sz = OBBMin[0] * mat[2] + OBBMin[1] * mat[6] + OBBMin[2] * mat[10] + mat[14];
pBoundBox->ex = OBBMax[0] * mat[0] + OBBMax[1] * mat[4] + OBBMax[2] * mat[8] + mat[12];
pBoundBox->ey = OBBMax[0] * mat[1] + OBBMax[1] * mat[5] + OBBMax[2] * mat[9] + mat[13];
pBoundBox->ez = OBBMax[0] * mat[2] + OBBMax[1] * mat[6] + OBBMax[2] * mat[10] + mat[14];
vtMin->x = min(vtMin->x, pBoundBox->sx);
vtMin->x = min(vtMin->x, pBoundBox->ex);
vtMin->y = min(vtMin->y, pBoundBox->sy);
vtMin->y = min(vtMin->y, pBoundBox->ey);
vtMin->z = min(vtMin->z, pBoundBox->sz);
vtMin->z = min(vtMin->z, pBoundBox->ez);
vtMax->x = max(vtMax->x, pBoundBox->sx);
vtMax->x = max(vtMax->x, pBoundBox->ex);
vtMax->y = max(vtMax->y, pBoundBox->sy);
vtMax->y = max(vtMax->y, pBoundBox->ey);
vtMax->z = max(vtMax->z, pBoundBox->sz);
vtMax->z = max(vtMax->z, pBoundBox->ez);
}
bool CGrannyModelInstance::Intersect(const D3DXMATRIX * c_pMatrix,
float * /*pu*/, float * /*pv*/, float * pt)
{
if (!m_pgrnModelInstance)
return false;
float u, v, t;
bool ret = false;
*pt = 100000000.0f;
float max = 10000000.0f;
D3DXVECTOR3 vtMin, vtMax;
vtMin.x = vtMin.y = vtMin.z = max;
vtMax.x = vtMax.y = vtMax.z = -max;
static stl_stack_pool<TBoundBox> s_boundBoxPool(1024);
s_boundBoxPool.clear();
int meshCount = m_pModel->GetMeshCount();
for (int m = 0; m < meshCount; ++m)
{
//const CGrannyMesh * pMesh = m_pModel->GetMeshPointer(m);
const granny_mesh * pgrnMesh = m_pModel->GetGrannyModelPointer()->MeshBindings[m].Mesh;
for (int b = 0; b < pgrnMesh->BoneBindingCount; ++b)
{
const granny_bone_binding& rgrnBoneBinding = pgrnMesh->BoneBindings[b];
TBoundBox * pBoundBox = s_boundBoxPool.alloc();
// WORK
float * Transform = GrannyGetWorldPose4x4(__GetWorldPosePtr(), __GetMeshBoneIndices(m)[b]);
// END_OF_WORK
MakeBoundBox(pBoundBox,
Transform,
rgrnBoneBinding.OBBMin,
rgrnBoneBinding.OBBMax,
&vtMin,
&vtMax);
pBoundBox->meshIndex = m;
pBoundBox->boneIndex = b;
}
}
if (!IntersectCube(c_pMatrix,
vtMin.x, vtMin.y, vtMin.z,
vtMax.x, vtMax.y, vtMax.z,
ms_vtPickRayOrig, ms_vtPickRayDir,
&u, &v, &t))
{
return ret;
}
return true;
/*
TBoundBox* boundBoxs = s_boundBoxPool.base();
for (int i = 0; i < s_boundBoxPool.size(); ++i)
{
TBoundBox& rcurBoundBox=boundBoxs[i];
if (!IntersectBoundBox(c_pMatrix, rcurBoundBox, &u, &v, &t))
continue;
granny_matrix_4x4* pgrnMatCompositeBuffer = GrannyGetWorldPoseComposite4x4Array(m_pgrnWorldPose);
const CGrannyMesh* c_pMesh = m_pModel->GetMeshPointer(rcurBoundBox.meshIndex);
const granny_mesh* c_pgrnMesh = c_pMesh->GetGrannyMeshPointer();
if (!GrannyMeshIsRigid(c_pgrnMesh))
{
//continue;
ret = true;
}
else
{
D3DXMATRIX matMesh;
int* toBoneIndices = c_pMesh->GetBoneIndices();
D3DXMatrixMultiply(&matMesh, (D3DXMATRIX*) pgrnMatCompositeBuffer[toBoneIndices[0]], c_pMatrix);
granny_tri_material_group* pgrnTriGroups = GrannyGetMeshTriangleGroups(c_pgrnMesh);
int mtrlCount = c_pMesh->GetGrannyMeshPointer()->MaterialBindingCount;
int vtxCount = GrannyGetMeshVertexCount(c_pgrnMesh);
int groupCount = GrannyGetMeshTriangleGroupCount(c_pgrnMesh);
TIndex* modelIndices;
TPNTVertex* modelVertices;
if (m_pModel->LockVertices((void**)&modelIndices, (void**)&modelVertices))
{
TIndex* meshIndices = modelIndices + c_pMesh->GetIndexBasePosition();
TPNTVertex* meshVertices = modelVertices + c_pMesh->GetVertexBasePosition();
for (int i = 0; i < groupCount; ++i)
{
granny_tri_material_group& rgrnTriGroup = pgrnTriGroups[i];
if (rgrnTriGroup.MaterialIndex < 0 || rgrnTriGroup.MaterialIndex >= mtrlCount)
continue;
if (IntersectMesh(&matMesh,
meshVertices,
sizeof(TPNTVertex),
vtxCount,
meshIndices,
GrannyGetMeshIndexCount(c_pgrnMesh),
ms_vtPickRayOrig,
ms_vtPickRayDir,
&u, &v, &t))
{
ret = true;
break;
}
}
m_pModel->UnlockVertices();
}
}
if (ret)
{
*pu = u;
*pv = v;
*pt = -t;
if (c_szModelName)
{
if (!strncmp(c_pgrnMesh->Name, c_szModelName, strlen(c_szModelName)))
return ret;
ret = false;
continue;
}
return ret;
}
}
return (ret);
*/
}
#include "../EterBase/Timer.h"
void CGrannyModelInstance::GetBoundBox(D3DXVECTOR3* vtMin, D3DXVECTOR3* vtMax)
{
if (!m_pgrnModelInstance)
return;
TBoundBox BoundBox;
vtMin->x = vtMin->y = vtMin->z = +100000.0f;
vtMax->x = vtMax->y = vtMax->z = -100000.0f;
int meshCount = m_pModel->GetMeshCount();
for (int m = 0; m < meshCount; ++m)
{
//const CGrannyMesh* pMesh = m_pModel->GetMeshPointer(m);
const granny_mesh* pgrnMesh = m_pModel->GetGrannyModelPointer()->MeshBindings[m].Mesh;
// WORK
int* boneIndices = __GetMeshBoneIndices(m);
// END_OF_WORK
for (int b = 0; b < pgrnMesh->BoneBindingCount; ++b)
{
const granny_bone_binding& rgrnBoneBinding = pgrnMesh->BoneBindings[b];
MakeBoundBox(&BoundBox,
GrannyGetWorldPose4x4(__GetWorldPosePtr(), boneIndices[b]),
rgrnBoneBinding.OBBMin, rgrnBoneBinding.OBBMax, vtMin, vtMax);
}
}
}
bool CGrannyModelInstance::GetMeshMatrixPointer(int iMesh, const D3DXMATRIX ** c_ppMatrix) const
{
if (!m_pgrnModelInstance)
return false;
int meshCount = m_pModel->GetMeshCount();
if (meshCount <= 0)
return false;
// WORK
//const CGrannyMesh * pMesh = m_pModel->GetMeshPointer(iMesh);
*c_ppMatrix = (D3DXMATRIX *)GrannyGetWorldPose4x4(__GetWorldPosePtr(), __GetMeshBoneIndices(iMesh)[0]);
// END_OF_WORK
return true;
}
/*
void CGraphicThingInstance::DrawBoundBox()
{
if (!mc_pMeshVector)
return;
if (!m_pgrnWorldPose)
return;
D3DXVECTOR3 vtMin;
D3DXVECTOR3 vtMax;
SetDiffuseColor(0.0f, 1.0f, 0.0f);
// ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> <20>ڽ<EFBFBD>
//GetBoundBox(&vtMin, &vtMax);
//DrawLineCube(vtMin.x, vtMin.y, vtMin.z, vtMax.x, vtMax.y, vtMax.z);
//const CThing::TMeshVector& rmeshVector=mc_pModel->meshVector;
ms_lpd3dMatStack->LoadMatrix(&m_Matrix);
for (size_t m=0; m<mc_pMeshVector->size(); ++m)
{
const CThing::TMesh& rmesh=mc_pMeshVector->at(m);
for (int b=0; b<rmesh.pgrnMesh->BoneBindingCount; ++b)
{
granny_bone_binding& rgrnBoneBinding=rmesh.pgrnMesh->BoneBindings[b];
int* toBoneIndices=GrannyGetMeshBindingToBoneIndices(rmesh.pgrnMeshBinding);
D3DXMATRIX* pmat=(D3DXMATRIX*)GrannyGetWorldPose4x4(m_pgrnWorldPose, toBoneIndices[b]);
D3DXVec3TransformCoord(&vtMin, &D3DXVECTOR3(rgrnBoneBinding.OBBMin), pmat);
D3DXVec3TransformCoord(&vtMax, &D3DXVECTOR3(rgrnBoneBinding.OBBMax), pmat);
DrawLineCube(vtMin.x, vtMin.y, vtMin.z, vtMax.x, vtMax.y, vtMax.z);
}
}
}
*/