From 1660ed310ab0c85ddb1e514e55fa2ca383eb2971 Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Mon, 8 Oct 2012 21:50:20 +0200 Subject: [PATCH] Add support for the OGRE 1.8 binary mesh format --- src/lib/StdMeshLoaderBinary.cpp | 10 ++++++- src/lib/StdMeshLoaderBinaryChunks.cpp | 41 +++++++++++++++++++++++---- src/lib/StdMeshLoaderBinaryChunks.h | 26 +++++++++++++++-- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/lib/StdMeshLoaderBinary.cpp b/src/lib/StdMeshLoaderBinary.cpp index fbf2befff..fb3d888d0 100644 --- a/src/lib/StdMeshLoaderBinary.cpp +++ b/src/lib/StdMeshLoaderBinary.cpp @@ -294,13 +294,21 @@ void StdMeshLoader::LoadSkeletonBinary(StdMesh *mesh, const char *src, size_t si boost::ptr_map bones; boost::ptr_vector animations; for (Ogre::Skeleton::ChunkID id = Ogre::Skeleton::Chunk::Peek(&stream); - id == Ogre::Skeleton::CID_Bone || id == Ogre::Skeleton::CID_Bone_Parent || id == Ogre::Skeleton::CID_Animation; + id == Ogre::Skeleton::CID_BlendMode || id == Ogre::Skeleton::CID_Bone || id == Ogre::Skeleton::CID_Bone_Parent || id == Ogre::Skeleton::CID_Animation; id = Ogre::Skeleton::Chunk::Peek(&stream) ) { std::auto_ptr chunk(Ogre::Skeleton::Chunk::Read(&stream)); switch (chunk->GetType()) { + case Ogre::Skeleton::CID_BlendMode: + { + Ogre::Skeleton::ChunkBlendMode& cblend = *static_cast(chunk.get()); + // TODO: Handle it + if(cblend.blend_mode != 0) // 0 is average, 1 is cumulative. I'm actually not sure what the difference really is... anyway we implement only one method yet. I think it's average, but not 100% sure. + LogF("StdMeshLoader: CID_BlendMode not implemented."); + } + break; case Ogre::Skeleton::CID_Bone: { Ogre::Skeleton::ChunkBone &cbone = *static_cast(chunk.get()); diff --git a/src/lib/StdMeshLoaderBinaryChunks.cpp b/src/lib/StdMeshLoaderBinaryChunks.cpp index d94c70f12..93793bdec 100644 --- a/src/lib/StdMeshLoaderBinaryChunks.cpp +++ b/src/lib/StdMeshLoaderBinaryChunks.cpp @@ -27,10 +27,12 @@ namespace Ogre { namespace Mesh { - const uint32_t ChunkFileHeader::CurrentVersion = 1041; // Major * 1000 + Minor + const uint32_t ChunkFileHeader::CurrentVersion = 1080; // Major * 1000 + Minor const std::map ChunkFileHeader::VersionTable = boost::assign::map_list_of - // 1.41: Current version - ("[MeshSerializer_v1.41]", CurrentVersion) + // 1.8: Current version + ("[MeshSerializer_v1.8]", CurrentVersion) + // 1.41: Changes to morph keyframes and poses. We don't use either, so no special handling needed + ("[MeshSerializer_v1.41]", 1041) // 1.40: Changes to CID_Mesh_LOD chunks, we ignore those, so no special handling needed ("[MeshSerializer_v1.40]", 1040); @@ -334,7 +336,12 @@ namespace Ogre namespace Skeleton { - const std::string ChunkFileHeader::ExpectedVersion("[Serializer_v1.10]"); + const uint32_t ChunkFileHeader::CurrentVersion = 1080; // Major * 1000 + Minor + const std::map ChunkFileHeader::VersionTable = boost::assign::map_list_of + // 1.80: Current version + ("[Serializer_v1.80]", CurrentVersion) + // 1.10: adds SKELETON_BLENDMODE and SKELETON_ANIMATION_BASEINFO chunks. The chunks have been added to the loader, but we ignore them for now. + ("[Serializer_v1.10]", 1010); Chunk *Chunk::Read(DataStream *stream) { @@ -357,9 +364,11 @@ namespace Ogre switch (id) { case CID_Header: chunk.reset(new ChunkFileHeader()); break; + case CID_BlendMode: chunk.reset(new ChunkBlendMode()); break; case CID_Bone: chunk.reset(new ChunkBone()); break; case CID_Bone_Parent: chunk.reset(new ChunkBoneParent()); break; case CID_Animation: chunk.reset(new ChunkAnimation()); break; + case CID_Animation_BaseInfo: chunk.reset(new ChunkAnimationBaseInfo()); break; case CID_Animation_Track: chunk.reset(new ChunkAnimationTrack()); break; case CID_Animation_Track_KF: chunk.reset(new ChunkAnimationTrackKF()); break; case CID_Animation_Link: chunk.reset(new ChunkAnimationLink()); break; @@ -378,11 +387,16 @@ namespace Ogre void ChunkFileHeader::ReadImpl(DataStream *stream) { // Simple version check - version = stream->Read(); - if (version != ExpectedVersion) + VersionTable_t::const_iterator it = VersionTable.find(stream->Read()); + if (it == VersionTable.end()) throw InvalidVersion(); } + void ChunkBlendMode::ReadImpl(DataStream* stream) + { + blend_mode = stream->Read(); + } + void ChunkBone::ReadImpl(DataStream *stream) { name = stream->Read(); @@ -417,6 +431,15 @@ namespace Ogre { name = stream->Read(); duration = stream->Read(); + + if(!stream->AtEof() && Chunk::Peek(stream) == CID_Animation_BaseInfo) + { + Chunk* chunk = Chunk::Read(stream); + assert(chunk->GetType() == CID_Animation_BaseInfo); + // TODO: Handle it + LogF("StdMeshLoader: CID_Animation_BaseInfo not implemented. Skeleton might not be imported properly."); + } + while (!stream->AtEof() && Chunk::Peek(stream) == CID_Animation_Track) { Chunk *chunk = Chunk::Read(stream); @@ -425,6 +448,12 @@ namespace Ogre } } + void ChunkAnimationBaseInfo::ReadImpl(DataStream* stream) + { + base_animation_name = stream->Read(); + base_key_frame_time = stream->Read(); + } + void ChunkAnimationTrack::ReadImpl(DataStream *stream) { bone = stream->Read(); diff --git a/src/lib/StdMeshLoaderBinaryChunks.h b/src/lib/StdMeshLoaderBinaryChunks.h index 3fa6d2a3d..66a1b8686 100644 --- a/src/lib/StdMeshLoaderBinaryChunks.h +++ b/src/lib/StdMeshLoaderBinaryChunks.h @@ -353,7 +353,8 @@ namespace Ogre static Chunk *Read(DataStream *stream); }; - class ChunkUnknown; class ChunkFileHeader; + class ChunkUnknown; class + ChunkFileHeader; class ChunkMesh; class ChunkMeshSkeletonLink; class ChunkMeshBoneAssignments; class ChunkMeshBounds; class ChunkSubmesh; class ChunkSubmeshOp; class ChunkGeometry; class ChunkGeometryVertexDecl; class ChunkGeometryVertexDeclElement; class ChunkGeometryVertexBuffer; class ChunkGeometryVertexData; @@ -538,9 +539,11 @@ namespace Ogre { CID_Invalid = 0, CID_Header = 0x1000, + CID_BlendMode= 0x1010, CID_Bone = 0x2000, CID_Bone_Parent = 0x3000, CID_Animation = 0x4000, + CID_Animation_BaseInfo = 0x4010, CID_Animation_Track = 0x4100, CID_Animation_Track_KF = 0x4110, CID_Animation_Link = 0x5000 @@ -564,7 +567,9 @@ namespace Ogre class ChunkFileHeader : public Chunk { - static const std::string ExpectedVersion; + typedef std::map VersionTable_t; + static const VersionTable_t VersionTable; + static const uint32_t CurrentVersion; public: std::string version; @@ -572,6 +577,14 @@ namespace Ogre virtual void ReadImpl(DataStream *stream); }; + class ChunkBlendMode : public Chunk + { + public: + uint16_t blend_mode; + protected: + virtual void ReadImpl(DataStream* stream); + }; + class ChunkBone : public Chunk { public: @@ -604,6 +617,15 @@ namespace Ogre virtual void ReadImpl(DataStream *stream); }; + class ChunkAnimationBaseInfo : public Chunk + { + public: + std::string base_animation_name; + float base_key_frame_time; + protected: + virtual void ReadImpl(DataStream* stream); + }; + class ChunkAnimationTrack : public Chunk { public: