From 85986fe32562d7a060a72ab20d1e1ba0d2560f75 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 4 May 2003 05:21:16 +0000 Subject: [PATCH] optimizing Model --- stepmania/src/Milkshape.h | 13 +- stepmania/src/Model.cpp | 305 +++++++++++++++++++++++++------- stepmania/src/Model.h | 6 +- stepmania/src/ScreenSandbox.cpp | 14 +- 4 files changed, 260 insertions(+), 78 deletions(-) diff --git a/stepmania/src/Milkshape.h b/stepmania/src/Milkshape.h index 096db60910..d819a5c79d 100644 --- a/stepmania/src/Milkshape.h +++ b/stepmania/src/Milkshape.h @@ -62,20 +62,21 @@ typedef enum { /* msVertex */ typedef struct msVertex { - byte nFlags; +// byte nFlags; msVec3 Vertex; msVec2 uv; + msVec3 Normal; char nBoneIndex; } msVertex; /* msTriangle */ typedef struct { - word nFlags; +// word nFlags; word nVertexIndices[3]; - word nNormalIndices[3]; - msVec3 Normal; - byte nSmoothingGroup; +// word nNormalIndices[3]; +// msVec3 Normal; +// byte nSmoothingGroup; } msTriangle; /* msMesh */ @@ -87,7 +88,7 @@ typedef struct msMesh vector Vertices; - vector Normals; +// vector Normals; vector Triangles; } msMesh; diff --git a/stepmania/src/Model.cpp b/stepmania/src/Model.cpp index f86144eb09..94fab3afd1 100644 --- a/stepmania/src/Model.cpp +++ b/stepmania/src/Model.cpp @@ -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 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; jnTotalFrames = 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; diff --git a/stepmania/src/Model.h b/stepmania/src/Model.h index 7140f0c3f4..3ce5d1f75e 100644 --- a/stepmania/src/Model.h +++ b/stepmania/src/Model.h @@ -13,6 +13,7 @@ #include "Actor.h" #include "RageTypes.h" +#include struct msModel; @@ -34,7 +35,8 @@ public: public: void Clear (); - bool Load( CString sPath ); + bool LoadMilkshapeAscii( CString sPath ); + bool LoadMilkshapeAsciiBones( CString sPath ); virtual void Update( float fDelta ); virtual void DrawPrimitives(); @@ -47,6 +49,8 @@ private: msModel *m_pModel; RageVector3 m_vMins, m_vMaxs; myBone_t *m_pBones; + typedef vector RageVertexVector; + vector m_vTempVerticesByBone; float m_fCurrFrame; }; diff --git a/stepmania/src/ScreenSandbox.cpp b/stepmania/src/ScreenSandbox.cpp index a9f733dc82..4610dc0d04 100644 --- a/stepmania/src/ScreenSandbox.cpp +++ b/stepmania/src/ScreenSandbox.cpp @@ -23,17 +23,21 @@ ScreenSandbox::ScreenSandbox() : Screen("ScreenSandbox") { m_quad.StretchTo( RectI(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) ); - m_quad.SetDiffuse( RageColor(1,1,1,1) ); -// this->AddChild( &m_quad ); + m_quad.SetDiffuse( RageColor(0,0,1,1) ); + m_quad.SetZ( -100 ); + this->AddChild( &m_quad ); // m_sprite.Load( "C:\\stepmania\\stepmania\\RandomMovies\\cm301[1].avi" ); // m_sprite.SetXY( CENTER_X, CENTER_Y ); // this->AddChild( &m_sprite ); m_model.SetXY(CENTER_X, CENTER_Y); - m_model.SetZoomX(5); - m_model.SetZoomY(5); - m_model.Load( "bend.txt" ); + m_model.SetZoomX(12); + m_model.SetZoomY(-12); +// m_model.SetY(0); +// m_model.LoadMilkshapeAscii( "bend.txt" ); + m_model.LoadMilkshapeAscii( "D:\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\char0000\\model.txt" ); + m_model.LoadMilkshapeAsciiBones( "D:\\Dev\\ddrpc char hacking\\DDRPCRip\\models\\howtoplay.bones.txt" ); this->AddChild(&m_model); m_model.SetEffectSpin( RageVector3(0,90,0) );