Sirikata
|
00001 /* Sirikata Utilities -- Math Library 00002 * Location.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 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 #ifndef _LOCATION_HPP_ 00033 #define _LOCATION_HPP_ 00034 00035 #include "Transform.hpp" 00036 00037 namespace Sirikata { 00038 00039 class Location: public Transform { 00040 Vector3<float32> mVelocity; 00041 Vector3<float32> mAxisOfRotation; 00042 float32 mAngularSpeed; 00043 00044 void changeToWorld(const Location &reference) { 00045 setVelocity(reference.getVelocity() + reference.getOrientation() * getVelocity()); 00046 addAngularRotation(reference.getAxisOfRotation(), reference.getAngularSpeed()); 00047 setVelocity(getVelocity() + 00048 reference.getAngularSpeed() * ( 00049 reference.getAxisOfRotation().cross(getPosition().downCast<float32>()))); 00050 00051 Transform temp = Transform::toWorld(reference); 00052 setPosition(temp.getPosition()); 00053 setOrientation(temp.getOrientation()); 00054 } 00055 void changeToLocal(const Location &reference) { 00056 Transform temp = Transform::toLocal(reference); 00057 setPosition(temp.getPosition()); 00058 setOrientation(temp.getOrientation()); 00059 00060 setVelocity(getVelocity() - 00061 reference.getAngularSpeed() * ( 00062 reference.getAxisOfRotation().cross(getPosition().downCast<float32>()))); 00063 addAngularRotation(reference.getAxisOfRotation(), -reference.getAngularSpeed()); 00064 Quaternion inverseOtherOrientation (reference.getOrientation().inverse()); 00065 setVelocity(inverseOtherOrientation * (getVelocity() - reference.getVelocity())); 00066 } 00067 public: 00068 Location(){} 00069 Location(const Vector3<float64>&position, 00070 const Quaternion&orientation, 00071 const Vector3<float32> &velocity, 00072 const Vector3<float32> angularVelocityAxis, 00073 float32 angularVelocityRadians) 00074 :Transform(position,orientation),mVelocity(velocity),mAxisOfRotation(angularVelocityAxis), mAngularSpeed(angularVelocityRadians) 00075 { 00076 } 00077 00078 00079 bool operator ==(const Location&other)const { 00080 bool eq=getPosition()==other.getPosition(); 00081 bool veq=other.mVelocity==mVelocity; 00082 bool qeq=getOrientation()==other.getOrientation(); 00083 bool aeq=mAxisOfRotation==other.mAxisOfRotation; 00084 bool seq=mAngularSpeed==other.mAngularSpeed; 00085 return eq&&veq&&qeq&&aeq&&seq; 00086 } 00087 00088 const Vector3<float32>&getVelocity()const { 00089 return mVelocity; 00090 } 00091 00092 00093 void setVelocity(const Vector3<float32> velocity) { 00094 mVelocity=velocity; 00095 } 00096 const Transform &getTransform() const { 00097 return *this; 00098 } 00099 const Vector3<float32>&getAxisOfRotation() const { 00100 return mAxisOfRotation; 00101 } 00102 void setAxisOfRotation(const Vector3<float32>&axis) { 00103 mAxisOfRotation=axis; 00104 } 00105 float32 getAngularSpeed() const{ 00106 return mAngularSpeed; 00107 } 00108 void setAngularSpeed(float32 radianspersecond) { 00109 mAngularSpeed=radianspersecond; 00110 } 00111 void addAngularRotation(const Vector3<float32> &axis, float32 radianspersecond) { 00112 mAxisOfRotation=mAxisOfRotation*mAngularSpeed+axis*radianspersecond; 00113 mAngularSpeed=mAxisOfRotation.length(); 00114 if (mAngularSpeed) 00115 mAxisOfRotation/=mAngularSpeed; 00116 } 00117 Location blend(const Location&newLocation,float32 percentNew) const{ 00118 float32 percentOld=(1.0f-percentNew); 00119 Vector3<float32> angAxis=mAxisOfRotation*mAngularSpeed*percentOld; 00120 angAxis+=newLocation.getAxisOfRotation()*newLocation.getAngularSpeed()*percentNew; 00121 float angSpeed=angAxis.length(); 00122 if (angSpeed) angAxis/=angSpeed; 00123 return Location (newLocation.getPosition()*percentNew+getPosition()*percentOld, 00124 (newLocation.getOrientation()*percentNew+getOrientation()*percentOld).normal(), 00125 newLocation.getVelocity()*percentNew+getVelocity()*percentOld, 00126 angAxis, 00127 angSpeed); 00128 } 00129 Location toWorld(const Location &reference) const { 00130 Location copy(*this); 00131 copy.changeToWorld(reference); 00132 return copy; 00133 } 00134 Location toLocal(const Location &reference) const { 00135 Location copy(*this); 00136 copy.changeToLocal(reference); 00137 return copy; 00138 } 00139 template<class TimeDuration> Location extrapolate(const TimeDuration&dt)const { 00140 return Location(getPosition()+Vector3<float64>(getVelocity())*dt.toSeconds(), 00141 getAngularSpeed() 00142 ? getOrientation()*Quaternion(getAxisOfRotation(), 00143 (float)(getAngularSpeed()*dt.toSeconds())) 00144 : getOrientation(), 00145 getVelocity(), 00146 getAxisOfRotation(), 00147 getAngularSpeed()); 00148 } 00149 }; 00150 inline std::ostream &operator<< (std::ostream &os, const Location &loc) { 00151 os << "[" << loc.getTransform() << "; vel=" << 00152 loc.getVelocity() << "; angVel = " << loc.getAngularSpeed() << 00153 " around " << loc.getAxisOfRotation() << "]"; 00154 return os; 00155 } 00156 00157 } 00158 #endif