Sirikata
libcore/include/sirikata/core/util/MotionQuaternion.hpp
Go to the documentation of this file.
00001 /*  Sirikata
00002  *  MotionQuaternion.hpp
00003  *
00004  *  Copyright (c) 2009, Ewen Cheslack-Postava
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_MOTION_QUATERNION_HPP_
00034 #define _SIRIKATA_MOTION_QUATERNION_HPP_
00035 
00036 #include <sirikata/core/util/Platform.hpp>
00037 #include <sirikata/core/util/Time.hpp>
00038 #include <sirikata/core/util/TemporalValue.hpp>
00039 
00040 
00041 namespace Sirikata {
00042 
00043 class MotionQuaternion {
00044 public:
00045     typedef Quaternion PositionType;
00046     typedef Quaternion VelocityType;
00047 
00048     MotionQuaternion()
00049      : mStart(Quaternion::identity()),
00050        mDirection(Quaternion::identity())
00051     {
00052     }
00053 
00054     MotionQuaternion(const Quaternion& pos, const Quaternion& vel)
00055      : mStart(pos), mDirection(vel)
00056     {
00057     }
00058 
00059     const Quaternion& position() const {
00060         return mStart;
00061     }
00062 
00063     const Quaternion& velocity() const {
00064         return mDirection.getDirection();
00065     }
00066 
00067     Quaternion extrapolatePosition(const Duration& dt) const {
00068         return (mStart * (mDirection.getDirection().normal().exp(mDirection.getMag() * dt.toSeconds())));
00069     }
00070 
00071 
00072     Quaternion extrapolateVelocity(const Duration& dt) const {
00073         return mDirection.getDirection();
00074     }
00075 
00076     MotionQuaternion extrapolate(const Duration& dt) const {
00077         return MotionQuaternion(extrapolatePosition(dt), extrapolateVelocity(dt));
00078     }
00079 
00080 private:
00081     Quaternion mStart;
00082 
00083     struct DirectionQuat
00084     {
00085         DirectionQuat(Quaternion newDir)
00086          : mDir(newDir),
00087            mDirMag(newDir.length())
00088         {
00089         }
00090         void setDirectction(const Quaternion& newDir)
00091         {
00092             mDir = newDir;
00093             mDirMag = newDir.length();
00094         }
00095 
00096         const Quaternion& getDirection() const
00097         {
00098             return mDir;
00099         }
00100         const float& getMag() const
00101         {
00102             return mDirMag;
00103         }
00104         
00105     private:
00106         Quaternion mDir;
00107         float mDirMag;
00108     };
00109 
00110     DirectionQuat mDirection;
00111     
00112 }; // class MotionQuaternion
00113 
00114 class TimedMotionQuaternion : public TemporalValue<MotionQuaternion> {
00115 public:
00116     typedef TemporalValue<MotionQuaternion> Base;
00117     typedef MotionQuaternion::PositionType PositionType;
00118     typedef MotionQuaternion::VelocityType VelocityType;
00119 
00120     TimedMotionQuaternion()
00121      : TemporalValue<MotionQuaternion>()
00122     {}
00123     TimedMotionQuaternion(const Time& when, const MotionQuaternion& l)
00124      : TemporalValue<MotionQuaternion>(  when , l)
00125        //: //TemporalValue<MotionQuaternion>( (when == Time::null()) ? (Time::local()) : when , l)
00126        //FIXME: making it so that TimedMotionQuaternion does not accept null time.
00127        //Only doing this because we haven't solved synchronization yet, and it's
00128        //making it so that can't put default motion values into initialization
00129        //file.  
00130     {}
00131 
00132     Time updateTime() const {
00133         return Base::time();
00134     }
00135 
00136     const PositionType& position() const {
00137         return Base::value().position();
00138     }
00139 
00140     PositionType position(const Duration& dt) const {
00141         return Base::value().extrapolatePosition(dt);
00142     }
00143 
00144     PositionType position(const Time& t) const {
00145         return position(t - Base::time());
00146     }
00147 
00148     const VelocityType& velocity() const {
00149         return Base::value().velocity();
00150     }
00151 
00152     TimedMotionQuaternion& operator+=(const PositionType &offset) {
00153         update(Base::time(), Base::value().position() * offset, Base::value().velocity());
00154         return *this;
00155     }
00156 
00157     void update(const Time& t, const PositionType& pos, const VelocityType& vel) {
00158         assert(t > Base::time());
00159         Base::updateValue(t, MotionQuaternion(pos, vel));
00160     }
00161 };
00162 
00163 } // namespace Sirikata
00164 
00165 #endif //_SIRIKATA_MOTION_QUATERNION_HPP_