#include "DrawScene.h"
#include "SceneCache.h"
#include "GetPosition.h"
ShadingMode pShadingMode);
void ComputeShapeDeformation(
FbxMesh* pMesh,
void ComputeClusterDeformation(
FbxAMatrix& pGlobalPosition,
void ComputeLinearDeformation(
FbxAMatrix& pGlobalPosition,
void ComputeDualQuaternionDeformation(
FbxAMatrix& pGlobalPosition,
void ComputeSkinDeformation(
FbxAMatrix& pGlobalPosition,
void ReadVertexCacheData(
FbxMesh* pMesh,
void MatrixScale(
FbxAMatrix& pMatrix,
double pValue);
void MatrixAddToDiagonal(
FbxAMatrix& pMatrix,
double pValue);
{
for (int lLightIndex = 0; lLightIndex < lLightCount; ++lLightIndex)
{
if (lNode)
{
FbxAMatrix lGlobalPosition = GetGlobalPosition(lNode, pTime, pPose);
FbxAMatrix lGlobalOffPosition = lGlobalPosition * lGeometryOffset;
DrawLight(lNode, pTime, lGlobalOffPosition);
}
}
}
ShadingMode pShadingMode)
{
FbxAMatrix lGlobalPosition = GetGlobalPosition(pNode, pTime, pPose, &pParentGlobalPosition);
{
FbxAMatrix lGlobalOffPosition = lGlobalPosition * lGeometryOffset;
DrawNode(pNode, pTime, pAnimLayer, pParentGlobalPosition, lGlobalOffPosition, pPose, pShadingMode);
}
for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
{
DrawNodeRecursive(pNode->
GetChild(lChildIndex), pTime, pAnimLayer, lGlobalPosition, pPose, pShadingMode);
}
}
FbxPose* pPose, ShadingMode pShadingMode)
{
if (lNodeAttribute)
{
{
DrawMarker(pGlobalPosition);
}
{
DrawSkeleton(pNode, pParentGlobalPosition, pGlobalPosition);
}
{
DrawMesh(pNode, pTime, pAnimLayer, pGlobalPosition, pPose, pShadingMode);
}
{
DrawCamera(pNode, pTime, pAnimLayer, pGlobalPosition);
}
{
DrawNull(pGlobalPosition);
}
}
else
{
DrawNull(pGlobalPosition);
}
}
{
GlDrawMarker(pGlobalPosition);
}
{
{
GlDrawLimbNode(pParentGlobalPosition, pGlobalPosition);
}
}
{
if (lVertexCount == 0)
{
return;
}
const VBOMesh * lMeshCache =
static_cast<const VBOMesh *
>(lMesh->
GetUserDataPtr());
const bool lHasDeformation = lHasVertexCache || lHasShape || lHasSkin;
if (!lMeshCache || lHasDeformation)
{
}
if (lHasDeformation)
{
if (lHasVertexCache)
{
ReadVertexCacheData(lMesh, pTime, lVertexArray);
}
else
{
if (lHasShape)
{
ComputeShapeDeformation(lMesh, pTime, pAnimLayer, lVertexArray);
}
int lClusterCount = 0;
for (int lSkinIndex = 0; lSkinIndex < lSkinCount; ++lSkinIndex)
{
}
if (lClusterCount)
{
ComputeSkinDeformation(pGlobalPosition, lMesh, pTime, lVertexArray, pPose);
}
}
if (lMeshCache)
lMeshCache->UpdateVertexPosition(lMesh, lVertexArray);
}
glPushMatrix();
glMultMatrixd((const double*)pGlobalPosition);
if (lMeshCache)
{
lMeshCache->BeginDraw(pShadingMode);
const int lSubMeshCount = lMeshCache->GetSubMeshCount();
for (int lIndex = 0; lIndex < lSubMeshCount; ++lIndex)
{
if (pShadingMode == SHADING_MODE_SHADED)
{
if (lMaterial)
{
const MaterialCache * lMaterialCache =
static_cast<const MaterialCache *
>(lMaterial->
GetUserDataPtr());
if (lMaterialCache)
{
lMaterialCache->SetCurrentMaterial();
}
}
else
{
MaterialCache::SetDefaultMaterial();
}
}
lMeshCache->Draw(lIndex, pShadingMode);
}
lMeshCache->EndDraw();
}
else
{
glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; lPolygonIndex++)
{
glBegin(GL_LINE_LOOP);
for (int lVerticeIndex = 0; lVerticeIndex < lVerticeCount; lVerticeIndex++)
{
glVertex3dv((GLdouble *)lVertexArray[lMesh->
GetPolygonVertex(lPolygonIndex, lVerticeIndex)]);
}
glEnd();
}
}
glPopMatrix();
delete [] lVertexArray;
}
{
memcpy(lDstVertexArray, pVertexArray, lVertexCount *
sizeof(
FbxVector4));
for(int lBlendShapeIndex = 0; lBlendShapeIndex<lBlendShapeDeformerCount; ++lBlendShapeIndex)
{
for(int lChannelIndex = 0; lChannelIndex<lBlendShapeChannelCount; ++lChannelIndex)
{
if(lChannel)
{
if (!lFCurve) continue;
double lWeight = lFCurve->
Evaluate(pTime);
int lStartIndex = -1;
int lEndIndex = -1;
for(int lShapeIndex = 0; lShapeIndex<lShapeCount; ++lShapeIndex)
{
if(lWeight > 0 && lWeight <= lFullWeights[0])
{
lEndIndex = 0;
break;
}
if(lWeight > lFullWeights[lShapeIndex] && lWeight < lFullWeights[lShapeIndex+1])
{
lStartIndex = lShapeIndex;
lEndIndex = lShapeIndex + 1;
break;
}
}
if(lStartIndex > -1)
{
}
if(lEndIndex > -1)
{
}
if(lStartIndex == -1 && lEndShape)
{
double lEndWeight = lFullWeights[0];
lWeight = (lWeight/lEndWeight) * 100;
memcpy(lDstVertexArray, lSrcVertexArray, lVertexCount *
sizeof(
FbxVector4));
for (int j = 0; j < lVertexCount; j++)
{
lDstVertexArray[j] += lInfluence;
}
}
else if(lStartShape && lEndShape)
{
double lStartWeight = lFullWeights[lStartIndex];
double lEndWeight = lFullWeights[lEndIndex];
lWeight = ((lWeight-lStartWeight)/(lEndWeight-lStartWeight)) * 100;
for (int j = 0; j < lVertexCount; j++)
{
lDstVertexArray[j] += lInfluence;
}
}
}
}
}
memcpy(pVertexArray, lDstVertexArray, lVertexCount *
sizeof(
FbxVector4));
delete [] lDstVertexArray;
}
void ComputeClusterDeformation(
FbxAMatrix& pGlobalPosition,
{
FbxAMatrix lClusterRelativeCurrentPositionInverse;
{
lAssociateGlobalInitPosition *= lAssociateGeometry;
lAssociateGlobalCurrentPosition = GetGlobalPosition(pCluster->
GetAssociateModel(), pTime, pPose);
lReferenceGeometry = GetGeometry(pMesh->
GetNode());
lReferenceGlobalInitPosition *= lReferenceGeometry;
lReferenceGlobalCurrentPosition = pGlobalPosition;
lClusterGeometry = GetGeometry(pCluster->
GetLink());
lClusterGlobalInitPosition *= lClusterGeometry;
lClusterGlobalCurrentPosition = GetGlobalPosition(pCluster->
GetLink(), pTime, pPose);
pVertexTransformMatrix = lReferenceGlobalInitPosition.
Inverse() * lAssociateGlobalInitPosition * lAssociateGlobalCurrentPosition.
Inverse() *
lClusterGlobalCurrentPosition * lClusterGlobalInitPosition.
Inverse() * lReferenceGlobalInitPosition;
}
else
{
lReferenceGlobalCurrentPosition = pGlobalPosition;
lReferenceGeometry = GetGeometry(pMesh->
GetNode());
lReferenceGlobalInitPosition *= lReferenceGeometry;
lClusterGlobalCurrentPosition = GetGlobalPosition(pCluster->
GetLink(), pTime, pPose);
lClusterRelativeInitPosition = lClusterGlobalInitPosition.
Inverse() * lReferenceGlobalInitPosition;
lClusterRelativeCurrentPositionInverse = lReferenceGlobalCurrentPosition.
Inverse() * lClusterGlobalCurrentPosition;
pVertexTransformMatrix = lClusterRelativeCurrentPositionInverse * lClusterRelativeInitPosition;
}
}
void ComputeLinearDeformation(
FbxAMatrix& pGlobalPosition,
{
memset(lClusterDeformation, 0, lVertexCount *
sizeof(
FbxAMatrix));
double* lClusterWeight = new double[lVertexCount];
memset(lClusterWeight, 0, lVertexCount * sizeof(double));
{
for (int i = 0; i < lVertexCount; ++i)
{
}
}
for ( int lSkinIndex=0; lSkinIndex<lSkinCount; ++lSkinIndex)
{
for ( int lClusterIndex=0; lClusterIndex<lClusterCount; ++lClusterIndex)
{
continue;
ComputeClusterDeformation(pGlobalPosition, pMesh, lCluster, lVertexTransformMatrix, pTime, pPose);
for (int k = 0; k < lVertexIndexCount; ++k)
{
if (lIndex >= lVertexCount)
continue;
if (lWeight == 0.0)
{
continue;
}
MatrixScale(lInfluence, lWeight);
{
MatrixAddToDiagonal(lInfluence, 1.0 - lWeight);
lClusterDeformation[lIndex] = lInfluence * lClusterDeformation[lIndex];
lClusterWeight[lIndex] = 1.0;
}
else
{
MatrixAdd(lClusterDeformation[lIndex], lInfluence);
lClusterWeight[lIndex] += lWeight;
}
}
}
}
for (int i = 0; i < lVertexCount; i++)
{
double lWeight = lClusterWeight[i];
if (lWeight != 0.0)
{
lDstVertex = lClusterDeformation[i].
MultT(lSrcVertex);
{
lDstVertex /= lWeight;
}
{
lSrcVertex *= (1.0 - lWeight);
lDstVertex += lSrcVertex;
}
}
}
delete [] lClusterDeformation;
delete [] lClusterWeight;
}
void ComputeDualQuaternionDeformation(
FbxAMatrix& pGlobalPosition,
{
double* lClusterWeight = new double[lVertexCount];
memset(lClusterWeight, 0, lVertexCount * sizeof(double));
for ( int lSkinIndex=0; lSkinIndex<lSkinCount; ++lSkinIndex)
{
for ( int lClusterIndex=0; lClusterIndex<lClusterCount; ++lClusterIndex)
{
continue;
ComputeClusterDeformation(pGlobalPosition, pMesh, lCluster, lVertexTransformMatrix, pTime, pPose);
for (int k = 0; k < lVertexIndexCount; ++k)
{
if (lIndex >= lVertexCount)
continue;
if (lWeight == 0.0)
continue;
{
lDQClusterDeformation[lIndex] = lInfluence;
lClusterWeight[lIndex] = 1.0;
}
else
{
if(lClusterIndex == 0)
{
lDQClusterDeformation[lIndex] = lInfluence;
}
else
{
if( lSign >= 0.0 )
{
lDQClusterDeformation[lIndex] += lInfluence;
}
else
{
lDQClusterDeformation[lIndex] -= lInfluence;
}
}
lClusterWeight[lIndex] += lWeight;
}
}
}
}
for (int i = 0; i < lVertexCount; i++)
{
double lWeightSum = lClusterWeight[i];
if (lWeightSum != 0.0)
{
lDstVertex = lDQClusterDeformation[i].
Deform(lDstVertex);
{
lDstVertex /= lWeightSum;
}
{
lSrcVertex *= (1.0 - lWeightSum);
lDstVertex += lSrcVertex;
}
}
}
delete [] lDQClusterDeformation;
delete [] lClusterWeight;
}
void ComputeSkinDeformation(
FbxAMatrix& pGlobalPosition,
{
{
ComputeLinearDeformation(pGlobalPosition, pMesh, pTime, pVertexArray, pPose);
}
{
ComputeDualQuaternionDeformation(pGlobalPosition, pMesh, pTime, pVertexArray, pPose);
}
{
ComputeLinearDeformation(pGlobalPosition, pMesh, pTime, lVertexArrayLinear, pPose);
ComputeDualQuaternionDeformation(pGlobalPosition, pMesh, pTime, lVertexArrayDQ, pPose);
for(int lBWIndex = 0; lBWIndex<lBlendWeightsCount; ++lBWIndex)
{
pVertexArray[lBWIndex] = lVertexArrayDQ[lBWIndex] * lBlendWeight + lVertexArrayLinear[lBWIndex] * (1 - lBlendWeight);
}
}
}
void ReadVertexCacheData(
FbxMesh* pMesh,
{
bool lReadSucceed = false;
unsigned int BufferSize = 0;
return;
unsigned int Length = 0;
if (Length != lVertexCount*3)
return;
lReadSucceed = lCache->
Read(&lReadBuf, BufferSize, pTime, lChannelIndex);
if (lReadSucceed)
{
unsigned int lReadBufIndex = 0;
while (lReadBufIndex < 3*lVertexCount)
{
pVertexArray[lReadBufIndex/3].
mData[0] = lReadBuf[lReadBufIndex]; lReadBufIndex++;
pVertexArray[lReadBufIndex/3].
mData[1] = lReadBuf[lReadBufIndex]; lReadBufIndex++;
pVertexArray[lReadBufIndex/3].
mData[2] = lReadBuf[lReadBufIndex]; lReadBufIndex++;
}
}
}
{
FbxVector4 lCameraPosition, lCameraDefaultDirection, lCameraInterestPosition;
lCameraPosition = pGlobalPosition.
GetT();
lCameraDefaultDirection = lCameraPosition + lXPositiveAxis;
lCameraGlobalPosition = pGlobalPosition;
{
lCameraInterestPosition = GetGlobalPosition(pNode->
GetTarget(), pTime).GetT();
lCameraDefaultDirection,
lCameraInterestPosition,
lCameraDirection);
lCameraGlobalPosition.
SetR(lCameraDirection);
}
double lRoll = 0;
if (cam)
{
}
GlDrawCamera(lCameraGlobalPosition, lRoll);
}
{
if (!lLight)
return;
lLightRotation.
SetR(lYNegativeAxis);
const FbxAMatrix lLightGlobalPosition = pGlobalPosition * lLightRotation;
glPushMatrix();
glMultMatrixd((const double*)lLightGlobalPosition);
const LightCache * lLightCache =
static_cast<const LightCache *
>(lLight->
GetUserDataPtr());
if (lLightCache)
{
lLightCache->SetLight(pTime);
}
glPopMatrix();
}
{
GlDrawCrossHair(pGlobalPosition);
}
void MatrixScale(
FbxAMatrix& pMatrix,
double pValue)
{
int i,j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
pMatrix[i][j] *= pValue;
}
}
}
void MatrixAddToDiagonal(
FbxAMatrix& pMatrix,
double pValue)
{
pMatrix[0][0] += pValue;
pMatrix[1][1] += pValue;
pMatrix[2][2] += pValue;
pMatrix[3][3] += pValue;
}
{
int i,j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
pDstMatrix[i][j] += pSrcMatrix[i][j];
}
}
}