Sirikata
|
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_