optimize meshes where all vertices are associated with the same bone
This commit is contained in:
+36
-6
@@ -111,7 +111,22 @@ void Model::LoadPieces( CString sMeshesPath, CString sMaterialsPath, CString sBo
|
|||||||
//
|
//
|
||||||
// Setup temp vertices (if necessary)
|
// Setup temp vertices (if necessary)
|
||||||
//
|
//
|
||||||
m_bUseTempVertices = m_mapNameToAnimation[DEFAULT_ANIMATION_NAME].Bones.size() > 0; // if there are no bones, then there's no reason to use temp vertices
|
bool bHasAnyPerVertexBones = false;
|
||||||
|
for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++)
|
||||||
|
{
|
||||||
|
msMesh& mesh = m_pGeometry->m_Meshes[i];
|
||||||
|
for (int j = 0; j < (int)mesh.Vertices.size(); j++)
|
||||||
|
{
|
||||||
|
RageModelVertex &vert = mesh.Vertices[j];
|
||||||
|
if( vert.boneIndex != -1 )
|
||||||
|
{
|
||||||
|
bHasAnyPerVertexBones = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bUseTempVertices = bHasAnyPerVertexBones;
|
||||||
if( m_bUseTempVertices )
|
if( m_bUseTempVertices )
|
||||||
{
|
{
|
||||||
m_vTempVerticesByMesh.resize( m_pGeometry->m_Meshes.size() );
|
m_vTempVerticesByMesh.resize( m_pGeometry->m_Meshes.size() );
|
||||||
@@ -476,9 +491,6 @@ void Model::DrawPrimitives()
|
|||||||
// UGLY: This overrides the Actor's BlendMode
|
// UGLY: This overrides the Actor's BlendMode
|
||||||
DISPLAY->SetTextureModeAdd();
|
DISPLAY->SetTextureModeAdd();
|
||||||
}
|
}
|
||||||
|
|
||||||
DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 );
|
|
||||||
DISPLAY->SetSphereEnironmentMapping( false );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -495,7 +507,23 @@ void Model::DrawPrimitives()
|
|||||||
shininess );
|
shininess );
|
||||||
DISPLAY->ClearAllTextures();
|
DISPLAY->ClearAllTextures();
|
||||||
DISPLAY->SetSphereEnironmentMapping( false );
|
DISPLAY->SetSphereEnironmentMapping( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply mesh-specific bone (if any)
|
||||||
|
if( pMesh->nBoneIndex != -1 )
|
||||||
|
{
|
||||||
|
DISPLAY->PushMatrix();
|
||||||
|
|
||||||
|
RageMatrix &mat = m_vpBones[pMesh->nBoneIndex].mFinal;
|
||||||
|
DISPLAY->PreMultMatrix( mat );
|
||||||
|
}
|
||||||
|
|
||||||
DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 );
|
DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 );
|
||||||
|
DISPLAY->SetSphereEnironmentMapping( false );
|
||||||
|
|
||||||
|
if( pMesh->nBoneIndex != -1 )
|
||||||
|
{
|
||||||
|
DISPLAY->PopMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -611,12 +639,14 @@ void Model::PlayAnimation( CString sAniName, float fPlayRate )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subtract out the bone's resting position
|
||||||
for (i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++)
|
for (i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++)
|
||||||
{
|
{
|
||||||
msMesh *pMesh = &m_pGeometry->m_Meshes[i];
|
msMesh *pMesh = &m_pGeometry->m_Meshes[i];
|
||||||
for (j = 0; j < (int)pMesh->Vertices.size(); j++)
|
for (j = 0; j < (int)pMesh->Vertices.size(); j++)
|
||||||
{
|
{
|
||||||
RageModelVertex *pVertex = &pMesh->Vertices[j];
|
RageModelVertex *pVertex = &pMesh->Vertices[j];
|
||||||
|
int nBoneIndex = (pMesh->nBoneIndex!=-1) ? pMesh->nBoneIndex : pVertex->boneIndex;
|
||||||
if (pVertex->boneIndex != -1)
|
if (pVertex->boneIndex != -1)
|
||||||
{
|
{
|
||||||
pVertex->p[0] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][0];
|
pVertex->p[0] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][0];
|
||||||
@@ -785,9 +815,9 @@ void Model::Update( float fDelta )
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// process vertices
|
// process per-vertex bones
|
||||||
//
|
//
|
||||||
if( m_bUseTempVertices && m_pGeometry )
|
if( m_pGeometry && m_bUseTempVertices )
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++)
|
for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
Chris Danford
|
Chris Danford
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "Model.h"
|
#include "RageModelGeometry.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ typedef struct msMesh
|
|||||||
|
|
||||||
// vector<msVec3> Normals; // each vertex holds its own normal
|
// vector<msVec3> Normals; // each vertex holds its own normal
|
||||||
|
|
||||||
|
// OPTIMIZATION: If all verts in a mesh are transformed by the same bone,
|
||||||
|
// then send the transform to the graphics card for the whole mesh instead
|
||||||
|
// of transforming each vertex on the CPU;
|
||||||
|
char nBoneIndex; // -1 = no bone
|
||||||
|
|
||||||
vector<msTriangle> Triangles;
|
vector<msTriangle> Triangles;
|
||||||
} msMesh;
|
} msMesh;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,41 @@ RageModelGeometry::~RageModelGeometry ()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RageModelGeometry::OptimizeBones()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < m_Meshes.size(); i++)
|
||||||
|
{
|
||||||
|
msMesh& mesh = m_Meshes[i];
|
||||||
|
|
||||||
|
// check to see if all vertices have the same bone index
|
||||||
|
bool bAllVertsUseSameBone = true;
|
||||||
|
char nBoneIndex = !mesh.Vertices.empty() ? mesh.Vertices[0].boneIndex : -1;
|
||||||
|
if( nBoneIndex != -1 )
|
||||||
|
{
|
||||||
|
for (unsigned j = 1; j < mesh.Vertices.size(); j++)
|
||||||
|
{
|
||||||
|
RageModelVertex& vertex = mesh.Vertices[j];
|
||||||
|
if( vertex.boneIndex != nBoneIndex )
|
||||||
|
{
|
||||||
|
bAllVertsUseSameBone = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( bAllVertsUseSameBone )
|
||||||
|
{
|
||||||
|
mesh.nBoneIndex = nBoneIndex;
|
||||||
|
|
||||||
|
// clear all vertex/bone associations;
|
||||||
|
for (unsigned j = 0; j < mesh.Vertices.size(); j++)
|
||||||
|
{
|
||||||
|
RageModelVertex& vertex = mesh.Vertices[j];
|
||||||
|
vertex.boneIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define THROW RageException::Throw( "Parse at line %d: '%s'", sLine.c_str() );
|
#define THROW RageException::Throw( "Parse at line %d: '%s'", sLine.c_str() );
|
||||||
|
|
||||||
void RageModelGeometry::LoadMilkshapeAscii( CString sPath )
|
void RageModelGeometry::LoadMilkshapeAscii( CString sPath )
|
||||||
@@ -81,6 +116,8 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath )
|
|||||||
// mesh.nFlags = nFlags;
|
// mesh.nFlags = nFlags;
|
||||||
mesh.nMaterialIndex = (byte)nIndex;
|
mesh.nMaterialIndex = (byte)nIndex;
|
||||||
|
|
||||||
|
mesh.nBoneIndex = -1;
|
||||||
|
|
||||||
//
|
//
|
||||||
// vertices
|
// vertices
|
||||||
//
|
//
|
||||||
@@ -119,7 +156,6 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// normals
|
// normals
|
||||||
//
|
//
|
||||||
@@ -193,6 +229,8 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptimizeBones();
|
||||||
|
|
||||||
f.Close();
|
f.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void LoadMilkshapeAscii( CString sMilkshapeAsciiFile );
|
void LoadMilkshapeAscii( CString sMilkshapeAsciiFile );
|
||||||
|
void OptimizeBones();
|
||||||
|
|
||||||
int m_iRefCount;
|
int m_iRefCount;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user