#ifndef FRAMECAPTURE_H #define FRAMECAPTURE_H #include "Ogre.h" using namespace Ogre; class FrameCapture: public FrameListener { class SceneNodeTransformKey { public: Vector3 translate; Quaternion rotation; SceneNode* node; SceneNodeTransformKey(SceneNode* node) { this->node = node; translate = node->getPosition(); rotation = node->getOrientation(); } void applyKey() { node->setPosition(translate); node->setOrientation(rotation); } }; class SceneNodeTransformAnimation { protected: std::vector keys; SceneNode* node; std::vector::iterator iter; std::vector::iterator iterEnd; public: SceneNodeTransformAnimation(SceneNode* node) { this->node = node; } void addKey() { keys.push_back(new SceneNodeTransformKey(node)); } void startPlay() { iter = keys.begin(); iterEnd = keys.end(); } bool stepFrame() { if(iter == iterEnd) return false; (*iter)->applyKey(); iter++; return true; } void reset() { keys.clear(); } }; protected: std::vector< SceneNodeTransformAnimation*> animables; public: FrameCapture(RenderTarget* rendertarget) { target = rendertarget; isPlaying = false; isRecording = false; isSaving = false; framerate = 20; frameTime = 1000 / framerate; lastTime = 0; } void addAnimableNode(SceneNode* node) { SceneNodeTransformAnimation* newTrack = new SceneNodeTransformAnimation(node); animables.push_back(newTrack); } void recordEvent() { if(!isRecording && !isPlaying) startRecording(); else if(isRecording) stopRecording(); } void playEvent() { if(!isRecording && !isPlaying) startPlaying(); else if(isPlaying) stopPlaying(); } void setSaving(){isSaving = true;} void setFrameRate(int fr) { framerate = fr; frameTime = 1000 / framerate; } protected: bool isPlaying; bool isRecording; bool isSaving; int framerate; unsigned long currentFrame; unsigned long frameTime; unsigned long lastTime; RenderTarget* target; void startPlaying() { isPlaying = true; std::vector< SceneNodeTransformAnimation*>::iterator iter = animables.begin(); std::vector< SceneNodeTransformAnimation*>::iterator iterEnd = animables.end(); while(iter != iterEnd) { (*iter)->startPlay(); iter++; } currentFrame = 0; } void stopPlaying() { isPlaying = false; } void startRecording() { isRecording = true; std::vector< SceneNodeTransformAnimation*>::iterator iter = animables.begin(); std::vector< SceneNodeTransformAnimation*>::iterator iterEnd = animables.end(); while(iter != iterEnd) { (*iter)->reset(); iter++; } } void stopRecording() { isRecording = false; } void play() { std::vector< SceneNodeTransformAnimation*>::iterator iter = animables.begin(); std::vector< SceneNodeTransformAnimation*>::iterator iterEnd = animables.end(); while(iter != iterEnd) { if(!(*iter)->stepFrame()) { isPlaying = false; isSaving = false; return; } iter++; } currentFrame++; } void record() { unsigned long thisTime = Root::getSingleton().getTimer()->getMilliseconds(); unsigned long timeElapsed = thisTime - lastTime; if(timeElapsed < frameTime) return; lastTime = thisTime; std::vector< SceneNodeTransformAnimation*>::iterator iter = animables.begin(); std::vector< SceneNodeTransformAnimation*>::iterator iterEnd = animables.end(); while(iter != iterEnd) { (*iter)->addKey(); iter++; } } bool frameStarted(const FrameEvent& evt) { if(isPlaying) play(); if(isRecording) record(); return true; } bool frameEnded(const FrameEvent& evt) { if(isSaving) { String filename = "capture" + StringConverter::toString(currentFrame) + ".tga"; target->writeContentsToFile(filename); } return true; } }; #endif