#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 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¸¯ÅÍ ²ËÂ÷´Â ¹Ù¿îµù ¹Ú½º //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; msize(); ++m) { const CThing::TMesh& rmesh=mc_pMeshVector->at(m); for (int b=0; bBoneBindingCount; ++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); } } } */