Welcome to the new Ogre Wiki!
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
/* ----------------------------------------------------------------------------- Copyright (c) 2010 Jacob 'jacmoe' Moen You may use this sample code for anything you like, it is public domain. ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Filename: AnimationSerializer.cpp Description: A serializer for keyframe animations ----------------------------------------------------------------------------- */ #include "AnimationSerializer.h" #include "OgrePrerequisites.h" #include "OgreException.h" #include "OgreAnimation.h" #include "OgreAnimationTrack.h" #include "OgreKeyFrame.h" #include "OgreString.h" #include "OgreDataStream.h" #include "OgreLogManager.h" #include "OgreResourceGroupManager.h" #include "OgreStringConverter.h" /// stream overhead = ID + size const long STREAM_OVERHEAD_SIZE = sizeof(Ogre::uint16) + sizeof(Ogre::uint32); AnimationSerializer::AnimationSerializer() { mVersion = "[AnimationSerializer.10]"; } AnimationSerializer::~AnimationSerializer() { } void AnimationSerializer::exportAnimation(const Ogre::Animation* pAnimation, const Ogre::String& filename, Endian endianMode) { // Decide on endian mode determineEndianness(endianMode); Ogre::String msg; mpfFile = fopen(filename.c_str(), "wb"); if (!mpfFile) { OGRE_EXCEPT(Ogre::Exception::ERR_CANNOT_WRITE_TO_FILE, "Unable to open file " + filename + " for writing", "AnimationSerializer::exportAnimation"); } writeFileHeader(); Ogre::LogManager::getSingleton().stream() << "Exporting animation: " << pAnimation->getName(); writeAnimation(pAnimation); Ogre::LogManager::getSingleton().logMessage("Animation exported."); fclose(mpfFile); } Ogre::Animation* AnimationSerializer::importAnimation(const Ogre::String& filename) { Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename); return importAnimation(stream); } Ogre::Animation* AnimationSerializer::importAnimation(Ogre::DataStreamPtr& stream) { // Determine endianness (must be the first thing we do!) determineEndianness(stream); // Check header readFileHeader(stream); Ogre::Animation* anim; unsigned short streamID; while(!stream->eof()) { streamID = readChunk(stream); switch (streamID) { case AC_ANIMATION: anim = readAnimation(stream); break; } } return anim; } void AnimationSerializer::writeAnimation(const Ogre::Animation* anim) { writeChunkHeader(AC_ANIMATION, calcAnimationSize(anim)); // char* name : Name of the animation writeString(anim->getName()); // float length : Length of the animation in seconds float len = anim->getLength(); writeFloats(&len, 1); // Write all tracks Ogre::Animation::NodeTrackIterator trackIt = anim->getNodeTrackIterator(); while(trackIt.hasMoreElements()) { writeAnimationTrack(trackIt.getNext()); } } void AnimationSerializer::writeAnimationTrack(const Ogre::NodeAnimationTrack* track) { static unsigned short trackId = 0; writeChunkHeader(AC_ANIMATION_TRACK, calcAnimationTrackSize(track)); writeShorts(&trackId, 1); // Write all keyframes for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) { writeKeyFrame(track->getNodeKeyFrame(i)); } trackId++; } void AnimationSerializer::writeKeyFrame(const Ogre::TransformKeyFrame* key) { writeChunkHeader(AC_ANIMATION_TRACK_KEYFRAME, calcKeyFrameSize(key)); // float time : The time position (seconds) float time = key->getTime(); writeFloats(&time, 1); // Quaternion rotate : Rotation to apply at this keyframe writeObject(key->getRotation()); // Vector3 translate : Translation to apply at this keyframe writeObject(key->getTranslate()); } Ogre::Animation* AnimationSerializer::readAnimation(Ogre::DataStreamPtr& stream) { Ogre::String name; name = readString(stream); // float length : Length of the animation in seconds float len; readFloats(stream, &len, 1); Ogre::Animation* anim = new Ogre::Animation(name, len); // Read all tracks if (!stream->eof()) { unsigned short streamID = readChunk(stream); while(streamID == AC_ANIMATION_TRACK && !stream->eof()) { readAnimationTrack(stream, anim); if (!stream->eof()) { // Get next stream streamID = readChunk(stream); } } if (!stream->eof()) { // Backpedal back to start of this stream if we've found a non-track stream->skip(-STREAM_OVERHEAD_SIZE); } } return anim; } void AnimationSerializer::readAnimationTrack(Ogre::DataStreamPtr& stream, Ogre::Animation* anim) { unsigned short trackId; readShorts(stream, &trackId, 1); // Create track Ogre::NodeAnimationTrack* pTrack = anim->createNodeTrack(trackId); // Keep looking for nested keyframes if (!stream->eof()) { unsigned short streamID = readChunk(stream); while(streamID == AC_ANIMATION_TRACK_KEYFRAME && !stream->eof()) { readKeyFrame(stream, pTrack); if (!stream->eof()) { // Get next stream streamID = readChunk(stream); } } if (!stream->eof()) { // Backpedal back to start of this stream if we've found a non-keyframe stream->skip(-STREAM_OVERHEAD_SIZE); } } } void AnimationSerializer::readKeyFrame(Ogre::DataStreamPtr& stream, Ogre::NodeAnimationTrack* track) { // float time : The time position (seconds) float time; readFloats(stream, &time, 1); Ogre::TransformKeyFrame *kf = track->createNodeKeyFrame(time); // Quaternion rotate : Rotation to apply at this keyframe Ogre::Quaternion rot; readObject(stream, rot); kf->setRotation(rot); // Vector3 translate : Translation to apply at this keyframe Ogre::Vector3 trans; readObject(stream, trans); kf->setTranslate(trans); } size_t AnimationSerializer::calcAnimationSize(const Ogre::Animation* pAnim) { size_t size = STREAM_OVERHEAD_SIZE; // Name, including terminator size += pAnim->getName().length() + 1; // length size += sizeof(float); // Nested animation tracks Ogre::Animation::NodeTrackIterator trackIt = pAnim->getNodeTrackIterator(); while(trackIt.hasMoreElements()) { size += calcAnimationTrackSize(trackIt.getNext()); } return size; } size_t AnimationSerializer::calcAnimationTrackSize(const Ogre::NodeAnimationTrack* pTrack) { size_t size = STREAM_OVERHEAD_SIZE; // unsigned short boneIndex : Index of bone to apply to size += sizeof(unsigned short); // Nested keyframes for (unsigned short i = 0; i < pTrack->getNumKeyFrames(); ++i) { size += calcKeyFrameSize(pTrack->getNodeKeyFrame(i)); } return size; } size_t AnimationSerializer::calcKeyFrameSize(const Ogre::TransformKeyFrame* pKey) { size_t size = STREAM_OVERHEAD_SIZE; // float time : The time position (seconds) size += sizeof(float); // Quaternion rotate : Rotation to apply at this keyframe size += sizeof(float) * 4; // Vector3 translate : Translation to apply at this keyframe size += sizeof(float) * 3; return size; }
Contributors to this page: jacmoe
.
Page last modified on Saturday 31 of July, 2010 10:46:48 UTC by jacmoe
.
The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.
Sidebar
Last changes
- Hydrax
- QtOgre
- SoC2012 Complete the DirectX 11 render system
- SoC2012 Volume Rendering with LOD aimed at terrain
- SoC2012 Improve and Demo the Terrain System
- Mogre and WPF
- SoC2012 Implementation of Off-Screen Particles
- Advanced Ogre Framework
- Ogre overlays using Qt
- Architecture and Design in Games
Search box
Online users
60
online users

