Sirikata
|
00001 /* Sirikata Utilities -- Math Library 00002 * Vector4.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 00033 #ifndef _SIRIKATA_VECTOR4_HPP_ 00034 #define _SIRIKATA_VECTOR4_HPP_ 00035 00036 #include <string> 00037 #include <cassert> 00038 #include <sstream> 00039 00040 namespace Sirikata { 00041 template <typename scalar> class Vector3; 00042 00043 template <typename scalar> class Vector4 { 00044 public: 00045 static const unsigned char size = 4; 00046 typedef scalar real; 00047 union { 00048 struct { 00049 scalar x; 00050 scalar y; 00051 scalar z; 00052 scalar w; 00053 }; 00054 scalar v[4]; 00055 }; 00056 Vector4(scalar x, scalar y, scalar z, scalar w) { 00057 this->x=x; 00058 this->y=y; 00059 this->z=z; 00060 this->w=w; 00061 } 00062 Vector4(){} 00063 00064 Vector4(const Vector3<scalar>& xyz, scalar w) { 00065 this->x = xyz.x; 00066 this->y = xyz.y; 00067 this->z = xyz.z; 00068 this->w = w; 00069 } 00070 00071 template<class T>T convert(const T*ptr=NULL) const{ 00072 return T(x,y,z,w); 00073 } 00074 template<class T> Vector4<T> downCast() const{ 00075 return Vector4<T>((T)x,(T)y,(T)z,(T)w); 00076 } 00077 00078 template <class V> static Vector4 fromArray(const V&other){ 00079 return Vector4(other[0],other[1],other[2],other[3]); 00080 } 00081 00082 template <class V> static Vector4 fromSSE(const V&other){ 00083 return Vector4(other.x(),other.y(),other.z(),other.w()); 00084 } 00085 scalar&operator[](const unsigned int i) { 00086 assert(i<4); 00087 return v[i]; 00088 } 00089 scalar operator[](const unsigned int i) const{ 00090 assert(i<4); 00091 return v[i]; 00092 } 00093 Vector4&operator=(scalar other) { 00094 x=other; 00095 y=other; 00096 z=other; 00097 w=other; 00098 return *this; 00099 } 00100 static Vector4 zero() { 00101 return Vector4(0,0,0,0); 00102 } 00103 static Vector4 unitX() { 00104 return Vector4(1,0,0,0); 00105 } 00106 static Vector4 unitY() { 00107 return Vector4(0,1,0,0); 00108 } 00109 static Vector4 unitZ() { 00110 return Vector4(0,0,1,0); 00111 } 00112 static Vector4 unitNegX() { 00113 return Vector4(-1,0,0,0); 00114 } 00115 static Vector4 unitNegY() { 00116 return Vector4(0,-1,0,0); 00117 } 00118 static Vector4 unitNegZ() { 00119 return Vector4(0,0,-1,0); 00120 } 00121 Vector4 operator*(scalar scale) const { 00122 return Vector4(x*scale,y*scale,z*scale,w*scale); 00123 } 00124 Vector4 operator/(scalar scale) const { 00125 return Vector4(x/scale,y/scale,z/scale,w/scale); 00126 } 00127 Vector4 operator+(const Vector4&other) const { 00128 return Vector4(x+other.x,y+other.y,z+other.z,w+other.w); 00129 } 00130 Vector4 operator-(const Vector4&other) const { 00131 return Vector4(x-other.x,y-other.y,z-other.z,w-other.w); 00132 } 00133 Vector4 operator-() const { 00134 return Vector4(-x,-y,-z,-w); 00135 } 00136 Vector4& operator*=(scalar scale) { 00137 x*=scale; 00138 y*=scale; 00139 z*=scale; 00140 w*=scale; 00141 return *this; 00142 } 00143 Vector4& operator/=(scalar scale) { 00144 x/=scale; 00145 y/=scale; 00146 z/=scale; 00147 w/=scale; 00148 return *this; 00149 } 00150 Vector4& operator+=(const Vector4& other) { 00151 x+=other.x; 00152 y+=other.y; 00153 z+=other.z; 00154 w+=other.w; 00155 return *this; 00156 } 00157 Vector4& operator-=(const Vector4& other) { 00158 x-=other.x; 00159 y-=other.y; 00160 z-=other.z; 00161 w-=other.w; 00162 return *this; 00163 } 00164 Vector4 componentMultiply(const Vector4&other) const { 00165 return Vector4(x*other.x,y*other.y,z*other.z,w*other.w); 00166 } 00167 scalar dot(const Vector4 &other) const{ 00168 return x*other.x+y*other.y+z*other.z+w*other.w; 00169 } 00170 Vector4 min(const Vector4&other)const { 00171 return Vector4(other.x<x?other.x:x, 00172 other.y<y?other.y:y, 00173 other.z<z?other.z:z, 00174 other.w<w?other.w:w); 00175 } 00176 Vector4 max(const Vector4&other)const { 00177 return Vector4(other.x>x?other.x:x, 00178 other.y>y?other.y:y, 00179 other.z>z?other.z:z, 00180 other.w>w?other.w:w); 00181 } 00182 scalar lengthSquared()const { 00183 return dot(*this); 00184 } 00185 scalar length()const { 00186 return (scalar)sqrt(dot(*this)); 00187 } 00188 bool operator==(const Vector4&other)const { 00189 return x==other.x&&y==other.y&&z==other.z&&w==other.w; 00190 } 00191 bool operator!=(const Vector4&other)const { 00192 return x!=other.x||y!=other.y||z!=other.z||w!=other.w; 00193 } 00194 Vector4 normal()const { 00195 scalar len=length(); 00196 if (len>1e-08) 00197 return *this/len; 00198 return *this; 00199 } 00200 scalar normalizeThis() { 00201 scalar len=length(); 00202 if (len>1e-08) 00203 *this/=len; 00204 return len; 00205 } 00206 std::string toString()const { 00207 std::ostringstream os; 00208 os<<'<'<<x<<","<<y<<","<<z<<","<<w<<'>'; 00209 return os.str(); 00210 } 00211 }; 00212 00213 template<typename scalar> inline Vector4<scalar> operator *(scalar lhs, const Vector4<scalar> &rhs) { 00214 return Vector4<scalar>(lhs*rhs.x,lhs*rhs.y,lhs*rhs.z,lhs*rhs.w); 00215 } 00216 template<typename scalar> inline Vector4<scalar> operator /(scalar lhs, const Vector4<scalar> &rhs) { 00217 return Vector4<scalar>(lhs/rhs.x,lhs/rhs.y,lhs/rhs.z,lhs/rhs.w); 00218 } 00219 template<typename scalar> inline std::ostream& operator <<(std::ostream& os, const Vector4<scalar> &rhs) { 00220 os<<'<'<<rhs.x<<","<<rhs.y<<","<<rhs.z<<","<<rhs.w<<'>'; 00221 return os; 00222 } 00223 template<typename scalar> inline std::istream& operator >>(std::istream& is, Vector4<scalar> &rhs) { 00224 // FIXME this should be more robust. It currently relies on the exact format provided by operator << 00225 char dummy; 00226 is >> dummy >> rhs.x >> dummy >> rhs.y >> dummy >> rhs.z >> dummy >> rhs.w >> dummy; 00227 return is; 00228 } 00229 00230 } 00231 00232 #endif //_SIRIKATA_VECTOR4_HPP_