Camcorder-cpp        
/*
 -----------------------------------------------------------------------------
 Copyright (c) 2000-2008 Torus Knot Software Ltd
 
 You may use this code for anything you like, it is public domain.
 -----------------------------------------------------------------------------
 */
 #include "Camcorder.h"
 #include "OgreOverlayManager.h"
 #include "OgreBorderPanelOverlayElement.h"
 
 //---------------------------------------------------------------------
 CamcorderHelper::CamcorderHelper()
 : mMode(IDLE)
 , mEnabled(false)
 , mViewport(0)
 , mCurrentAnimation(0)
 , mCurrentTrack(0)
 , mInterpolationMode(Animation::IM_SPLINE)
 , mRotationInterpolationMode(Animation::RIM_SPHERICAL)
 , mKeyFrameFrequency(3.0)
 , mPlaybackSpeed(1.0)
 , mOverlay(0)
 {
 
 }
 //---------------------------------------------------------------------
 CamcorderHelper::~CamcorderHelper()
 {
     delete mCurrentAnimation;
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::setEnabled(bool enabled)
 {
     mEnabled = enabled;
 
     if (!mOverlay)
         createOverlay();
 
     if (enabled)
         mOverlay->show();
     else
         mOverlay->hide();
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::setMode(Mode m)
 {
     if (m != mMode)
     {
         switch (m)
         {
         case PLAYBACK:
             mSavedPos = mCamera->getDerivedPosition();
             mSavedOrientation = mCamera->getDerivedOrientation();
             mPlaybackTime = 0;
             break;
         case IDLE:
             if (mMode == PLAYBACK)
             {
                 // return camera to saved position
                 mCamera->setPosition(mSavedPos);
                 mCamera->setOrientation(mSavedOrientation);
             }
             break;
         case RECORDING:
             mRecordingTime = 0;
             mLastKeyTime = 0;
             addKeyFrame(mLastKeyTime);
             break;
         };
 
         mMode = m;
     }
 
 
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::init(Viewport* vp, Camera* cam)
 {
     mViewport = vp;
     mCamera = cam;
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::setPositionInterpolationMode(Animation::InterpolationMode m)
 {
     mInterpolationMode = m;
     if (mCurrentAnimation)
         mCurrentAnimation->setInterpolationMode(m);
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::setRotationInterpolationMode(Animation::RotationInterpolationMode m)
 {
     mRotationInterpolationMode = m;
     if (mCurrentAnimation)
         mCurrentAnimation->setRotationInterpolationMode(m);
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::processUnbufferedKeyboard(OIS::Keyboard* keyboard, Real timeElapsed)
 {
     static float delay = 0;
 
     delay -= timeElapsed;
 
     if (!mEnabled)
         return;
 
     // Toggle playback mode
     if (keyboard->isKeyDown(OIS::KC_RETURN) && delay <= 0)
     {
         if (mMode == IDLE)
         {
             setMode(PLAYBACK);
         }
         else if (mMode == PLAYBACK)
         {
             setMode(IDLE);
         }
 
         delay = 0.5;
     }
 
     if (keyboard->isKeyDown(OIS::KC_INSERT) && delay <= 0)
     {
         if (mMode == IDLE)
         {
             setMode(RECORDING);
         }
         else if (mMode == RECORDING)
         {
             setMode(IDLE);
         }
 
         delay = 0.5;
     }
 
     if (keyboard->isKeyDown(OIS::KC_SPACE) && delay <= 0)
     {
         // take snapshot
         if (mMode == IDLE)
         {
             if (!mCurrentAnimation)
                 mLastKeyTime = 0.0f;
             else
                 mLastKeyTime += mKeyFrameFrequency;
 
             addKeyFrame(mLastKeyTime);
 
             delay = 0.5;
         }
 
     }
     if (keyboard->isKeyDown(OIS::KC_LBRACKET) && delay <= 0)
     {
         if (mMode == PLAYBACK)
         {
             mPlaybackSpeed -= 0.1;
             if (mPlaybackSpeed < 0.1)
                 mPlaybackSpeed = 0.1;
         }
         else
         {
             mKeyFrameFrequency -= 0.1;
             if (mKeyFrameFrequency < 0.1)
                 mKeyFrameFrequency = 0.1;
         }
         delay = 0.1;
     }
     if (keyboard->isKeyDown(OIS::KC_RBRACKET) && delay <= 0)
     {
         if (mMode == PLAYBACK)
         {
             mPlaybackSpeed += 0.1;
         }
         else
         {
             mKeyFrameFrequency += 0.1;
         }
         delay = 0.1;
     }
 
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::addKeyFrame(Real time)
 {
     // take a snapshot
     if (!mCurrentAnimation)
     {
         mCurrentAnimation = new Animation("CamCorderAnim", 0);
         mCurrentTrack = mCurrentAnimation->createNodeTrack(0);
         mCurrentAnimation->setInterpolationMode(mInterpolationMode);
         mCurrentAnimation->setRotationInterpolationMode(mRotationInterpolationMode);
         mCurrentTrack->setUseShortestRotationPath(false);
     }
 
     if (time == 0)
         mCurrentTrack->removeAllKeyFrames();
 
     TransformKeyFrame* kf = mCurrentTrack->createNodeKeyFrame(time);
     mCurrentAnimation->setLength(time);
 
     kf->setTranslate(mCamera->getDerivedPosition());
     kf->setRotation(mCamera->getDerivedOrientation());
 
     
 }
 //---------------------------------------------------------------------
 void CamcorderHelper::update(Real timeElapsed)
 {
     if (!mEnabled)
         return;
 
     if (mMode == PLAYBACK && mCurrentTrack)
     {
         mPlaybackTime += timeElapsed * mPlaybackSpeed;
 
         TransformKeyFrame kf(0, 0);
         mCurrentTrack->getInterpolatedKeyFrame(TimeIndex(mPlaybackTime), &kf);
 
         mCamera->setPosition(kf.getTranslate());
         mCamera->setOrientation(kf.getRotation());
 
         mCurrentPosText->setCaption(StringConverter::toString(mPlaybackTime));
         mModeText->setCaption("PLAY");
         mModeText->setColour(ColourValue::Green);
 
         mFreqText->setCaption(StringConverter::toString(mPlaybackSpeed));
         mFreqLabel->setCaption("Playback Speed:");
 
 
     }
     else if (mMode == RECORDING)
     {
         mRecordingTime += timeElapsed;
         if (mRecordingTime - mLastKeyTime >= mKeyFrameFrequency)
         {
             mLastKeyTime = mRecordingTime;
             addKeyFrame(mLastKeyTime);
         }
 
         mCurrentPosText->setCaption(StringConverter::toString(mRecordingTime));
         mModeText->setCaption("REC");
         mModeText->setColour(ColourValue::Red);
         mFreqText->setCaption(StringConverter::toString(mKeyFrameFrequency));
         mFreqLabel->setCaption("Recording Freq:");
 
     }
     else
     {
         mModeText->setCaption("IDLE");
         mModeText->setColour(ColourValue::White);
         mCurrentPosText->setCaption("");
         mFreqText->setCaption(StringConverter::toString(mKeyFrameFrequency));
         mFreqLabel->setCaption("Recording Freq:");
     }
 
     if (mCurrentAnimation)
     {
         mLengthText->setCaption(StringConverter::toString(mCurrentAnimation->getLength()));
         mKeyFramesText->setCaption(StringConverter::toString(mCurrentTrack->getNumKeyFrames()));
     }
     else
     {
         mLengthText->setCaption("0");
         mKeyFramesText->setCaption("0");
     }
 
 
 
 
     
 
 }
 //---------------------------------------------------------------------
 bool CamcorderHelper::isPlayingBack() const
 {
     return mMode == PLAYBACK;
 }
 //---------------------------------------------------------------------
 bool CamcorderHelper::isRecording() const
 {
     return mMode == RECORDING;
 }
 //---------------------------------------------------------------------
 bool CamcorderHelper::isIdle() const
 {
     return mMode == IDLE;
 }
 //---------------------------------------------------------------------
 #define OVERLAY_WIDTH 400
 #define OVERLAY_HEIGHT 85
 void CamcorderHelper::createOverlay()
 {
     OverlayManager& omgr = OverlayManager::getSingleton();
     mOverlay = omgr.create("CamCorder");
     
     BorderPanelOverlayElement* cnt = static_cast<BorderPanelOverlayElement*>(
         omgr.createOverlayElement("BorderPanel", "CC/Main"));
 
     cnt->setMetricsMode(GMM_PIXELS);
     cnt->setVerticalAlignment(GVA_BOTTOM);
     cnt->setHorizontalAlignment(GHA_CENTER);
     cnt->setPosition(-OVERLAY_WIDTH / 2, -(OVERLAY_HEIGHT + 5));
     cnt->setDimensions(OVERLAY_WIDTH, OVERLAY_HEIGHT);
     cnt->setMaterialName("Core/StatsBlockCenter");
     cnt->setBorderSize(1, 1, 1, 1);
     cnt->setBorderMaterialName("Core/StatsBlockBorder");
     cnt->setTopLeftBorderUV(0.0000, 1.0000, 0.0039, 0.9961);
     cnt->setTopBorderUV(0.0039, 1.0000, 0.9961, 0.9961);
     cnt->setTopRightBorderUV(0.9961, 1.0000, 1.0000, 0.9961);
     cnt->setLeftBorderUV(0.0000, 0.9961, 0.0039, 0.0039);
     cnt->setRightBorderUV(0.9961, 0.9961, 1.0000, 0.0039);
     cnt->setBottomLeftBorderUV(0.0000, 0.0039, 0.0039, 0.0000);
     cnt->setBottomBorderUV(0.0039, 0.0039, 0.9961, 0.0000);
     cnt->setBottomRightBorderUV(0.9961, 0.0039, 1.0000, 0.0000);
 
     mOverlay->add2D(cnt);
 
     TextAreaOverlayElement* label = createText(5, 5, "Mode:");
     cnt->addChild(label);
     label = createText(5, 20, "Animation Len:");
     cnt->addChild(label);
     label = createText(5, 35, "# Keyframes:");
     cnt->addChild(label);
     mFreqLabel = createText(5, 50, "Keyframe Freq:");
     cnt->addChild(mFreqLabel);
     label = createText(5, 65, "Current Pos:");
     cnt->addChild(label);
 
     label = createText(200, 5, "INSERT = record");
     cnt->addChild(label);
     label = createText(200, 20, "RETURN = play");
     cnt->addChild(label);
     label = createText(200, 35, "SPACE = manual keyframe");
     cnt->addChild(label);
     label = createText(200, 50, "[] = change freq / playback");
     cnt->addChild(label);
 
 
     mModeText = createText(100, 5, "");
     cnt->addChild(mModeText);
     mLengthText = createText(100, 20, "");
     cnt->addChild(mLengthText);
     mKeyFramesText = createText(100, 35, "");
     cnt->addChild(mKeyFramesText);
     mFreqText = createText(100, 50, "");
     cnt->addChild(mFreqText);
     mCurrentPosText = createText(100, 65, "");
     cnt->addChild(mCurrentPosText);
 
 
     mOverlay->hide();
     
 
 }
 //---------------------------------------------------------------------
 TextAreaOverlayElement* CamcorderHelper::createText(Real left, Real top, const String& text)
 {
     OverlayManager& omgr = OverlayManager::getSingleton();
     static int counter = 0;
     TextAreaOverlayElement* t = static_cast<TextAreaOverlayElement*>(
         omgr.createOverlayElement("TextArea", "CC/ModeLabel/" + StringConverter::toString(counter++)));
     t->setMetricsMode(GMM_PIXELS);
     t->setVerticalAlignment(GVA_TOP);
     t->setHorizontalAlignment(GHA_LEFT);
     t->setPosition(left, top);
     t->setDimensions(30, text.length() * 20);
     t->setCaption(text);
     t->setFontName("BlueHighway");
     t->setCharHeight(16);
 
     return t;
 
 }