optimization: don't make a temp copy of vertices if the model has no bones

This commit is contained in:
Chris Danford
2004-02-08 04:58:43 +00:00
parent 221b51c2b4
commit 9ca4de158f
4 changed files with 81 additions and 69 deletions
+64 -65
View File
@@ -26,7 +26,6 @@ const CString DEFAULT_ANIMATION_NAME = "default";
Model::Model ()
{
m_pBones = NULL;
m_bTextureWrapping = true;
SetUseZBuffer( true );
m_pCurAnimation = NULL;
@@ -42,9 +41,7 @@ Model::~Model ()
void Model::Clear ()
{
delete[] m_pBones;
m_pBones = NULL;
m_vpBones.clear();
m_Meshes.clear();
m_Materials.clear();
m_mapNameToAnimation.clear();
@@ -139,11 +136,11 @@ bool Model::LoadMilkshapeAscii( CString sPath )
THROW
}
msVertex& vertex = mesh.Vertices[j];
RageModelVertex& vertex = mesh.Vertices[j];
// vertex.nFlags = nFlags;
memcpy( vertex.Vertex, Vertex, sizeof(vertex.Vertex) );
memcpy( vertex.uv, uv, sizeof(vertex.uv) );
vertex.nBoneIndex = (byte)nIndex;
memcpy( vertex.p, Vertex, sizeof(vertex.p) );
memcpy( vertex.t, uv, sizeof(vertex.t) );
vertex.boneIndex = (byte)nIndex;
RageVec3AddToBounds( RageVector3(Vertex), m_vMins, m_vMaxs );
}
@@ -208,10 +205,9 @@ bool Model::LoadMilkshapeAscii( CString sPath )
// deflate the normals into vertices
for( int k=0; k<3; k++ )
{
msVertex& Vertex = mesh.Vertices[ nIndices[k] ];
RageVector3& Normal = Normals[ nNormalIndices[k] ];
Vertex.Normal = Normal;
RageModelVertex& vertex = mesh.Vertices[ nIndices[k] ];
RageVector3& normal = Normals[ nNormalIndices[k] ];
vertex.n = normal;
}
msTriangle& Triangle = mesh.Triangles[j];
@@ -341,13 +337,19 @@ bool Model::LoadMilkshapeAscii( CString sPath )
LoadMilkshapeAsciiBones( DEFAULT_ANIMATION_NAME, sPath );
// Setup temp vertices
m_vTempVerticesByBone.resize( m_Meshes.size() );
for (i = 0; i < (int)m_Meshes.size(); i++)
{
msMesh& Mesh = m_Meshes[i];
m_vTempVerticesByBone[i].resize( Mesh.Vertices.size() );
}
//
// Setup temp vertices (if necessary)
//
bUseTempVertices = m_mapNameToAnimation[DEFAULT_ANIMATION_NAME].Bones.size() > 0; // if there are no bones, then there's no reason to use temp vertices
if( bUseTempVertices )
{
m_vTempVerticesByMesh.resize( m_Meshes.size() );
for (i = 0; i < (int)m_Meshes.size(); i++)
{
msMesh& Mesh = m_Meshes[i];
m_vTempVerticesByMesh[i].resize( Mesh.Vertices.size() );
}
}
return true;
}
@@ -508,30 +510,30 @@ void Model::DrawPrimitives()
//
// process vertices
//
for (int i = 0; i < (int)m_Meshes.size(); i++)
if( bUseTempVertices )
{
msMesh *pMesh = &m_Meshes[i];
RageModelVertexVector& TempVertices = m_vTempVerticesByBone[i];
for (int j = 0; j < (int)pMesh->Vertices.size(); j++)
for (int i = 0; i < (int)m_Meshes.size(); i++)
{
RageModelVertex& tempVert = TempVertices[j];
msVertex& originalVert = pMesh->Vertices[j];
memcpy( &tempVert.t, originalVert.uv, sizeof(originalVert.uv) );
if( originalVert.nBoneIndex == -1 )
msMesh *pMesh = &m_Meshes[i];
RageModelVertexVector& TempVertices = m_vTempVerticesByMesh[i];
for (int j = 0; j < (int)pMesh->Vertices.size(); j++)
{
memcpy( &tempVert.n, originalVert.Normal, sizeof(originalVert.Normal) );
memcpy( &tempVert.p, originalVert.Vertex, sizeof(originalVert.Vertex) );
}
else
{
int bone = originalVert.nBoneIndex;
RageModelVertex& tempVert = TempVertices[j];
RageModelVertex& originalVert = pMesh->Vertices[j];
RageVec3TransformNormal( &tempVert.n, &originalVert.Normal, &m_pBones[bone].mFinal );
RageVec3TransformCoord( &tempVert.p, &originalVert.Vertex, &m_pBones[bone].mFinal );
tempVert.t = originalVert.t;
if( originalVert.boneIndex == -1 )
{
tempVert.n = originalVert.n;
tempVert.p = originalVert.p;
}
else
{
int bone = originalVert.boneIndex;
RageVec3TransformNormal( &tempVert.n, &originalVert.n, &m_vpBones[bone].mFinal );
RageVec3TransformCoord( &tempVert.p, &originalVert.p, &m_vpBones[bone].mFinal );
}
}
}
}
@@ -546,7 +548,7 @@ void Model::DrawPrimitives()
for (int i = 0; i < (int)m_Meshes.size(); i++)
{
msMesh *pMesh = &m_Meshes[i];
RageModelVertexVector& TempVertices = m_vTempVerticesByBone[i];
RageModelVertexVector& TempVertices = bUseTempVertices ? m_vTempVerticesByMesh[i] : pMesh->Vertices;
if( pMesh->nMaterialIndex != -1 ) // has a material
{
@@ -616,7 +618,7 @@ void Model::DrawPrimitives()
for (int i = 0; i < (int)m_Meshes.size(); i++)
{
msMesh *pMesh = &m_Meshes[i];
RageModelVertexVector& TempVertices = m_vTempVerticesByBone[i];
RageModelVertexVector& TempVertices = m_vTempVerticesByMesh[i];
// apply material
if( pMesh->nMaterialIndex != -1 )
@@ -686,10 +688,7 @@ void Model::PlayAnimation( CString sAniName, float fPlayRate )
// setup bones
int nBoneCount = (int)m_pCurAnimation->Bones.size();
if (!m_pBones)
{
m_pBones = new myBone_t[nBoneCount];
}
m_vpBones.resize( nBoneCount );
int i, j;
for (i = 0; i < nBoneCount; i++)
@@ -700,23 +699,23 @@ void Model::PlayAnimation( CString sAniName, float fPlayRate )
vRot[1] = pBone->Rotation[1] * 180 / (float) PI;
vRot[2] = pBone->Rotation[2] * 180 / (float) PI;
RageMatrixAngles( &m_pBones[i].mRelative, vRot );
RageMatrixAngles( &m_vpBones[i].mRelative, vRot );
m_pBones[i].mRelative.m[3][0] = pBone->Position[0];
m_pBones[i].mRelative.m[3][1] = pBone->Position[1];
m_pBones[i].mRelative.m[3][2] = pBone->Position[2];
m_vpBones[i].mRelative.m[3][0] = pBone->Position[0];
m_vpBones[i].mRelative.m[3][1] = pBone->Position[1];
m_vpBones[i].mRelative.m[3][2] = pBone->Position[2];
int nParentBone = m_pCurAnimation->FindBoneByName( pBone->szParentName );
if (nParentBone != -1)
{
RageMatrixMultiply( &m_pBones[i].mAbsolute, &m_pBones[nParentBone].mAbsolute, &m_pBones[i].mRelative );
RageMatrixMultiply( &m_vpBones[i].mAbsolute, &m_vpBones[nParentBone].mAbsolute, &m_vpBones[i].mRelative );
m_pBones[i].mFinal = m_pBones[i].mAbsolute;
m_vpBones[i].mFinal = m_vpBones[i].mAbsolute;
}
else
{
m_pBones[i].mAbsolute = m_pBones[i].mRelative;
m_pBones[i].mFinal = m_pBones[i].mRelative;
m_vpBones[i].mAbsolute = m_vpBones[i].mRelative;
m_vpBones[i].mFinal = m_vpBones[i].mRelative;
}
}
@@ -725,19 +724,19 @@ void Model::PlayAnimation( CString sAniName, float fPlayRate )
msMesh *pMesh = &m_Meshes[i];
for (j = 0; j < (int)pMesh->Vertices.size(); j++)
{
msVertex *pVertex = &pMesh->Vertices[j];
if (pVertex->nBoneIndex != -1)
RageModelVertex *pVertex = &pMesh->Vertices[j];
if (pVertex->boneIndex != -1)
{
pVertex->Vertex[0] -= m_pBones[pVertex->nBoneIndex].mAbsolute.m[3][0];
pVertex->Vertex[1] -= m_pBones[pVertex->nBoneIndex].mAbsolute.m[3][1];
pVertex->Vertex[2] -= m_pBones[pVertex->nBoneIndex].mAbsolute.m[3][2];
pVertex->p[0] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][0];
pVertex->p[1] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][1];
pVertex->p[2] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][2];
RageVector3 vTmp;
RageMatrix inverse;
RageMatrixTranspose( &inverse, &m_pBones[pVertex->nBoneIndex].mAbsolute ); // transpose = inverse for rotation matrices
RageVec3TransformNormal( &vTmp, &pVertex->Vertex, &inverse );
RageMatrixTranspose( &inverse, &m_vpBones[pVertex->boneIndex].mAbsolute ); // transpose = inverse for rotation matrices
RageVec3TransformNormal( &vTmp, &pVertex->p, &inverse );
pVertex->Vertex = vTmp;
pVertex->p = vTmp;
}
}
}
@@ -779,7 +778,7 @@ Model::AdvanceFrame (float dt)
int nRotationKeyCount = pBone->RotationKeys.size();
if (nPositionKeyCount == 0 && nRotationKeyCount == 0)
{
m_pBones[i].mFinal = m_pBones[i].mAbsolute;
m_vpBones[i].mFinal = m_vpBones[i].mAbsolute;
}
else
{
@@ -860,16 +859,16 @@ Model::AdvanceFrame (float dt)
m.m[3][1] = vPos[1];
m.m[3][2] = vPos[2];
RageMatrixMultiply( &m_pBones[i].mRelativeFinal, &m_pBones[i].mRelative, &m );
RageMatrixMultiply( &m_vpBones[i].mRelativeFinal, &m_vpBones[i].mRelative, &m );
int nParentBone = m_pCurAnimation->FindBoneByName( pBone->szParentName );
if (nParentBone == -1)
{
m_pBones[i].mFinal = m_pBones[i].mRelativeFinal;
m_vpBones[i].mFinal = m_vpBones[i].mRelativeFinal;
}
else
{
RageMatrixMultiply( &m_pBones[i].mFinal, &m_pBones[nParentBone].mFinal, &m_pBones[i].mRelativeFinal );
RageMatrixMultiply( &m_vpBones[i].mFinal, &m_vpBones[nParentBone].mFinal, &m_vpBones[i].mRelativeFinal );
}
}
}
+9 -2
View File
@@ -60,9 +60,16 @@ private:
msAnimation* m_pCurAnimation;
RageVector3 m_vMins, m_vMaxs;
myBone_t *m_pBones;
vector<myBone_t> m_vpBones;
// true if any vertex has a bone weight.
// If true, then render from m_vTempVerticesByBone.
// Otherwise, render directly from the mesh's vertices
bool bUseTempVertices;
typedef vector<RageModelVertex> RageModelVertexVector;
vector<RageModelVertexVector> m_vTempVerticesByBone;
vector<RageModelVertexVector> m_vTempVerticesByMesh;
float m_fCurrFrame;
CString m_sDefaultAnimation;
float m_fDefaultAnimationRate;
+5 -2
View File
@@ -45,14 +45,16 @@ typedef enum {
} msFlag;
/* msVertex */
/*
typedef struct msVertex
{
// byte nFlags; // we don't care about saving this flag
RageVector3 Vertex;
RageVector2 uv;
RageVector3 Normal;
RageVector2 uv;
char nBoneIndex;
} msVertex;
*/
/* msTriangle */
typedef struct
@@ -71,7 +73,8 @@ typedef struct msMesh
char szName[MS_MAX_NAME];
char nMaterialIndex;
vector<msVertex> Vertices;
vector<RageModelVertex> Vertices;
// vector<msVertex> Vertices;
// vector<msVec3> Normals; // each vertex holds its own normal
+3
View File
@@ -11,6 +11,8 @@
-----------------------------------------------------------------------------
*/
#include "SDL_types.h" // for Sint8
/* These are shared between Actor and RageDisplay. I don't want to put this in
* Actor (because Rage shouldn't touch Actor) and I don't want to have Actor.h
* depend on RageDisplay (since that'd boost RDisplay.h a lot), so let's just
@@ -227,6 +229,7 @@ struct RageModelVertex // doesn't have color. Relies on material color
RageVector3 p; // position
RageVector3 n; // normal
RageVector2 t; // texture coordinates
Sint8 boneIndex;
};
// RageMatrix elements are specified in row-major order. This