PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: Vector4.h * 00003 * 00004 * Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLMATH_VECTOR4_H__ 00024 #define __PLMATH_VECTOR4_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include "PLMath/Vector3.h" 00032 00033 00034 //[-------------------------------------------------------] 00035 //[ Namespace ] 00036 //[-------------------------------------------------------] 00037 namespace PLMath { 00038 00039 00040 //[-------------------------------------------------------] 00041 //[ Classes ] 00042 //[-------------------------------------------------------] 00043 /** 00044 * @brief 00045 * 4D vector 00046 */ 00047 class Vector4 { 00048 00049 00050 //[-------------------------------------------------------] 00051 //[ Public definitions ] 00052 //[-------------------------------------------------------] 00053 public: 00054 /** 00055 * @brief 00056 * Vector component 00057 */ 00058 enum Component { 00059 X = 0, /**< X component */ 00060 Y = 1, /**< Y component */ 00061 Z = 2, /**< Z component */ 00062 W = 3 /**< Z component */ 00063 }; 00064 00065 00066 //[-------------------------------------------------------] 00067 //[ Public static data ] 00068 //[-------------------------------------------------------] 00069 public: 00070 static PLMATH_API const Vector4 Zero; /**< 0.0, 0.0, 0.0, 0.0 */ 00071 static PLMATH_API const Vector4 One; /**< 1.0, 1.0, 1.0, 1.0 */ 00072 static PLMATH_API const Vector4 NegativeOne; /**< -1.0, -1.0, -1.0, -1.0 */ 00073 static PLMATH_API const Vector4 UnitX; /**< 1.0, 0.0, 0.0, 1.0 */ 00074 static PLMATH_API const Vector4 UnitY; /**< 0.0, 1.0, 0.0, 1.0 */ 00075 static PLMATH_API const Vector4 UnitZ; /**< 0.0, 0.0, 1.0, 1.0 */ 00076 static PLMATH_API const Vector4 UnitW; /**< 0.0, 0.0, 0.0, 1.0 */ 00077 static PLMATH_API const Vector4 NegativeUnitX; /**< -1.0, 0.0, 0.0, 1.0 */ 00078 static PLMATH_API const Vector4 NegativeUnitY; /**< 0.0, -1.0, 0.0, 1.0 */ 00079 static PLMATH_API const Vector4 NegativeUnitZ; /**< 0.0, 0.0, -1.0, 1.0 */ 00080 static PLMATH_API const Vector4 NegativeUnitW; /**< 0.0, 0.0, 0.0, -1.0 */ 00081 00082 00083 //[-------------------------------------------------------] 00084 //[ Public data ] 00085 //[-------------------------------------------------------] 00086 public: 00087 /** 00088 * @brief 00089 * Some direct vertex element accesses 00090 */ 00091 union { 00092 /** 00093 * @brief 00094 * Vertex element array access 00095 */ 00096 float fV[4]; 00097 00098 /** 00099 * @brief 00100 * Known vertex element names when dealing with positions or directions 00101 */ 00102 struct { 00103 float x, y, z, w; 00104 }; 00105 }; 00106 00107 00108 //[-------------------------------------------------------] 00109 //[ Public functions ] 00110 //[-------------------------------------------------------] 00111 public: 00112 //[-------------------------------------------------------] 00113 //[ Constructors ] 00114 //[-------------------------------------------------------] 00115 /** 00116 * @brief 00117 * Default constructor setting the components to (0, 0, 0, 1) 00118 */ 00119 inline Vector4(); 00120 00121 inline Vector4(float fX, float fY, float fZ = 0.0f, float fW = 1.0f); 00122 inline Vector4(const float fV[]); 00123 PLMATH_API Vector4(const Vector2 &vV, float fZ = 0.0f, float fW = 1.0f); 00124 PLMATH_API Vector4(const Vector3 &vV, float fW = 1.0f); 00125 inline Vector4(const Vector4 &vV); 00126 inline Vector4(const PLCore::String &sString); 00127 00128 //[-------------------------------------------------------] 00129 //[ Destructor ] 00130 //[-------------------------------------------------------] 00131 inline ~Vector4(); 00132 00133 //[-------------------------------------------------------] 00134 //[ Assignment operators ] 00135 //[-------------------------------------------------------] 00136 inline Vector4 &operator =(const float fV[]); 00137 PLMATH_API Vector4 &operator =(const Vector2 &vV); 00138 PLMATH_API Vector4 &operator =(const Vector3 &vV); 00139 inline Vector4 &operator =(const Vector4 &vV); 00140 00141 //[-------------------------------------------------------] 00142 //[ Comparison ] 00143 //[-------------------------------------------------------] 00144 /** 00145 * @brief 00146 * Compares two vectors 00147 * 00148 * @param[in] vV 00149 * Vector to compare with 00150 * 00151 * @return 00152 * 'true' if all components are equal, else 'false' 00153 */ 00154 inline bool operator ==(const Vector4 &vV) const; 00155 00156 /** 00157 * @brief 00158 * Compares two vectors 00159 * 00160 * @param[in] vV 00161 * Vector to compare with 00162 * 00163 * @return 00164 * 'false' if all components are equal, else 'true' 00165 */ 00166 inline bool operator !=(const Vector4 &vV) const; 00167 00168 /** 00169 * @brief 00170 * Compares two vectors lexicographically 00171 * 00172 * @param[in] vV 00173 * Vector to compare with 00174 * 00175 * @return 00176 * 'true' if ALL components of this vector are less, else 'false' 00177 * 00178 * @note 00179 * - A lexicographical order for 4-dimensional vectors is used (see http://en.wikipedia.org/wiki/Ordered_vector_space) 00180 */ 00181 inline bool operator <(const Vector4 &vV) const; 00182 00183 /** 00184 * @brief 00185 * Compares two vectors lexicographically 00186 * 00187 * @param[in] vV 00188 * Vector to compare with 00189 * 00190 * @return 00191 * 'true' if ALL components of this vector are greater, else 'false' 00192 * 00193 * @see 00194 * - "operator <" 00195 */ 00196 inline bool operator >(const Vector4 &vV) const; 00197 00198 /** 00199 * @brief 00200 * Compares two vectors lexicographically 00201 * 00202 * @param[in] vV 00203 * Vector to compare with 00204 * 00205 * @return 00206 * 'true' if ALL components of this vector are less or equal, else 'false' 00207 * 00208 * @see 00209 * - "operator <" 00210 */ 00211 inline bool operator <=(const Vector4 &vV) const; 00212 00213 /** 00214 * @brief 00215 * Compares two vectors lexicographically 00216 * 00217 * @param[in] vV 00218 * Vector to compare with 00219 * 00220 * @return 00221 * 'true' if ALL components of this vector are greater or equal, else 'false' 00222 * 00223 * @see 00224 * - "operator <" 00225 */ 00226 inline bool operator >=(const Vector4 &vV) const; 00227 00228 //[-------------------------------------------------------] 00229 //[ Vector ] 00230 //[-------------------------------------------------------] 00231 inline Vector4 operator +(const Vector4 &vV) const; 00232 inline Vector4 operator +(float fN) const; 00233 inline Vector4 &operator +=(const Vector4 &vV); 00234 inline Vector4 &operator +=(float fN); 00235 inline Vector4 operator -() const; 00236 inline Vector4 operator -(const Vector4 &vV) const; 00237 inline Vector4 operator -(float fN) const; 00238 inline Vector4 &operator -=(const Vector4 &vV); 00239 inline Vector4 &operator -=(float fN); 00240 00241 /** 00242 * @brief 00243 * Per component multiplication 00244 * 00245 * @param[in] vV 00246 * Vector to multiplicate with 00247 * 00248 * @return 00249 * The resulting vector 00250 */ 00251 inline Vector4 operator *(const Vector4 &vV) const; 00252 inline Vector4 operator *(float fS) const; 00253 00254 /** 00255 * @brief 00256 * Per component multiplication 00257 * 00258 * @param[in] vV 00259 * Vector to multiplicate with 00260 * 00261 * @return 00262 * This vector which is now the resulting vector 00263 */ 00264 inline Vector4 &operator *=(const Vector4 &vV); 00265 inline Vector4 &operator *=(float fS); 00266 00267 /** 00268 * @brief 00269 * Transforms the vector 00270 * 00271 * @param[in] mTrans 00272 * Matrix which transforms the vector 00273 * 00274 * @return 00275 * This vector which is now the resulting vector 00276 */ 00277 PLMATH_API Vector4 &operator *=(const Matrix4x4 &mTrans); 00278 00279 /** 00280 * @brief 00281 * Per component division 00282 * 00283 * @param[in] vV 00284 * Vector to divide through 00285 * 00286 * @return 00287 * The resulting vector 00288 */ 00289 inline Vector4 operator /(const Vector4 &vV) const; 00290 inline Vector4 operator /(float fS) const; 00291 00292 /** 00293 * @brief 00294 * Per component division 00295 * 00296 * @param[in] vV 00297 * Vector to divide through 00298 * 00299 * @return 00300 * This vector which is now the resulting vector 00301 */ 00302 inline Vector4 &operator /=(const Vector4 &vV); 00303 inline Vector4 &operator /=(float fS); 00304 00305 //[-------------------------------------------------------] 00306 //[ Get and set ] 00307 //[-------------------------------------------------------] 00308 PLMATH_API operator Vector3(); 00309 inline operator float *(); 00310 inline operator const float *() const; 00311 inline float &operator [](int nIndex); 00312 inline const float &operator [](int nIndex) const; 00313 inline void GetXYZW(float &fX, float &fY, float &fZ, float &fW) const; 00314 inline float GetX() const; 00315 inline float GetY() const; 00316 inline float GetZ() const; 00317 inline float GetW() const; 00318 inline void SetXYZ(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f); 00319 inline void SetXYZ(const float fV[]); 00320 PLMATH_API void SetXYZ(const Vector3 &vV); 00321 inline void SetXYZW(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f, float fW = 1.0f); 00322 inline void SetXYZW(const float fV[]); 00323 PLMATH_API void SetXYZW(const Vector3 &vV, float fW = 1.0f); 00324 inline void SetX(float fX = 0.0f); 00325 inline void SetY(float fY = 0.0f); 00326 inline void SetZ(float fZ = 0.0f); 00327 inline void SetW(float fW = 1.0f); 00328 inline void IncXYZW(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f, float fW = 0.0f); 00329 inline void IncXYZW(const float fV[]); 00330 inline void IncX(float fX); 00331 inline void IncY(float fY); 00332 inline void IncZ(float fZ); 00333 inline void IncW(float fW); 00334 00335 //[-------------------------------------------------------] 00336 //[ Misc ] 00337 //[-------------------------------------------------------] 00338 /** 00339 * @brief 00340 * Returns whether the vector is null or not 00341 * 00342 * @return 00343 * 'true' if the vector is null, else 'false' 00344 */ 00345 inline bool IsNull() const; 00346 00347 /** 00348 * @brief 00349 * Returns whether the vector is packed (within range of 0-1) or not 00350 * 00351 * @return 00352 * 'true' if the vector is packed, else 'false' 00353 */ 00354 inline bool IsPacked() const; 00355 00356 /** 00357 * @brief 00358 * Packs/clamps the vector into a range of 0-1 00359 * 00360 * @remarks 00361 * First, the vector is normalized - now each component is between -1 and 1. 00362 * This normalized vector is scaled by 0.5 and 0.5 is added. 00363 */ 00364 inline void PackTo01(); 00365 00366 /** 00367 * @brief 00368 * Returns a vector which is packed/clamped into the range of 0-1 00369 * 00370 * @return 00371 * The packed vector 00372 * 00373 * @see 00374 * - PackTo01() 00375 */ 00376 inline Vector4 GetPackedTo01() const; 00377 00378 /** 00379 * @brief 00380 * Unpacks the packed vector into a range of -1 to 1 00381 * 00382 * @remarks 00383 * The vector is scaled by 2 and 1 is subtracted. 00384 * 00385 * @note 00386 * - There's no internal check whether the vector is packed or not, you can do this 00387 * by yourself using the IsPacked() function 00388 */ 00389 inline void UnpackFrom01(); 00390 00391 /** 00392 * @brief 00393 * Returns a unpacked vector of the range of -1 to 1 00394 * 00395 * @return 00396 * The unpacked vector 00397 * 00398 * @see 00399 * - UnpackFrom01() 00400 */ 00401 inline Vector4 GetUnpackedFrom01() const; 00402 00403 /** 00404 * @brief 00405 * Returns the smallest component 00406 * 00407 * @return 00408 * The smallest component 00409 * 00410 * @remarks 00411 * If x is 1, y is 2, z is 3 and w is 4, this function will return the x component. 00412 */ 00413 inline Component GetSmallestComponent() const; 00414 00415 /** 00416 * @brief 00417 * Returns the value of the smallest component 00418 * 00419 * @return 00420 * The value of the smallest component 00421 * 00422 * @see 00423 * - GetSmallestComponent() above 00424 */ 00425 inline float GetSmallestValue() const; 00426 00427 /** 00428 * @brief 00429 * Returns the greatest component 00430 * 00431 * @return 00432 * The greatest component 00433 * 00434 * @remarks 00435 * If x is 1, y is 2, z is 3 and w is 4, this function will return the w component. 00436 */ 00437 inline Component GetGreatestComponent() const; 00438 00439 /** 00440 * @brief 00441 * Returns the value of the greatest component 00442 * 00443 * @return 00444 * The value of the greatest component 00445 * 00446 * @see 00447 * - GetGreatestComponent() above 00448 */ 00449 inline float GetGreatestValue() const; 00450 00451 /** 00452 * @brief 00453 * Inverts the vector 00454 * 00455 * @remarks 00456 * v'.x = -v.x\n 00457 * v'.y = -v.y\n 00458 * v'.z = -v.z\n 00459 * v'.w = -v.w 00460 */ 00461 inline void Invert(); 00462 00463 /** 00464 * @brief 00465 * Returns the inverted vector 00466 * 00467 * @return 00468 * Inverted vector 00469 * 00470 * @see 00471 * - Invert() 00472 */ 00473 inline Vector4 GetInverted() const; 00474 00475 /** 00476 * @brief 00477 * Returns the length of the vector (also called magnitude) 00478 * 00479 * @return 00480 * Vector length 00481 * 00482 * @remarks 00483 * l = sqrt(x*x + y*y + z*z + w*w) 00484 */ 00485 inline float GetLength() const; 00486 00487 /** 00488 * @brief 00489 * Returns the squared length of the vector (also called norm) 00490 * 00491 * @return 00492 * Squared vector length 00493 * 00494 * @remarks 00495 * l = x*x + y*y + z*z + w*w 00496 * 00497 * @note 00498 * - For better performance, use this function instead of GetLength() whenever 00499 * possible. You can often work with squared lengths instead of the 'real' ones. 00500 */ 00501 inline float GetSquaredLength() const; 00502 00503 /** 00504 * @brief 00505 * Sets the vector to the given length 00506 * 00507 * @param[in] fLength 00508 * Length to set 00509 * 00510 * @remarks 00511 * v' = v*l/sqrt(x*x + y*y + z*z + w*w) 00512 */ 00513 inline void SetLength(float fLength = 1.0f); 00514 00515 /** 00516 * @brief 00517 * Normalizes the vector 00518 * 00519 * @return 00520 * This instance 00521 * 00522 * @remarks 00523 * v' = v*1/sqrt(x*x + y*y + z*z + w*w) 00524 * 00525 * @note 00526 * - This will set the vector to a length of 1 (same as SetLength(1.0f) :) 00527 * - A normalized vector is called 'unit vector' 00528 */ 00529 inline Vector4 &Normalize(); 00530 00531 /** 00532 * @brief 00533 * Returns the normalized vector 00534 * 00535 * @return 00536 * Normalized vector 00537 * 00538 * @see 00539 * - Normalize() 00540 */ 00541 inline Vector4 GetNormalized() const; 00542 00543 /** 00544 * @brief 00545 * Returns the distance to another vector 00546 * 00547 * @param[in] vV 00548 * The other vector 00549 * 00550 * @return 00551 * Distance to the other vector 00552 * 00553 * @remarks 00554 * dx = v2.x-v1.x\n 00555 * dy = v2.y-v1.y\n 00556 * dz = v2.z-v1.z\n 00557 * dw = v2.w-v1.w\n 00558 * d = sqrt(dx*dx + dy*dy + dz*dz + dw*dw) 00559 */ 00560 inline float GetDistance(const Vector4 &vV) const; 00561 00562 /** 00563 * @brief 00564 * Returns the squared distance to another vector 00565 * 00566 * @param[in] vV 00567 * The other vector 00568 * 00569 * @return 00570 * Squared distance to the other vector 00571 * 00572 * @remarks 00573 * dx = v2.x-v1.x\n 00574 * dy = v2.y-v1.y\n 00575 * dz = v2.z-v1.z\n 00576 * dw = v2.w-v1.w\n 00577 * d = dx*dx + dy*dy + dz*dz + dw*dw 00578 * 00579 * @note 00580 * - For better performance, use this function instead of GetDistance() whenever 00581 * possible. You can often work with squared distances instead of the 'real' ones. 00582 */ 00583 inline float GetSquaredDistance(const Vector4 &vV) const; 00584 00585 /** 00586 * @brief 00587 * Returns the dot product of two vectors 00588 * 00589 * @param[in] vV 00590 * Second vector 00591 * 00592 * @return 00593 * Dot product of the vectors 00594 * 00595 * @remarks 00596 * d = this->x*vV.x + this->y*vV.y + this->z*vV.z + this->w*vV.w 00597 * 00598 * @note 00599 * - The dot product is also known as 'scalar product' or 'inner product' 00600 * - The dot product of a vector with itself is equal to it's squared length, so it's possible to 00601 * use GetSquaredLength() instead of v.DotProduct(v) 00602 * - The dot product is commutative 00603 * - If the two vectors are perpendicular, their dot product equals zero 00604 * - If the angle between the two vectors is acute (< 90 degrees) the dot product will be positive, 00605 * if the angle is obtuse (> 90 degrees) the dot product will be negative 00606 * - Geometric definition: a.DotProduct(b) = a.GetLength() * b.GetLength() * cos(r) 00607 * 00608 * @see 00609 * - GetAngle() 00610 */ 00611 inline float DotProduct(const Vector4 &vV) const; 00612 00613 /** 00614 * @brief 00615 * Project vector a onto another vector b 00616 * 00617 * @param[in] vA 00618 * Vector to project 00619 * @param[in] vB 00620 * Vector to project onto 00621 * 00622 * @remarks 00623 * @code 00624 * ^. 00625 * / . 00626 * / . 00627 * a / . 00628 * / . a.DotProduct(b) 00629 * / . projb(a) = b * ----------------- 00630 * / . b.DotProduct(b) 00631 * / . 00632 * --->____. 00633 * b ^= projb(a) 00634 * @endcode 00635 * 00636 * @return 00637 * The resulting projection vector 00638 */ 00639 inline Vector4 ProjectVector(const Vector4 &vA, const Vector4 &vB) const; 00640 00641 /** 00642 * @brief 00643 * Calculates the angle between two vectors 00644 * 00645 * @param[in] vV 00646 * Second vector 00647 * 00648 * @return 00649 * The angle between the two vectors (in radians) 00650 * 00651 * @remarks 00652 * @code 00653 * v1.DotProduct(v2) 00654 * cos A = -------------------------------- 00655 * v1.GetLength() * v2.GetLength() 00656 * @endcode 00657 * 00658 * @note 00659 * - If the two vectors are normalized, you can also use acos(DotProduct()) which is 00660 * in this case more performant 00661 */ 00662 inline float GetAngle(const Vector4 &vV) const; 00663 00664 /** 00665 * @brief 00666 * Calculates a normalized projection vector 00667 * 00668 * @param[in] vX 00669 * The first vector to calculate the projection from 00670 * @param[in] vN 00671 * The second vector to calculate the projection from 00672 * 00673 * @return 00674 * Reference to the vector itself which is now the resulting projection 00675 */ 00676 PLMATH_API Vector4 &GetProjection(const Vector4 &vX, const Vector4 &vN); 00677 00678 /** 00679 * @brief 00680 * Project the vector on to the plane created by two direction vectors 00681 * 00682 * @param[in] vV1 00683 * First of the two direction vectors creating the plane 00684 * @param[in] vV2 00685 * Second of the two direction vectors creating the plane 00686 * 00687 * @return 00688 * Reference to the vector itself which is now the resulting projection vector 00689 * 00690 * @note 00691 * - vV1 and vV2 MUST be perpendicular to each other 00692 */ 00693 PLMATH_API Vector4 &ProjectPlane(const Vector4 &vV1, const Vector4 &vV2); 00694 00695 /** 00696 * @brief 00697 * To string 00698 * 00699 * @return 00700 * String with the data 00701 */ 00702 PLMATH_API PLCore::String ToString() const; 00703 00704 /** 00705 * @brief 00706 * From string 00707 * 00708 * @param[in] sString 00709 * String with the data 00710 */ 00711 PLMATH_API bool FromString(const PLCore::String &sString); 00712 00713 00714 }; 00715 00716 00717 //[-------------------------------------------------------] 00718 //[ Namespace ] 00719 //[-------------------------------------------------------] 00720 } // PLMath 00721 00722 00723 //[-------------------------------------------------------] 00724 //[ Implementation ] 00725 //[-------------------------------------------------------] 00726 #include "PLMath/Vector4.inl" 00727 #include "PLMath/TypeVector4.inl" 00728 00729 00730 #endif // __PLMATH_VECTOR4_H__
|