client/EterGrnLib/ModelInstanceUpdate.cpp

207 lines
5.1 KiB
C++

#include "StdAfx.h"
#include "../eterbase/Debug.h"
#include "ModelInstance.h"
#include "Model.h"
void CGrannyModelInstance::Update(DWORD dwAniFPS)
{
if (!dwAniFPS)
return;
const DWORD c_dwCurUpdateFrame = (DWORD) (GetLocalTime() * ANIFPS_MAX);
const DWORD ANIFPS_STEP = ANIFPS_MAX/dwAniFPS;
if (c_dwCurUpdateFrame>ANIFPS_STEP && c_dwCurUpdateFrame/ANIFPS_STEP==m_dwOldUpdateFrame/ANIFPS_STEP)
return;
m_dwOldUpdateFrame=c_dwCurUpdateFrame;
//DWORD t1=timeGetTime();
GrannySetModelClock(m_pgrnModelInstance, GetLocalTime());
//DWORD t2=timeGetTime();
#ifdef __PERFORMANCE_CHECKER__
{
static FILE* fp=fopen("perf_grn_setmodelclock.txt", "w");
if (t2-t1>3)
{
fprintf(fp, "%f:%x:- GrannySetModelClock(time=%f) = %dms\n", timeGetTime()/1000.0f, this, GetLocalTime(), t2-t1);
fflush(fp);
}
}
#endif
}
void CGrannyModelInstance::UpdateLocalTime(float fElapsedTime)
{
m_fSecondsElapsed = fElapsedTime;
m_fLocalTime += fElapsedTime;
}
void CGrannyModelInstance::UpdateTransform(D3DXMATRIX * pMatrix, float fSecondsElapsed)
{
if (!m_pgrnModelInstance)
{
TraceError("CGrannyModelIstance::UpdateTransform - m_pgrnModelInstance = NULL");
return;
}
GrannyUpdateModelMatrix(m_pgrnModelInstance, fSecondsElapsed, (const float *) pMatrix, (float *) pMatrix);
//Tracef("%f %f %f",pMatrix->_41,pMatrix->_42,pMatrix->_43);
}
void CGrannyModelInstance::Deform(const D3DXMATRIX * c_pWorldMatrix)
{
if (IsEmpty())
return;
// DELETED
//m_pgrnWorldPose = m_pgrnWorldPoseReal;
/////////////////////////////////////////////
UpdateWorldPose();
UpdateWorldMatrices(c_pWorldMatrix);
if (m_pModel->CanDeformPNTVertices())
{
// WORK
CGraphicVertexBuffer& rkDeformableVertexBuffer = __GetDeformableVertexBufferRef();
TPNTVertex* pntVertices;
if (rkDeformableVertexBuffer.LockRange(m_pModel->GetDeformVertexCount(), (void **)&pntVertices))
{
DeformPNTVertices(pntVertices);
rkDeformableVertexBuffer.Unlock();
}
else
{
TraceError("GRANNY DEFORM DYNAMIC BUFFER LOCK ERROR");
}
// END_OF_WORK
}
}
//////////////////////////////////////////////////////
class CGrannyLocalPose
{
public:
CGrannyLocalPose()
{
m_pgrnLocalPose = NULL;
m_boneCount = 0;
}
virtual ~CGrannyLocalPose()
{
if (m_pgrnLocalPose)
GrannyFreeLocalPose(m_pgrnLocalPose);
}
granny_local_pose * Get(int boneCount)
{
if (m_pgrnLocalPose)
{
if (m_boneCount >= boneCount)
return m_pgrnLocalPose;
GrannyFreeLocalPose(m_pgrnLocalPose);
}
m_boneCount = boneCount;
m_pgrnLocalPose = GrannyNewLocalPose(m_boneCount);
return m_pgrnLocalPose;
}
private:
granny_local_pose * m_pgrnLocalPose;
int m_boneCount;
};
//////////////////////////////////////////////////////
void CGrannyModelInstance::UpdateSkeleton(const D3DXMATRIX * c_pWorldMatrix, float /*fLocalTime*/)
{
// DELETED
//m_pgrnWorldPose = m_pgrnWorldPoseReal;
///////////////////////////////////////////
UpdateWorldPose();
UpdateWorldMatrices(c_pWorldMatrix);
}
void CGrannyModelInstance::UpdateWorldPose()
{
// WEP = m_iParentBoneIndex != 0 -> UpdateWorldPose(O)
// LOD = UpdateWorldPose(O)
// Hair = UpdateWorldPose(X)
if (m_ppkSkeletonInst)
if (*m_ppkSkeletonInst!=this)
return;
static CGrannyLocalPose s_SharedLocalPose;
granny_skeleton * pgrnSkeleton = GrannyGetSourceSkeleton(m_pgrnModelInstance);
granny_local_pose * pgrnLocalPose = s_SharedLocalPose.Get(pgrnSkeleton->BoneCount);
const float * pAttachBoneMatrix = (mc_pParentInstance) ? mc_pParentInstance->GetBoneMatrixPointer(m_iParentBoneIndex) : NULL;
GrannySampleModelAnimationsAccelerated(m_pgrnModelInstance, pgrnSkeleton->BoneCount, pAttachBoneMatrix, pgrnLocalPose, __GetWorldPosePtr());
/*
GrannySampleModelAnimations(m_pgrnModelInstance, 0, pgrnSkeleton->BoneCount, pgrnLocalPose);
GrannyBuildWorldPose(pgrnSkeleton, 0, pgrnSkeleton->BoneCount, pgrnLocalPose, pAttachBoneMatrix, m_pgrnWorldPose);
*/
GrannyFreeCompletedModelControls(m_pgrnModelInstance);
}
void CGrannyModelInstance::UpdateWorldMatrices(const D3DXMATRIX* c_pWorldMatrix)
{
// NO_MESH_BUG_FIX
if (!m_meshMatrices)
return;
// END_OF_NO_MESH_BUG_FIX
assert(m_pModel != NULL);
assert(ms_lpd3dMatStack != NULL);
int meshCount = m_pModel->GetMeshCount();
granny_matrix_4x4 * pgrnMatCompositeBuffer = GrannyGetWorldPoseComposite4x4Array(__GetWorldPosePtr());
D3DXMATRIX * boneMatrices = (D3DXMATRIX *) pgrnMatCompositeBuffer;
for (int i = 0; i < meshCount; ++i)
{
D3DXMATRIX & rWorldMatrix = m_meshMatrices[i];
const CGrannyMesh * pMesh = m_pModel->GetMeshPointer(i);
// WORK
int * boneIndices = __GetMeshBoneIndices(i);
// END_OF_WORK
if (pMesh->CanDeformPNTVertices())
{
rWorldMatrix = *c_pWorldMatrix;
}
else
{
int iBone = *boneIndices;
D3DXMatrixMultiply(&rWorldMatrix, &boneMatrices[iBone], c_pWorldMatrix);
}
}
#ifdef _TEST
TEST_matWorld = *c_pWorldMatrix;
#endif
}
void CGrannyModelInstance::DeformPNTVertices(void * pvDest)
{
assert(m_pModel != NULL);
assert(m_pModel->CanDeformPNTVertices());
// WORK
m_pModel->DeformPNTVertices(pvDest, (D3DXMATRIX *) GrannyGetWorldPoseComposite4x4Array(__GetWorldPosePtr()), m_vct_pgrnMeshBinding);
// END_OF_WORK
}