v3dmath.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:12k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file v3dmath.h
  3.  * @brief High precision 3 dimensional vector.
  4.  *
  5.  * $LicenseInfo:firstyear=2000&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2000-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_V3DMATH_H
  33. #define LL_V3DMATH_H
  34. #include "llerror.h"
  35. #include "v3math.h"
  36. class LLVector3d
  37. {
  38. public:
  39. F64 mdV[3];
  40. const static LLVector3d zero;
  41. const static LLVector3d x_axis;
  42. const static LLVector3d y_axis;
  43. const static LLVector3d z_axis;
  44. const static LLVector3d x_axis_neg;
  45. const static LLVector3d y_axis_neg;
  46. const static LLVector3d z_axis_neg;
  47. inline LLVector3d(); // Initializes LLVector3d to (0, 0, 0)
  48. inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z)
  49. inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2])
  50. inline explicit LLVector3d(const LLVector3 &vec);
  51. explicit LLVector3d(const LLSD& sd)
  52. {
  53. setValue(sd);
  54. }
  55. void setValue(const LLSD& sd)
  56. {
  57. mdV[0] = sd[0].asReal();
  58. mdV[1] = sd[1].asReal();
  59. mdV[2] = sd[2].asReal();
  60. }
  61. LLSD getValue() const
  62. {
  63. LLSD ret;
  64. ret[0] = mdV[0];
  65. ret[1] = mdV[1];
  66. ret[2] = mdV[2];
  67. return ret;
  68. }
  69. inline BOOL isFinite() const; // checks to see if all values of LLVector3d are finite
  70. BOOL clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns TRUE if data changed
  71. BOOL abs(); // sets all values to absolute value of original value (first octant), returns TRUE if changed
  72. inline const LLVector3d& clearVec(); // Clears LLVector3d to (0, 0, 0, 1)
  73. inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0)
  74. inline const LLVector3d& zeroVec(); // deprecated
  75. inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1)
  76. inline const LLVector3d& setVec(const LLVector3d &vec); // Sets LLVector3d to vec
  77. inline const LLVector3d& setVec(const F64 *vec); // Sets LLVector3d to vec
  78. inline const LLVector3d& setVec(const LLVector3 &vec);
  79. F64 magVec() const; // Returns magnitude of LLVector3d
  80. F64 magVecSquared() const; // Returns magnitude squared of LLVector3d
  81. inline F64 normVec(); // Normalizes and returns the magnitude of LLVector3d
  82. F64 length() const; // Returns magnitude of LLVector3d
  83. F64 lengthSquared() const; // Returns magnitude squared of LLVector3d
  84. inline F64 normalize(); // Normalizes and returns the magnitude of LLVector3d
  85. const LLVector3d& rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians
  86. const LLVector3d& rotVec(const F64 angle, const F64 x, const F64 y, const F64 z); // Rotates about x,y,z by angle radians
  87. const LLVector3d& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
  88. const LLVector3d& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
  89. BOOL isNull() const; // Returns TRUE if vector has a _very_small_ length
  90. BOOL isExactlyZero() const { return !mdV[VX] && !mdV[VY] && !mdV[VZ]; }
  91. const LLVector3d& operator=(const LLVector4 &a);
  92. F64 operator[](int idx) const { return mdV[idx]; }
  93. F64 &operator[](int idx) { return mdV[idx]; }
  94. friend LLVector3d operator+(const LLVector3d &a, const LLVector3d &b); // Return vector a + b
  95. friend LLVector3d operator-(const LLVector3d &a, const LLVector3d &b); // Return vector a minus b
  96. friend F64 operator*(const LLVector3d &a, const LLVector3d &b); // Return a dot b
  97. friend LLVector3d operator%(const LLVector3d &a, const LLVector3d &b); // Return a cross b
  98. friend LLVector3d operator*(const LLVector3d &a, const F64 k); // Return a times scaler k
  99. friend LLVector3d operator/(const LLVector3d &a, const F64 k); // Return a divided by scaler k
  100. friend LLVector3d operator*(const F64 k, const LLVector3d &a); // Return a times scaler k
  101. friend bool operator==(const LLVector3d &a, const LLVector3d &b); // Return a == b
  102. friend bool operator!=(const LLVector3d &a, const LLVector3d &b); // Return a != b
  103. friend const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b); // Return vector a + b
  104. friend const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b); // Return vector a minus b
  105. friend const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b); // Return a cross b
  106. friend const LLVector3d& operator*=(LLVector3d &a, const F64 k); // Return a times scaler k
  107. friend const LLVector3d& operator/=(LLVector3d &a, const F64 k); // Return a divided by scaler k
  108. friend LLVector3d operator-(const LLVector3d &a); // Return vector -a
  109. friend std::ostream&  operator<<(std::ostream& s, const LLVector3d &a); // Stream a
  110. static BOOL parseVector3d(const std::string& buf, LLVector3d* value);
  111. };
  112. typedef LLVector3d LLGlobalVec;
  113. const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)
  114. {
  115. mdV[0] = vec.mV[0];
  116. mdV[1] = vec.mV[1];
  117. mdV[2] = vec.mV[2];
  118. return *this;
  119. }
  120. inline LLVector3d::LLVector3d(void)
  121. {
  122. mdV[0] = 0.f;
  123. mdV[1] = 0.f;
  124. mdV[2] = 0.f;
  125. }
  126. inline LLVector3d::LLVector3d(const F64 x, const F64 y, const F64 z)
  127. {
  128. mdV[VX] = x;
  129. mdV[VY] = y;
  130. mdV[VZ] = z;
  131. }
  132. inline LLVector3d::LLVector3d(const F64 *vec)
  133. {
  134. mdV[VX] = vec[VX];
  135. mdV[VY] = vec[VY];
  136. mdV[VZ] = vec[VZ];
  137. }
  138. inline LLVector3d::LLVector3d(const LLVector3 &vec)
  139. {
  140. mdV[VX] = vec.mV[VX];
  141. mdV[VY] = vec.mV[VY];
  142. mdV[VZ] = vec.mV[VZ];
  143. }
  144. /*
  145. inline LLVector3d::LLVector3d(const LLVector3d &copy)
  146. {
  147. mdV[VX] = copy.mdV[VX];
  148. mdV[VY] = copy.mdV[VY];
  149. mdV[VZ] = copy.mdV[VZ];
  150. }
  151. */
  152. // Destructors
  153. // checker
  154. inline BOOL LLVector3d::isFinite() const
  155. {
  156. return (llfinite(mdV[VX]) && llfinite(mdV[VY]) && llfinite(mdV[VZ]));
  157. }
  158. // Clear and Assignment Functions
  159. inline const LLVector3d& LLVector3d::clearVec(void)
  160. {
  161. mdV[0] = 0.f;
  162. mdV[1] = 0.f;
  163. mdV[2]= 0.f;
  164. return (*this);
  165. }
  166. inline const LLVector3d& LLVector3d::setZero(void)
  167. {
  168. mdV[0] = 0.f;
  169. mdV[1] = 0.f;
  170. mdV[2] = 0.f;
  171. return (*this);
  172. }
  173. inline const LLVector3d& LLVector3d::zeroVec(void)
  174. {
  175. mdV[0] = 0.f;
  176. mdV[1] = 0.f;
  177. mdV[2] = 0.f;
  178. return (*this);
  179. }
  180. inline const LLVector3d& LLVector3d::setVec(const F64 x, const F64 y, const F64 z)
  181. {
  182. mdV[VX] = x;
  183. mdV[VY] = y;
  184. mdV[VZ] = z;
  185. return (*this);
  186. }
  187. inline const LLVector3d& LLVector3d::setVec(const LLVector3d &vec)
  188. {
  189. mdV[0] = vec.mdV[0];
  190. mdV[1] = vec.mdV[1];
  191. mdV[2] = vec.mdV[2];
  192. return (*this);
  193. }
  194. inline const LLVector3d& LLVector3d::setVec(const F64 *vec)
  195. {
  196. mdV[0] = vec[0];
  197. mdV[1] = vec[1];
  198. mdV[2] = vec[2];
  199. return (*this);
  200. }
  201. inline F64 LLVector3d::normVec(void)
  202. {
  203. F64 mag = fsqrtf(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  204. F64 oomag;
  205. if (mag > FP_MAG_THRESHOLD)
  206. {
  207. oomag = 1.f/mag;
  208. mdV[0] *= oomag;
  209. mdV[1] *= oomag;
  210. mdV[2] *= oomag;
  211. }
  212. else
  213. {
  214. mdV[0] = 0.f;
  215. mdV[1] = 0.f;
  216. mdV[2] = 0.f;
  217. mag = 0;
  218. }
  219. return (mag);
  220. }
  221. inline F64 LLVector3d::normalize(void)
  222. {
  223. F64 mag = fsqrtf(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  224. F64 oomag;
  225. if (mag > FP_MAG_THRESHOLD)
  226. {
  227. oomag = 1.f/mag;
  228. mdV[0] *= oomag;
  229. mdV[1] *= oomag;
  230. mdV[2] *= oomag;
  231. }
  232. else
  233. {
  234. mdV[0] = 0.f;
  235. mdV[1] = 0.f;
  236. mdV[2] = 0.f;
  237. mag = 0;
  238. }
  239. return (mag);
  240. }
  241. // LLVector3d Magnitude and Normalization Functions
  242. inline F64 LLVector3d::magVec(void) const
  243. {
  244. return fsqrtf(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  245. }
  246. inline F64 LLVector3d::magVecSquared(void) const
  247. {
  248. return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
  249. }
  250. inline F64 LLVector3d::length(void) const
  251. {
  252. return fsqrtf(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
  253. }
  254. inline F64 LLVector3d::lengthSquared(void) const
  255. {
  256. return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
  257. }
  258. inline LLVector3d operator+(const LLVector3d &a, const LLVector3d &b)
  259. {
  260. LLVector3d c(a);
  261. return c += b;
  262. }
  263. inline LLVector3d operator-(const LLVector3d &a, const LLVector3d &b)
  264. {
  265. LLVector3d c(a);
  266. return c -= b;
  267. }
  268. inline F64  operator*(const LLVector3d &a, const LLVector3d &b)
  269. {
  270. return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]);
  271. }
  272. inline LLVector3d operator%(const LLVector3d &a, const LLVector3d &b)
  273. {
  274. return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] );
  275. }
  276. inline LLVector3d operator/(const LLVector3d &a, const F64 k)
  277. {
  278. F64 t = 1.f / k;
  279. return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t );
  280. }
  281. inline LLVector3d operator*(const LLVector3d &a, const F64 k)
  282. {
  283. return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
  284. }
  285. inline LLVector3d operator*(F64 k, const LLVector3d &a)
  286. {
  287. return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
  288. }
  289. inline bool operator==(const LLVector3d &a, const LLVector3d &b)
  290. {
  291. return (  (a.mdV[0] == b.mdV[0])
  292. &&(a.mdV[1] == b.mdV[1])
  293. &&(a.mdV[2] == b.mdV[2]));
  294. }
  295. inline bool operator!=(const LLVector3d &a, const LLVector3d &b)
  296. {
  297. return (  (a.mdV[0] != b.mdV[0])
  298. ||(a.mdV[1] != b.mdV[1])
  299. ||(a.mdV[2] != b.mdV[2]));
  300. }
  301. inline const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b)
  302. {
  303. a.mdV[0] += b.mdV[0];
  304. a.mdV[1] += b.mdV[1];
  305. a.mdV[2] += b.mdV[2];
  306. return a;
  307. }
  308. inline const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b)
  309. {
  310. a.mdV[0] -= b.mdV[0];
  311. a.mdV[1] -= b.mdV[1];
  312. a.mdV[2] -= b.mdV[2];
  313. return a;
  314. }
  315. inline const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b)
  316. {
  317. LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]);
  318. a = ret;
  319. return a;
  320. }
  321. inline const LLVector3d& operator*=(LLVector3d &a, const F64 k)
  322. {
  323. a.mdV[0] *= k;
  324. a.mdV[1] *= k;
  325. a.mdV[2] *= k;
  326. return a;
  327. }
  328. inline const LLVector3d& operator/=(LLVector3d &a, const F64 k)
  329. {
  330. F64 t = 1.f / k;
  331. a.mdV[0] *= t;
  332. a.mdV[1] *= t;
  333. a.mdV[2] *= t;
  334. return a;
  335. }
  336. inline LLVector3d operator-(const LLVector3d &a)
  337. {
  338. return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] );
  339. }
  340. inline F64 dist_vec(const LLVector3d &a, const LLVector3d &b)
  341. {
  342. F64 x = a.mdV[0] - b.mdV[0];
  343. F64 y = a.mdV[1] - b.mdV[1];
  344. F64 z = a.mdV[2] - b.mdV[2];
  345. return fsqrtf( x*x + y*y + z*z );
  346. }
  347. inline F64 dist_vec_squared(const LLVector3d &a, const LLVector3d &b)
  348. {
  349. F64 x = a.mdV[0] - b.mdV[0];
  350. F64 y = a.mdV[1] - b.mdV[1];
  351. F64 z = a.mdV[2] - b.mdV[2];
  352. return x*x + y*y + z*z;
  353. }
  354. inline F64 dist_vec_squared2D(const LLVector3d &a, const LLVector3d &b)
  355. {
  356. F64 x = a.mdV[0] - b.mdV[0];
  357. F64 y = a.mdV[1] - b.mdV[1];
  358. return x*x + y*y;
  359. }
  360. inline LLVector3d lerp(const LLVector3d &a, const LLVector3d &b, const F64 u)
  361. {
  362. return LLVector3d(
  363. a.mdV[VX] + (b.mdV[VX] - a.mdV[VX]) * u,
  364. a.mdV[VY] + (b.mdV[VY] - a.mdV[VY]) * u,
  365. a.mdV[VZ] + (b.mdV[VZ] - a.mdV[VZ]) * u);
  366. }
  367. inline BOOL LLVector3d::isNull() const
  368. {
  369. if ( F_APPROXIMATELY_ZERO > mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ] )
  370. {
  371. return TRUE;
  372. }
  373. return FALSE;
  374. }
  375. inline F64 angle_between(const LLVector3d& a, const LLVector3d& b)
  376. {
  377. LLVector3d an = a;
  378. LLVector3d bn = b;
  379. an.normalize();
  380. bn.normalize();
  381. F64 cosine = an * bn;
  382. F64 angle = (cosine >= 1.0f) ? 0.0f :
  383. (cosine <= -1.0f) ? F_PI :
  384. acos(cosine);
  385. return angle;
  386. }
  387. inline BOOL are_parallel(const LLVector3d &a, const LLVector3d &b, const F64 epsilon)
  388. {
  389. LLVector3d an = a;
  390. LLVector3d bn = b;
  391. an.normalize();
  392. bn.normalize();
  393. F64 dot = an * bn;
  394. if ( (1.0f - fabs(dot)) < epsilon)
  395. {
  396. return TRUE;
  397. }
  398. return FALSE;
  399. }
  400. inline LLVector3d projected_vec(const LLVector3d &a, const LLVector3d &b)
  401. {
  402. LLVector3d project_axis = b;
  403. project_axis.normalize();
  404. return project_axis * (a * project_axis);
  405. }
  406. #endif // LL_V3DMATH_H