00001 #include "Vector3.hpp" 00002 #include "Euler3.hpp" 00003 #include "Quat4.hpp" 00004 #include "../math/BrayT.hpp" 00005 #include "../math/CoorT.hpp" 00006 #include "../math/Trig.hpp" 00007 00008 namespace se_core { 00009 const Vector3 Vector3::ZERO(0, 0, 0); 00010 const Vector3 Vector3::UNIT_FORWARD(0, 0, -1); 00011 00012 coor_t Vector3 00013 ::length() const { 00014 return CoorT::sqrt(lengthSquared()); 00015 } 00016 00017 coor_t Vector3 00018 ::xzLength() const { 00019 return CoorT::sqrt(xzLengthSquared()); 00020 } 00021 00022 bray_t Vector3 00023 ::angle(const Vector3& v1) const { 00024 //@TODO: What is this angle??? 00025 // return (double)Math.acos(dot(v1)/v1.length()/v.length()); 00026 // Numerically, near 0 and PI are very bad condition for acos. 00027 // In 3-space, |atan2(sin,cos)| is much stable. 00028 Vector3 c; 00029 c.cross(*this, v1); 00030 coor_t sin = c.length(); 00031 00032 return BrayT::abs(Trig::atan2(sin, dot(v1))); 00033 } 00034 00035 00036 bray_t Vector3 00037 ::yaw() const { 00038 return Trig::atan2(-z_, x_); 00039 } 00040 00041 00042 void Vector3 00043 ::setForward(const coor_t len, const bray_t yaw) { 00044 x_ = Trig::sinScale(len, yaw); 00045 z_ = -Trig::cosScale(len, yaw); 00046 } 00047 00048 00049 void Vector3 00050 ::setForward(const coor_t len, const bray_t yaw, const bray_t pitch) { 00051 setForward(len, yaw); 00052 00053 y_ = -Trig::sinScale(len, pitch); 00054 x_ = Trig::cosScale(x_, pitch); 00055 z_ = Trig::cosScale(z_, pitch); 00056 } 00057 00058 00059 void Vector3 00060 ::setForward(const coor_t len, const Euler3& a1) { 00061 setForward(len, a1.yaw_, a1.pitch_); 00062 } 00063 00064 /* 00065 void Vector3 00066 ::toAngle(Angle& dest) { 00067 // Based on rotation scheme found in Foley page 218-219. 00068 00069 // Get Yaw 00070 // Cos to yaw is x divided by length of line projection 00071 // to yx axis. 00072 coor_t length = new Vector2(x_, y_).length(); 00073 bray_t yaw; 00074 if (length > 0) 00075 yaw = Trig::acos(x_/ length); 00076 else 00077 yaw = 0; 00078 00079 if (y < 0) 00080 yaw = -yaw; 00081 00082 // Rotate line so it is directly above x-axis. 00083 Vector v = rotate(new Angle(0,0,-yaw)); 00084 00085 // Get pitch 00086 // Cos to pitch is the new lines x divided by the total 00087 // line length. 00088 float pitch = (float)Math.acos(v.x / v.getLength()); 00089 if (z<0) 00090 pitch = -(float)Math.toDegrees(pitch); 00091 else 00092 pitch = (float)Math.toDegrees(pitch); 00093 00094 return new Angle(0,pitch,yaw); 00095 } 00096 */ 00097 00098 00099 00100 void Vector3 00101 ::rotate(const Quat4& q) { 00102 // nVidia SDK implementation 00103 Vector3 uv, uuv; 00104 Vector3 qvec(q.x_, q.y_, q.z_); 00105 uv.cross(qvec, *this); 00106 uuv.cross(qvec, uv); 00107 uv.scale(2 * SCALE_RES * q.w_); 00108 uuv.scale(2 * SCALE_RES); 00109 00110 add(uv); 00111 add(uuv); 00112 } 00113 00114 00115 void Vector3 00116 ::rotateInverse(const Quat4& q) { 00117 Quat4 inv(q); 00118 inv.inverse(); 00119 rotate(inv); 00120 } 00121 00122 00123 void Vector3 00124 ::rotate(const Euler3& a) { 00125 rotate(Quat4(a)); 00126 } 00127 00128 00129 void Vector3 00130 ::rotateInverse(const Euler3& a) { 00131 rotateInverse(Quat4(a)); 00132 //Euler3 inv(a); 00133 //inv.invert(); 00134 //rotate(Quat4(inv)); 00135 } 00136 00137 00138 void Vector3 00139 ::rotate(const Vector3& v, const Quat4& q) { 00140 // nVidia SDK implementation 00141 Vector3 uv, uuv; 00142 Vector3 qvec(q.x_, q.y_, q.z_); 00143 uv.cross(qvec, v); 00144 uuv.cross(qvec, uv); 00145 uv.scale(2 * SCALE_RES * q.w_); 00146 uuv.scale(2 * SCALE_RES); 00147 00148 set(*this); 00149 add(uv); 00150 add(uuv); 00151 } 00152 00153 00154 void Vector3 00155 ::rotate(const Vector3& v, const Euler3& a) { 00156 rotate(v, Quat4(a)); 00157 } 00158 00159 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:13 2007 by Doxygen version 1.3.9.1.