forked from metin2/client
268 lines
7.1 KiB
C++
268 lines
7.1 KiB
C++
|
#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);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
*/
|