$search
00001 /* 00002 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ 00003 00004 This software is provided 'as-is', without any express or implied warranty. 00005 In no event will the authors be held liable for any damages arising from the use of this software. 00006 Permission is granted to anyone to use this software for any purpose, 00007 including commercial applications, and to alter it and redistribute it freely, 00008 subject to the following restrictions: 00009 00010 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 00011 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00012 3. This notice may not be removed or altered from any source distribution. 00013 */ 00014 00015 00016 00017 #ifndef SIMD__VECTOR3_H 00018 #define SIMD__VECTOR3_H 00019 00020 00021 #include "btScalar.h" 00022 #include "btMinMax.h" 00023 00024 #ifdef BT_USE_DOUBLE_PRECISION 00025 #define btVector3Data btVector3DoubleData 00026 #define btVector3DataName "btVector3DoubleData" 00027 #else 00028 #define btVector3Data btVector3FloatData 00029 #define btVector3DataName "btVector3FloatData" 00030 #endif //BT_USE_DOUBLE_PRECISION 00031 00032 00033 00034 00039 ATTRIBUTE_ALIGNED16(class) btVector3 00040 { 00041 public: 00042 00043 #if defined (__SPU__) && defined (__CELLOS_LV2__) 00044 btScalar m_floats[4]; 00045 public: 00046 SIMD_FORCE_INLINE const vec_float4& get128() const 00047 { 00048 return *((const vec_float4*)&m_floats[0]); 00049 } 00050 public: 00051 #else //__CELLOS_LV2__ __SPU__ 00052 #ifdef BT_USE_SSE // _WIN32 00053 union { 00054 __m128 mVec128; 00055 btScalar m_floats[4]; 00056 }; 00057 SIMD_FORCE_INLINE __m128 get128() const 00058 { 00059 return mVec128; 00060 } 00061 SIMD_FORCE_INLINE void set128(__m128 v128) 00062 { 00063 mVec128 = v128; 00064 } 00065 #else 00066 btScalar m_floats[4]; 00067 #endif 00068 #endif //__CELLOS_LV2__ __SPU__ 00069 00070 public: 00071 00073 SIMD_FORCE_INLINE btVector3() {} 00074 00075 00076 00082 SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) 00083 { 00084 m_floats[0] = x; 00085 m_floats[1] = y; 00086 m_floats[2] = z; 00087 m_floats[3] = btScalar(0.); 00088 } 00089 00090 00093 SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) 00094 { 00095 00096 m_floats[0] += v.m_floats[0]; m_floats[1] += v.m_floats[1];m_floats[2] += v.m_floats[2]; 00097 return *this; 00098 } 00099 00100 00103 SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) 00104 { 00105 m_floats[0] -= v.m_floats[0]; m_floats[1] -= v.m_floats[1];m_floats[2] -= v.m_floats[2]; 00106 return *this; 00107 } 00110 SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) 00111 { 00112 m_floats[0] *= s; m_floats[1] *= s;m_floats[2] *= s; 00113 return *this; 00114 } 00115 00118 SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) 00119 { 00120 btFullAssert(s != btScalar(0.0)); 00121 return *this *= btScalar(1.0) / s; 00122 } 00123 00126 SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const 00127 { 00128 return m_floats[0] * v.m_floats[0] + m_floats[1] * v.m_floats[1] +m_floats[2] * v.m_floats[2]; 00129 } 00130 00132 SIMD_FORCE_INLINE btScalar length2() const 00133 { 00134 return dot(*this); 00135 } 00136 00138 SIMD_FORCE_INLINE btScalar length() const 00139 { 00140 return btSqrt(length2()); 00141 } 00142 00145 SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; 00146 00149 SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; 00150 00153 SIMD_FORCE_INLINE btVector3& normalize() 00154 { 00155 return *this /= length(); 00156 } 00157 00159 SIMD_FORCE_INLINE btVector3 normalized() const; 00160 00164 SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ); 00165 00168 SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const 00169 { 00170 btScalar s = btSqrt(length2() * v.length2()); 00171 btFullAssert(s != btScalar(0.0)); 00172 return btAcos(dot(v) / s); 00173 } 00175 SIMD_FORCE_INLINE btVector3 absolute() const 00176 { 00177 return btVector3( 00178 btFabs(m_floats[0]), 00179 btFabs(m_floats[1]), 00180 btFabs(m_floats[2])); 00181 } 00184 SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const 00185 { 00186 return btVector3( 00187 m_floats[1] * v.m_floats[2] -m_floats[2] * v.m_floats[1], 00188 m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2], 00189 m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]); 00190 } 00191 00192 SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const 00193 { 00194 return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + 00195 m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + 00196 m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); 00197 } 00198 00201 SIMD_FORCE_INLINE int minAxis() const 00202 { 00203 return m_floats[0] < m_floats[1] ? (m_floats[0] <m_floats[2] ? 0 : 2) : (m_floats[1] <m_floats[2] ? 1 : 2); 00204 } 00205 00208 SIMD_FORCE_INLINE int maxAxis() const 00209 { 00210 return m_floats[0] < m_floats[1] ? (m_floats[1] <m_floats[2] ? 2 : 1) : (m_floats[0] <m_floats[2] ? 2 : 0); 00211 } 00212 00213 SIMD_FORCE_INLINE int furthestAxis() const 00214 { 00215 return absolute().minAxis(); 00216 } 00217 00218 SIMD_FORCE_INLINE int closestAxis() const 00219 { 00220 return absolute().maxAxis(); 00221 } 00222 00223 SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt) 00224 { 00225 btScalar s = btScalar(1.0) - rt; 00226 m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0]; 00227 m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1]; 00228 m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2]; 00229 //don't do the unused w component 00230 // m_co[3] = s * v0[3] + rt * v1[3]; 00231 } 00232 00236 SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const 00237 { 00238 return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, 00239 m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, 00240 m_floats[2] + (v.m_floats[2] -m_floats[2]) * t); 00241 } 00242 00245 SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) 00246 { 00247 m_floats[0] *= v.m_floats[0]; m_floats[1] *= v.m_floats[1];m_floats[2] *= v.m_floats[2]; 00248 return *this; 00249 } 00250 00252 SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } 00254 SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } 00256 SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } 00258 SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;}; 00260 SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;}; 00262 SIMD_FORCE_INLINE void setZ(btScalar z) {m_floats[2] = z;}; 00264 SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;}; 00266 SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } 00268 SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } 00270 SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } 00272 SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } 00273 00274 //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } 00275 //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } 00277 SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; } 00278 SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; } 00279 00280 SIMD_FORCE_INLINE bool operator==(const btVector3& other) const 00281 { 00282 return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0])); 00283 } 00284 00285 SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const 00286 { 00287 return !(*this == other); 00288 } 00289 00293 SIMD_FORCE_INLINE void setMax(const btVector3& other) 00294 { 00295 btSetMax(m_floats[0], other.m_floats[0]); 00296 btSetMax(m_floats[1], other.m_floats[1]); 00297 btSetMax(m_floats[2], other.m_floats[2]); 00298 btSetMax(m_floats[3], other.w()); 00299 } 00303 SIMD_FORCE_INLINE void setMin(const btVector3& other) 00304 { 00305 btSetMin(m_floats[0], other.m_floats[0]); 00306 btSetMin(m_floats[1], other.m_floats[1]); 00307 btSetMin(m_floats[2], other.m_floats[2]); 00308 btSetMin(m_floats[3], other.w()); 00309 } 00310 00311 SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) 00312 { 00313 m_floats[0]=x; 00314 m_floats[1]=y; 00315 m_floats[2]=z; 00316 m_floats[3] = btScalar(0.); 00317 } 00318 00319 void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const 00320 { 00321 v0->setValue(0. ,-z() ,y()); 00322 v1->setValue(z() ,0. ,-x()); 00323 v2->setValue(-y() ,x() ,0.); 00324 } 00325 00326 void setZero() 00327 { 00328 setValue(btScalar(0.),btScalar(0.),btScalar(0.)); 00329 } 00330 00331 SIMD_FORCE_INLINE bool isZero() const 00332 { 00333 return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0); 00334 } 00335 00336 SIMD_FORCE_INLINE bool fuzzyZero() const 00337 { 00338 return length2() < SIMD_EPSILON; 00339 } 00340 00341 SIMD_FORCE_INLINE void serialize(struct btVector3Data& dataOut) const; 00342 00343 SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn); 00344 00345 SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData& dataOut) const; 00346 00347 SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn); 00348 00349 SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData& dataOut) const; 00350 00351 SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn); 00352 00353 }; 00354 00356 SIMD_FORCE_INLINE btVector3 00357 operator+(const btVector3& v1, const btVector3& v2) 00358 { 00359 return btVector3(v1.m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]); 00360 } 00361 00363 SIMD_FORCE_INLINE btVector3 00364 operator*(const btVector3& v1, const btVector3& v2) 00365 { 00366 return btVector3(v1.m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]); 00367 } 00368 00370 SIMD_FORCE_INLINE btVector3 00371 operator-(const btVector3& v1, const btVector3& v2) 00372 { 00373 return btVector3(v1.m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]); 00374 } 00376 SIMD_FORCE_INLINE btVector3 00377 operator-(const btVector3& v) 00378 { 00379 return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]); 00380 } 00381 00383 SIMD_FORCE_INLINE btVector3 00384 operator*(const btVector3& v, const btScalar& s) 00385 { 00386 return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s); 00387 } 00388 00390 SIMD_FORCE_INLINE btVector3 00391 operator*(const btScalar& s, const btVector3& v) 00392 { 00393 return v * s; 00394 } 00395 00397 SIMD_FORCE_INLINE btVector3 00398 operator/(const btVector3& v, const btScalar& s) 00399 { 00400 btFullAssert(s != btScalar(0.0)); 00401 return v * (btScalar(1.0) / s); 00402 } 00403 00405 SIMD_FORCE_INLINE btVector3 00406 operator/(const btVector3& v1, const btVector3& v2) 00407 { 00408 return btVector3(v1.m_floats[0] / v2.m_floats[0],v1.m_floats[1] / v2.m_floats[1],v1.m_floats[2] / v2.m_floats[2]); 00409 } 00410 00412 SIMD_FORCE_INLINE btScalar 00413 btDot(const btVector3& v1, const btVector3& v2) 00414 { 00415 return v1.dot(v2); 00416 } 00417 00418 00420 SIMD_FORCE_INLINE btScalar 00421 btDistance2(const btVector3& v1, const btVector3& v2) 00422 { 00423 return v1.distance2(v2); 00424 } 00425 00426 00428 SIMD_FORCE_INLINE btScalar 00429 btDistance(const btVector3& v1, const btVector3& v2) 00430 { 00431 return v1.distance(v2); 00432 } 00433 00435 SIMD_FORCE_INLINE btScalar 00436 btAngle(const btVector3& v1, const btVector3& v2) 00437 { 00438 return v1.angle(v2); 00439 } 00440 00442 SIMD_FORCE_INLINE btVector3 00443 btCross(const btVector3& v1, const btVector3& v2) 00444 { 00445 return v1.cross(v2); 00446 } 00447 00448 SIMD_FORCE_INLINE btScalar 00449 btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3) 00450 { 00451 return v1.triple(v2, v3); 00452 } 00453 00458 SIMD_FORCE_INLINE btVector3 00459 lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) 00460 { 00461 return v1.lerp(v2, t); 00462 } 00463 00464 00465 00466 SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const 00467 { 00468 return (v - *this).length2(); 00469 } 00470 00471 SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const 00472 { 00473 return (v - *this).length(); 00474 } 00475 00476 SIMD_FORCE_INLINE btVector3 btVector3::normalized() const 00477 { 00478 return *this / length(); 00479 } 00480 00481 SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle ) 00482 { 00483 // wAxis must be a unit lenght vector 00484 00485 btVector3 o = wAxis * wAxis.dot( *this ); 00486 btVector3 x = *this - o; 00487 btVector3 y; 00488 00489 y = wAxis.cross( *this ); 00490 00491 return ( o + x * btCos( angle ) + y * btSin( angle ) ); 00492 } 00493 00494 class btVector4 : public btVector3 00495 { 00496 public: 00497 00498 SIMD_FORCE_INLINE btVector4() {} 00499 00500 00501 SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 00502 : btVector3(x,y,z) 00503 { 00504 m_floats[3] = w; 00505 } 00506 00507 00508 SIMD_FORCE_INLINE btVector4 absolute4() const 00509 { 00510 return btVector4( 00511 btFabs(m_floats[0]), 00512 btFabs(m_floats[1]), 00513 btFabs(m_floats[2]), 00514 btFabs(m_floats[3])); 00515 } 00516 00517 00518 00519 btScalar getW() const { return m_floats[3];} 00520 00521 00522 SIMD_FORCE_INLINE int maxAxis4() const 00523 { 00524 int maxIndex = -1; 00525 btScalar maxVal = btScalar(-BT_LARGE_FLOAT); 00526 if (m_floats[0] > maxVal) 00527 { 00528 maxIndex = 0; 00529 maxVal = m_floats[0]; 00530 } 00531 if (m_floats[1] > maxVal) 00532 { 00533 maxIndex = 1; 00534 maxVal = m_floats[1]; 00535 } 00536 if (m_floats[2] > maxVal) 00537 { 00538 maxIndex = 2; 00539 maxVal =m_floats[2]; 00540 } 00541 if (m_floats[3] > maxVal) 00542 { 00543 maxIndex = 3; 00544 maxVal = m_floats[3]; 00545 } 00546 00547 00548 00549 00550 return maxIndex; 00551 00552 } 00553 00554 00555 SIMD_FORCE_INLINE int minAxis4() const 00556 { 00557 int minIndex = -1; 00558 btScalar minVal = btScalar(BT_LARGE_FLOAT); 00559 if (m_floats[0] < minVal) 00560 { 00561 minIndex = 0; 00562 minVal = m_floats[0]; 00563 } 00564 if (m_floats[1] < minVal) 00565 { 00566 minIndex = 1; 00567 minVal = m_floats[1]; 00568 } 00569 if (m_floats[2] < minVal) 00570 { 00571 minIndex = 2; 00572 minVal =m_floats[2]; 00573 } 00574 if (m_floats[3] < minVal) 00575 { 00576 minIndex = 3; 00577 minVal = m_floats[3]; 00578 } 00579 00580 return minIndex; 00581 00582 } 00583 00584 00585 SIMD_FORCE_INLINE int closestAxis4() const 00586 { 00587 return absolute4().maxAxis4(); 00588 } 00589 00590 00591 00592 00600 /* void getValue(btScalar *m) const 00601 { 00602 m[0] = m_floats[0]; 00603 m[1] = m_floats[1]; 00604 m[2] =m_floats[2]; 00605 } 00606 */ 00613 SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 00614 { 00615 m_floats[0]=x; 00616 m_floats[1]=y; 00617 m_floats[2]=z; 00618 m_floats[3]=w; 00619 } 00620 00621 00622 }; 00623 00624 00626 SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal) 00627 { 00628 #ifdef BT_USE_DOUBLE_PRECISION 00629 unsigned char* dest = (unsigned char*) &destVal; 00630 unsigned char* src = (unsigned char*) &sourceVal; 00631 dest[0] = src[7]; 00632 dest[1] = src[6]; 00633 dest[2] = src[5]; 00634 dest[3] = src[4]; 00635 dest[4] = src[3]; 00636 dest[5] = src[2]; 00637 dest[6] = src[1]; 00638 dest[7] = src[0]; 00639 #else 00640 unsigned char* dest = (unsigned char*) &destVal; 00641 unsigned char* src = (unsigned char*) &sourceVal; 00642 dest[0] = src[3]; 00643 dest[1] = src[2]; 00644 dest[2] = src[1]; 00645 dest[3] = src[0]; 00646 #endif //BT_USE_DOUBLE_PRECISION 00647 } 00649 SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec) 00650 { 00651 for (int i=0;i<4;i++) 00652 { 00653 btSwapScalarEndian(sourceVec[i],destVec[i]); 00654 } 00655 00656 } 00657 00659 SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector) 00660 { 00661 00662 btVector3 swappedVec; 00663 for (int i=0;i<4;i++) 00664 { 00665 btSwapScalarEndian(vector[i],swappedVec[i]); 00666 } 00667 vector = swappedVec; 00668 } 00669 00670 SIMD_FORCE_INLINE void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q) 00671 { 00672 if (btFabs(n.z()) > SIMDSQRT12) { 00673 // choose p in y-z plane 00674 btScalar a = n[1]*n[1] + n[2]*n[2]; 00675 btScalar k = btRecipSqrt (a); 00676 p.setValue(0,-n[2]*k,n[1]*k); 00677 // set q = n x p 00678 q.setValue(a*k,-n[0]*p[2],n[0]*p[1]); 00679 } 00680 else { 00681 // choose p in x-y plane 00682 btScalar a = n.x()*n.x() + n.y()*n.y(); 00683 btScalar k = btRecipSqrt (a); 00684 p.setValue(-n.y()*k,n.x()*k,0); 00685 // set q = n x p 00686 q.setValue(-n.z()*p.y(),n.z()*p.x(),a*k); 00687 } 00688 } 00689 00690 00691 struct btVector3FloatData 00692 { 00693 float m_floats[4]; 00694 }; 00695 00696 struct btVector3DoubleData 00697 { 00698 double m_floats[4]; 00699 00700 }; 00701 00702 SIMD_FORCE_INLINE void btVector3::serializeFloat(struct btVector3FloatData& dataOut) const 00703 { 00705 for (int i=0;i<4;i++) 00706 dataOut.m_floats[i] = float(m_floats[i]); 00707 } 00708 00709 SIMD_FORCE_INLINE void btVector3::deSerializeFloat(const struct btVector3FloatData& dataIn) 00710 { 00711 for (int i=0;i<4;i++) 00712 m_floats[i] = btScalar(dataIn.m_floats[i]); 00713 } 00714 00715 00716 SIMD_FORCE_INLINE void btVector3::serializeDouble(struct btVector3DoubleData& dataOut) const 00717 { 00719 for (int i=0;i<4;i++) 00720 dataOut.m_floats[i] = double(m_floats[i]); 00721 } 00722 00723 SIMD_FORCE_INLINE void btVector3::deSerializeDouble(const struct btVector3DoubleData& dataIn) 00724 { 00725 for (int i=0;i<4;i++) 00726 m_floats[i] = btScalar(dataIn.m_floats[i]); 00727 } 00728 00729 00730 SIMD_FORCE_INLINE void btVector3::serialize(struct btVector3Data& dataOut) const 00731 { 00733 for (int i=0;i<4;i++) 00734 dataOut.m_floats[i] = m_floats[i]; 00735 } 00736 00737 SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3Data& dataIn) 00738 { 00739 for (int i=0;i<4;i++) 00740 m_floats[i] = dataIn.m_floats[i]; 00741 } 00742 00743 00744 #endif //SIMD__VECTOR3_H