optimizing Model

This commit is contained in:
Chris Danford
2003-05-04 05:21:16 +00:00
parent b7c56989f4
commit 85986fe325
4 changed files with 260 additions and 78 deletions
+239 -66
View File
@@ -17,6 +17,8 @@
#include "RageTextureManager.h"
const float FRAMES_PER_SECOND = 30;
Model::Model ()
{
m_pModel = NULL;
@@ -30,21 +32,14 @@ Model::~Model ()
void Model::Clear ()
{
if (m_pBones)
{
delete m_pBones;
m_pBones = 0;
}
delete[] m_pBones;
m_pBones = NULL;
if (m_pModel)
{
// msModel_Destroy (m_pModel); // not necessary since conversion to std::vector
delete m_pModel;
m_pModel = 0;
}
delete m_pModel;
m_pModel = NULL;
}
bool Model::Load( CString sPath )
bool Model::LoadMilkshapeAscii( CString sPath )
{
CString sDir, sThrowAway;
splitrelpath( sPath, sDir, sThrowAway, sThrowAway );
@@ -83,10 +78,11 @@ bool Model::Load( CString sPath )
int nNumMeshes = 0;
if (sscanf (szLine, "Meshes: %d", &nNumMeshes) == 1)
{
m_pModel->Meshes.resize( nNumMeshes );
for (i = 0; i < nNumMeshes && !bError; i++)
{
m_pModel->Meshes.resize( m_pModel->Meshes.size()+1 );
msMesh& mesh = m_pModel->Meshes.back();
msMesh& mesh = m_pModel->Meshes[i];
if (!fgets (szLine, 256, file))
{
@@ -121,6 +117,8 @@ bool Model::Load( CString sPath )
break;
}
mesh.Vertices.resize( nNumVertices );
for (j = 0; j < nNumVertices; j++)
{
if (!fgets (szLine, 256, file))
@@ -142,15 +140,16 @@ bool Model::Load( CString sPath )
break;
}
mesh.Vertices.resize( mesh.Vertices.size()+1 );
msVertex& vertex = mesh.Vertices.back();
vertex.nFlags = nFlags;
msVertex& vertex = mesh.Vertices[j];
// vertex.nFlags = nFlags;
memcpy( vertex.Vertex, Vertex, sizeof(vertex.Vertex) );
memcpy( vertex.uv, uv, sizeof(vertex.uv) );
vertex.nBoneIndex = nIndex;
AddPointToBounds (Vertex, m_vMins, m_vMaxs);
}
//
// normals
//
@@ -166,7 +165,9 @@ bool Model::Load( CString sPath )
bError = true;
break;
}
vector<msVec3> Normals;
Normals.resize( nNumNormals );
for (j = 0; j < nNumNormals; j++)
{
if (!fgets (szLine, 256, file))
@@ -183,8 +184,11 @@ bool Model::Load( CString sPath )
}
VectorNormalize (Normal);
mesh.Normals.push_back( Normal );
Normals[j] = Normal;
}
//
// triangles
//
@@ -201,6 +205,8 @@ bool Model::Load( CString sPath )
break;
}
mesh.Triangles.resize( nNumTriangles );
for (j = 0; j < nNumTriangles; j++)
{
if (!fgets (szLine, 256, file))
@@ -222,26 +228,19 @@ bool Model::Load( CString sPath )
break;
}
mesh.Triangles.resize( mesh.Triangles.size()+1 );
msTriangle& Triangle = mesh.Triangles.back();
Triangle.nFlags = nFlags;
memcpy( &Triangle.nVertexIndices, nIndices, sizeof(Triangle.nVertexIndices) );
memcpy( &Triangle.nNormalIndices, nNormalIndices, sizeof(Triangle.nNormalIndices) );
Triangle.nSmoothingGroup = nIndex;
// deflate the normals into vertices
for( int k=0; k<3; k++ )
{
//
// calculate triangle normals
//
vec3_t v1, v2;
msVertex *pVertices[3];
pVertices[0] = &mesh.Vertices[ nIndices[0] ];
pVertices[1] = &mesh.Vertices[ nIndices[1] ];
pVertices[2] = &mesh.Vertices[ nIndices[2] ];
VectorSubtract (pVertices[0]->Vertex, pVertices[1]->Vertex, v1);
VectorSubtract (pVertices[2]->Vertex, pVertices[1]->Vertex, v2);
CrossProduct (v1, v2, Triangle.Normal);
VectorNormalize (Triangle.Normal);
VectorScale (Triangle.Normal, -1, Triangle.Normal);
msVertex& Vertex = mesh.Vertices[ nIndices[k] ];
msVec3& Normal = Normals[ nNormalIndices[k] ];
Vertex.Normal = Normal;
}
msTriangle& Triangle = mesh.Triangles[j];
// Triangle.nFlags = nFlags;
memcpy( &Triangle.nVertexIndices, nIndices, sizeof(Triangle.nVertexIndices) );
// Triangle.nSmoothingGroup = nIndex;
}
}
}
@@ -252,13 +251,14 @@ bool Model::Load( CString sPath )
int nNumMaterials = 0;
if (sscanf (szLine, "Materials: %d", &nNumMaterials) == 1)
{
int i;
m_pModel->Materials.resize( nNumMaterials );
int i;
char szName[MS_MAX_NAME];
for (i = 0; i < nNumMaterials && !bError; i++)
{
m_pModel->Materials.resize( m_pModel->Materials.size()+1 );
msMaterial& Material = m_pModel->Materials.back();
msMaterial& Material = m_pModel->Materials[i];
// name
if (!fgets (szLine, 256, file))
@@ -355,7 +355,7 @@ bool Model::Load( CString sPath )
bError = true;
break;
}
Material.fTransparency = 1.0f;
Material.fTransparency = fTransparency;
// diffuse texture
if (!fgets (szLine, 256, file))
@@ -398,10 +398,11 @@ bool Model::Load( CString sPath )
int i;
char szName[MS_MAX_NAME];
m_pModel->Bones.resize( nNumBones );
for (i = 0; i < nNumBones && !bError; i++)
{
m_pModel->Bones.resize( m_pModel->Bones.size()+1 );
msBone& Bone = m_pModel->Bones.back();
msBone& Bone = m_pModel->Bones[i];
// name
if (!fgets (szLine, 256, file))
@@ -416,7 +417,7 @@ bool Model::Load( CString sPath )
}
strcpy( Bone.szName, szName );
// alpha texture
// parent
if (!fgets (szLine, 256, file))
{
bError = true;
@@ -461,6 +462,8 @@ bool Model::Load( CString sPath )
break;
}
Bone.PositionKeys.resize( nNumPositionKeys );
for (j = 0; j < nNumPositionKeys; j++)
{
if (!fgets (szLine, 256, file))
@@ -475,7 +478,7 @@ bool Model::Load( CString sPath )
}
msPositionKey key = { fTime, { Position[0], Position[1], Position[2] } };
Bone.PositionKeys.push_back( key );
Bone.PositionKeys[j] = key;
}
// rotation key count
@@ -491,6 +494,8 @@ bool Model::Load( CString sPath )
break;
}
Bone.RotationKeys.resize( nNumRotationKeys );
for (j = 0; j < nNumRotationKeys; j++)
{
if (!fgets (szLine, 256, file))
@@ -505,7 +510,7 @@ bool Model::Load( CString sPath )
}
msRotationKey key = { fTime, { Rotation[0], Rotation[1], Rotation[2] } };
Bone.RotationKeys.push_back( key );
Bone.RotationKeys[j] = key;
}
}
}
@@ -513,6 +518,176 @@ bool Model::Load( CString sPath )
fclose (file);
LoadMilkshapeAsciiBones( sPath );
// Setup temp vertices
m_vTempVerticesByBone.resize( m_pModel->Meshes.size() );
for (i = 0; i < m_pModel->Meshes.size(); i++)
{
msMesh& Mesh = m_pModel->Meshes[i];
m_vTempVerticesByBone[i].resize( Mesh.Vertices.size() );
}
return true;
}
bool Model::LoadMilkshapeAsciiBones( CString sPath )
{
CString sDir, sThrowAway;
splitrelpath( sPath, sDir, sThrowAway, sThrowAway );
FILE *file = fopen (sPath, "rt");
if (!file)
return false;
bool bError = false;
char szLine[256];
int nFlags, j;
while (fgets (szLine, 256, file) != NULL && !bError)
{
if (!strncmp (szLine, "//", 2))
continue;
//
// bones
//
int nNumBones = 0;
if (sscanf (szLine, "Bones: %d", &nNumBones) == 1)
{
int i;
char szName[MS_MAX_NAME];
m_pModel->Bones.resize( nNumBones );
for (i = 0; i < nNumBones && !bError; i++)
{
msBone& Bone = m_pModel->Bones[i];
// name
if (!fgets (szLine, 256, file))
{
bError = true;
break;
}
if (sscanf (szLine, "\"%[^\"]\"", szName) != 1)
{
bError = true;
break;
}
strcpy( Bone.szName, szName );
// parent
if (!fgets (szLine, 256, file))
{
bError = true;
break;
}
strcpy (szName, "");
sscanf (szLine, "\"%[^\"]\"", szName);
strcpy( Bone.szParentName, szName );
// flags, position, rotation
msVec3 Position, Rotation;
if (!fgets (szLine, 256, file))
{
bError = true;
break;
}
if (sscanf (szLine, "%d %f %f %f %f %f %f",
&nFlags,
&Position.v[0], &Position.v[1], &Position.v[2],
&Rotation.v[0], &Rotation.v[1], &Rotation.v[2]) != 7)
{
bError = true;
break;
}
Bone.nFlags = nFlags;
memcpy( &Bone.Position, &Position, sizeof(Bone.Position) );
memcpy( &Bone.Rotation, &Rotation, sizeof(Bone.Rotation) );
float fTime;
// position key count
if (!fgets (szLine, 256, file))
{
bError = true;
break;
}
int nNumPositionKeys = 0;
if (sscanf (szLine, "%d", &nNumPositionKeys) != 1)
{
bError = true;
break;
}
Bone.PositionKeys.resize( nNumPositionKeys );
for (j = 0; j < nNumPositionKeys; j++)
{
if (!fgets (szLine, 256, file))
{
bError = true;
break;
}
if (sscanf (szLine, "%f %f %f %f", &fTime, &Position[0], &Position[1], &Position[2]) != 4)
{
bError = true;
break;
}
msPositionKey key = { fTime, { Position[0], Position[1], Position[2] } };
Bone.PositionKeys[j] = key;
}
// rotation key count
if (!fgets (szLine, 256, file))
{
bError = true;
break;
}
int nNumRotationKeys = 0;
if (sscanf (szLine, "%d", &nNumRotationKeys) != 1)
{
bError = true;
break;
}
Bone.RotationKeys.resize( nNumRotationKeys );
for (j = 0; j < nNumRotationKeys; j++)
{
if (!fgets (szLine, 256, file))
{
bError = true;
break;
}
if (sscanf (szLine, "%f %f %f %f", &fTime, &Rotation[0], &Rotation[1], &Rotation[2]) != 4)
{
bError = true;
break;
}
msRotationKey key = { fTime, { Rotation[0], Rotation[1], Rotation[2] } };
Bone.RotationKeys[j] = key;
}
}
}
}
// ignore "Frames:" in file
m_pModel->nTotalFrames = 0;
for (int i = 0; i < m_pModel->Bones.size(); i++)
{
msBone& Bone = m_pModel->Bones[i];
for( int j=0; j<Bone.PositionKeys.size(); j++ )
{
m_pModel->nTotalFrames = max( m_pModel->nTotalFrames, Bone.PositionKeys[j].fTime );
m_pModel->nTotalFrames = max( m_pModel->nTotalFrames, Bone.RotationKeys[j].fTime );
}
}
SetupBones ();
return true;
@@ -532,9 +707,9 @@ void Model::DrawPrimitives()
DISPLAY->SetLightDirectional(
0,
RageColor(0.2f,0.2f,0.2f,1),
RageColor(1,1,1,1),
RageColor(1,1,1,1),
RageVector3(0, 0, +1) );
RageColor(0.8f,0.8f,0.8f,0.8f),
RageColor(0.8f,0.8f,0.8f,0.8f),
RageVector3(+1, 0, +1) );
for (int i = 0; i < (int)m_pModel->Meshes.size(); i++)
@@ -576,36 +751,34 @@ void Model::DrawPrimitives()
RageVertex verts[3];
msTriangle *pTriangle = &pMesh->Triangles[j];
word nIndices[3], nNormalIndices[3];
word nIndices[3];//, nNormalIndices[3];
memcpy( nIndices, pTriangle->nVertexIndices, sizeof(nIndices) );
memcpy( nNormalIndices, pTriangle->nNormalIndices, sizeof(nNormalIndices) );
// memcpy( nNormalIndices, pTriangle->nNormalIndices, sizeof(nNormalIndices) );
for (int k = 0; k < 3; k++)
{
RageVertex& v = verts[k];
msVec3 *normal = &pMesh->Normals[ nNormalIndices[k] ];
v.n.x = normal->v[0];
v.n.y = normal->v[1];
v.n.z = normal->v[2];
glNormal3fv( normal->v );
msVertex *pVertex = &pMesh->Vertices[ nIndices[k] ];
v.c = RageColor(1,1,1,1);
v.t.x = pVertex->uv[0];
v.t.y = pVertex->uv[1];
glTexCoord2f( pVertex->uv[0], pVertex->uv[1] );
float white[4] = {1,1,0,1};
glColor4fv( white );
v.t.x = pVertex->uv[0];
v.t.y = pVertex->uv[1];
glTexCoord2f( pVertex->uv[0], pVertex->uv[1] );
v.n.x = pVertex->Normal[0];
v.n.y = pVertex->Normal[1];
v.n.z = pVertex->Normal[2];
glNormal3fv( pVertex->Normal );
if (pVertex->nBoneIndex == -1)
{
v.p.x = pVertex->Vertex[0];
v.p.y = pVertex->Vertex[1];
v.p.z = pVertex->Vertex[2];
glVertex3fv( pVertex->Vertex );
glVertex3fv( &v.p.x );
}
else
{
@@ -708,7 +881,7 @@ Model::AdvanceFrame (float dt)
if (!m_pModel)
return;
m_fCurrFrame += dt;
m_fCurrFrame += FRAMES_PER_SECOND * dt;
if (m_fCurrFrame > (float) m_pModel->nTotalFrames)
m_fCurrFrame = 0.0f;