diff --git a/stepmania/src/Model.cpp b/stepmania/src/Model.cpp index 792492b1f1..f5df8b3c56 100644 --- a/stepmania/src/Model.cpp +++ b/stepmania/src/Model.cpp @@ -267,139 +267,16 @@ void Model::LoadMaterialsFromMilkshapeAscii( CString sPath ) bool Model::LoadMilkshapeAsciiBones( CString sAniName, CString sPath ) { - FixSlashesInPlace(sPath); - const CString sDir = Dirname( sPath ); + m_mapNameToAnimation[sAniName] = msAnimation(); + msAnimation &Animation = m_mapNameToAnimation[sAniName]; - RageFile f; - if ( !f.Open(sPath) ) - RageException::Throw( "Model:: Could not open \"%s\": %s", sPath.c_str(), f.GetError().c_str() ); - - CString sLine; - int iLineNum = 0; - - bool bLoaded = false; - while( f.GetLine( sLine ) > 0 ) - { - iLineNum++; - - if (!strncmp (sLine, "//", 2)) - continue; - - // - // bones - // - int nNumBones = 0; - if( sscanf (sLine, "Bones: %d", &nNumBones) != 1 ) - continue; - - m_mapNameToAnimation[sAniName] = msAnimation(); - msAnimation &Animation = m_mapNameToAnimation[sAniName]; - - char szName[MS_MAX_NAME]; - - Animation.Bones.resize( nNumBones ); - - for( int i = 0; i < nNumBones; i++ ) - { - msBone& Bone = Animation.Bones[i]; - - // name - if( f.GetLine( sLine ) <= 0 ) - THROW; - if (sscanf (sLine, "\"%[^\"]\"", szName) != 1) - THROW; - strcpy( Bone.szName, szName ); - - // parent - if( f.GetLine( sLine ) <= 0 ) - THROW; - strcpy (szName, ""); - sscanf (sLine, "\"%[^\"]\"", szName); - - strcpy( Bone.szParentName, szName ); - - // flags, position, rotation - RageVector3 Position, Rotation; - if( f.GetLine( sLine ) <= 0 ) - THROW; - - int nFlags; - if (sscanf (sLine, "%d %f %f %f %f %f %f", - &nFlags, - &Position[0], &Position[1], &Position[2], - &Rotation[0], &Rotation[1], &Rotation[2]) != 7) - { - THROW; - } - Rotation = RadianToDegree(Rotation); - - Bone.nFlags = nFlags; - memcpy( &Bone.Position, &Position, sizeof(Bone.Position) ); - memcpy( &Bone.Rotation, &Rotation, sizeof(Bone.Rotation) ); - - // position key count - if( f.GetLine( sLine ) <= 0 ) - THROW; - int nNumPositionKeys = 0; - if (sscanf (sLine, "%d", &nNumPositionKeys) != 1) - THROW; - - Bone.PositionKeys.resize( nNumPositionKeys ); - - for( int j = 0; j < nNumPositionKeys; ++j ) - { - if( f.GetLine( sLine ) <= 0 ) - THROW; - - float fTime; - if (sscanf (sLine, "%f %f %f %f", &fTime, &Position[0], &Position[1], &Position[2]) != 4) - THROW; - - msPositionKey key; - key.fTime = fTime; - key.Position = RageVector3( Position[0], Position[1], Position[2] ); - Bone.PositionKeys[j] = key; - } - - // rotation key count - if( f.GetLine( sLine ) <= 0 ) - THROW; - int nNumRotationKeys = 0; - if (sscanf (sLine, "%d", &nNumRotationKeys) != 1) - THROW; - - Bone.RotationKeys.resize( nNumRotationKeys ); - - for( int j = 0; j < nNumRotationKeys; ++j ) - { - if( f.GetLine( sLine ) <= 0 ) - THROW; - - float fTime; - if (sscanf (sLine, "%f %f %f %f", &fTime, &Rotation[0], &Rotation[1], &Rotation[2]) != 4) - THROW; - Rotation = RadianToDegree(Rotation); - - msRotationKey key; - key.fTime = fTime; - key.Rotation = RageVector3( Rotation[0], Rotation[1], Rotation[2] ); - Bone.RotationKeys[j] = key; - } - } - - // Ignore "Frames:" in file. Calculate it ourself - Animation.nTotalFrames = 0; - for( int i = 0; i < (int)Animation.Bones.size(); i++ ) - { - msBone& Bone = Animation.Bones[i]; - for( unsigned j = 0; j < Bone.PositionKeys.size(); ++j ) - Animation.nTotalFrames = max( Animation.nTotalFrames, (int)Bone.PositionKeys[j].fTime ); - for( unsigned j = 0; j < Bone.RotationKeys.size(); ++j ) - Animation.nTotalFrames = max( Animation.nTotalFrames, (int)Bone.RotationKeys[j].fTime ); - } + if( Animation.LoadMilkshapeAsciiBones( sAniName, sPath ) ) + { + m_mapNameToAnimation.erase( sAniName ); + return false; } - return bLoaded; + return true; } bool Model::EarlyAbortDraw() diff --git a/stepmania/src/ModelTypes.cpp b/stepmania/src/ModelTypes.cpp index 1d9e9b896f..f62b2d52a0 100644 --- a/stepmania/src/ModelTypes.cpp +++ b/stepmania/src/ModelTypes.cpp @@ -2,6 +2,8 @@ #include "ModelTypes.h" #include "IniFile.h" #include "RageUtil.h" +#include "RageFile.h" +#include "RageMath.h" #include "RageTexture.h" #include "RageTextureManager.h" #include "RageLog.h" @@ -177,6 +179,144 @@ msMesh::~msMesh() { } +#define THROW RageException::Throw( "Parse error in \"%s\" at line %d: '%s'", sPath.c_str(), iLineNum, sLine.c_str() ) + +bool msAnimation::LoadMilkshapeAsciiBones( CString sAniName, CString sPath ) +{ + FixSlashesInPlace(sPath); + const CString sDir = Dirname( sPath ); + + RageFile f; + if ( !f.Open(sPath) ) + RageException::Throw( "Model:: Could not open \"%s\": %s", sPath.c_str(), f.GetError().c_str() ); + + CString sLine; + int iLineNum = 0; + + msAnimation &Animation = *this; + + bool bLoaded = false; + while( f.GetLine( sLine ) > 0 ) + { + iLineNum++; + + if (!strncmp (sLine, "//", 2)) + continue; + + // + // bones + // + int nNumBones = 0; + if( sscanf (sLine, "Bones: %d", &nNumBones) != 1 ) + continue; + + char szName[MS_MAX_NAME]; + + Animation.Bones.resize( nNumBones ); + + for( int i = 0; i < nNumBones; i++ ) + { + msBone& Bone = Animation.Bones[i]; + + // name + if( f.GetLine( sLine ) <= 0 ) + THROW; + if (sscanf (sLine, "\"%[^\"]\"", szName) != 1) + THROW; + strcpy( Bone.szName, szName ); + + // parent + if( f.GetLine( sLine ) <= 0 ) + THROW; + strcpy (szName, ""); + sscanf (sLine, "\"%[^\"]\"", szName); + + strcpy( Bone.szParentName, szName ); + + // flags, position, rotation + RageVector3 Position, Rotation; + if( f.GetLine( sLine ) <= 0 ) + THROW; + + int nFlags; + if (sscanf (sLine, "%d %f %f %f %f %f %f", + &nFlags, + &Position[0], &Position[1], &Position[2], + &Rotation[0], &Rotation[1], &Rotation[2]) != 7) + { + THROW; + } + Rotation = RadianToDegree(Rotation); + + Bone.nFlags = nFlags; + memcpy( &Bone.Position, &Position, sizeof(Bone.Position) ); + memcpy( &Bone.Rotation, &Rotation, sizeof(Bone.Rotation) ); + + // position key count + if( f.GetLine( sLine ) <= 0 ) + THROW; + int nNumPositionKeys = 0; + if (sscanf (sLine, "%d", &nNumPositionKeys) != 1) + THROW; + + Bone.PositionKeys.resize( nNumPositionKeys ); + + for( int j = 0; j < nNumPositionKeys; ++j ) + { + if( f.GetLine( sLine ) <= 0 ) + THROW; + + float fTime; + if (sscanf (sLine, "%f %f %f %f", &fTime, &Position[0], &Position[1], &Position[2]) != 4) + THROW; + + msPositionKey key; + key.fTime = fTime; + key.Position = RageVector3( Position[0], Position[1], Position[2] ); + Bone.PositionKeys[j] = key; + } + + // rotation key count + if( f.GetLine( sLine ) <= 0 ) + THROW; + int nNumRotationKeys = 0; + if (sscanf (sLine, "%d", &nNumRotationKeys) != 1) + THROW; + + Bone.RotationKeys.resize( nNumRotationKeys ); + + for( int j = 0; j < nNumRotationKeys; ++j ) + { + if( f.GetLine( sLine ) <= 0 ) + THROW; + + float fTime; + if (sscanf (sLine, "%f %f %f %f", &fTime, &Rotation[0], &Rotation[1], &Rotation[2]) != 4) + THROW; + Rotation = RadianToDegree(Rotation); + + msRotationKey key; + key.fTime = fTime; + key.Rotation = RageVector3( Rotation[0], Rotation[1], Rotation[2] ); + Bone.RotationKeys[j] = key; + } + } + + // Ignore "Frames:" in file. Calculate it ourself + Animation.nTotalFrames = 0; + for( int i = 0; i < (int)Animation.Bones.size(); i++ ) + { + msBone& Bone = Animation.Bones[i]; + for( unsigned j = 0; j < Bone.PositionKeys.size(); ++j ) + Animation.nTotalFrames = max( Animation.nTotalFrames, (int)Bone.PositionKeys[j].fTime ); + for( unsigned j = 0; j < Bone.RotationKeys.size(); ++j ) + Animation.nTotalFrames = max( Animation.nTotalFrames, (int)Bone.RotationKeys[j].fTime ); + } + } + + return bLoaded; +} + /* * (c) 2003-2004 Chris Danford * All rights reserved. diff --git a/stepmania/src/ModelTypes.h b/stepmania/src/ModelTypes.h index 0efaa3965f..ae6b18d211 100644 --- a/stepmania/src/ModelTypes.h +++ b/stepmania/src/ModelTypes.h @@ -124,6 +124,8 @@ struct msAnimation return -1; } + bool LoadMilkshapeAsciiBones( CString sAniName, CString sPath ); + int nTotalFrames; RageVector3 Position;