Vector.h 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __MATH_VECTOR_H__
  21. #define __MATH_VECTOR_H__
  22. /*
  23. ===============================================================================
  24. Vector classes
  25. ===============================================================================
  26. */
  27. #define VECTOR_EPSILON 0.001f
  28. class idAngles;
  29. class idPolar3;
  30. class idMat3;
  31. //===============================================================
  32. //
  33. // idVec2 - 2D vector
  34. //
  35. //===============================================================
  36. class idVec2 {
  37. public:
  38. float x;
  39. float y;
  40. idVec2( void );
  41. explicit idVec2( const float x, const float y );
  42. void Set( const float x, const float y );
  43. void Zero( void );
  44. float operator[]( int index ) const;
  45. float & operator[]( int index );
  46. idVec2 operator-() const;
  47. float operator*( const idVec2 &a ) const;
  48. idVec2 operator*( const float a ) const;
  49. idVec2 operator/( const float a ) const;
  50. idVec2 operator+( const idVec2 &a ) const;
  51. idVec2 operator-( const idVec2 &a ) const;
  52. idVec2 & operator+=( const idVec2 &a );
  53. idVec2 & operator-=( const idVec2 &a );
  54. idVec2 & operator/=( const idVec2 &a );
  55. idVec2 & operator/=( const float a );
  56. idVec2 & operator*=( const float a );
  57. friend idVec2 operator*( const float a, const idVec2 b );
  58. bool Compare( const idVec2 &a ) const; // exact compare, no epsilon
  59. bool Compare( const idVec2 &a, const float epsilon ) const; // compare with epsilon
  60. bool operator==( const idVec2 &a ) const; // exact compare, no epsilon
  61. bool operator!=( const idVec2 &a ) const; // exact compare, no epsilon
  62. float Length( void ) const;
  63. float LengthFast( void ) const;
  64. float LengthSqr( void ) const;
  65. float Normalize( void ); // returns length
  66. float NormalizeFast( void ); // returns length
  67. idVec2 & Truncate( float length ); // cap length
  68. void Clamp( const idVec2 &min, const idVec2 &max );
  69. void Snap( void ); // snap to closest integer value
  70. void SnapInt( void ); // snap towards integer (floor)
  71. int GetDimension( void ) const;
  72. const float * ToFloatPtr( void ) const;
  73. float * ToFloatPtr( void );
  74. const char * ToString( int precision = 2 ) const;
  75. void Lerp( const idVec2 &v1, const idVec2 &v2, const float l );
  76. };
  77. extern idVec2 vec2_origin;
  78. #define vec2_zero vec2_origin
  79. ID_INLINE idVec2::idVec2( void ) {
  80. }
  81. ID_INLINE idVec2::idVec2( const float x, const float y ) {
  82. this->x = x;
  83. this->y = y;
  84. }
  85. ID_INLINE void idVec2::Set( const float x, const float y ) {
  86. this->x = x;
  87. this->y = y;
  88. }
  89. ID_INLINE void idVec2::Zero( void ) {
  90. x = y = 0.0f;
  91. }
  92. ID_INLINE bool idVec2::Compare( const idVec2 &a ) const {
  93. return ( ( x == a.x ) && ( y == a.y ) );
  94. }
  95. ID_INLINE bool idVec2::Compare( const idVec2 &a, const float epsilon ) const {
  96. if ( idMath::Fabs( x - a.x ) > epsilon ) {
  97. return false;
  98. }
  99. if ( idMath::Fabs( y - a.y ) > epsilon ) {
  100. return false;
  101. }
  102. return true;
  103. }
  104. ID_INLINE bool idVec2::operator==( const idVec2 &a ) const {
  105. return Compare( a );
  106. }
  107. ID_INLINE bool idVec2::operator!=( const idVec2 &a ) const {
  108. return !Compare( a );
  109. }
  110. ID_INLINE float idVec2::operator[]( int index ) const {
  111. return ( &x )[ index ];
  112. }
  113. ID_INLINE float& idVec2::operator[]( int index ) {
  114. return ( &x )[ index ];
  115. }
  116. ID_INLINE float idVec2::Length( void ) const {
  117. return ( float )idMath::Sqrt( x * x + y * y );
  118. }
  119. ID_INLINE float idVec2::LengthFast( void ) const {
  120. float sqrLength;
  121. sqrLength = x * x + y * y;
  122. return sqrLength * idMath::RSqrt( sqrLength );
  123. }
  124. ID_INLINE float idVec2::LengthSqr( void ) const {
  125. return ( x * x + y * y );
  126. }
  127. ID_INLINE float idVec2::Normalize( void ) {
  128. float sqrLength, invLength;
  129. sqrLength = x * x + y * y;
  130. invLength = idMath::InvSqrt( sqrLength );
  131. x *= invLength;
  132. y *= invLength;
  133. return invLength * sqrLength;
  134. }
  135. ID_INLINE float idVec2::NormalizeFast( void ) {
  136. float lengthSqr, invLength;
  137. lengthSqr = x * x + y * y;
  138. invLength = idMath::RSqrt( lengthSqr );
  139. x *= invLength;
  140. y *= invLength;
  141. return invLength * lengthSqr;
  142. }
  143. ID_INLINE idVec2 &idVec2::Truncate( float length ) {
  144. float length2;
  145. float ilength;
  146. if ( !length ) {
  147. Zero();
  148. }
  149. else {
  150. length2 = LengthSqr();
  151. if ( length2 > length * length ) {
  152. ilength = length * idMath::InvSqrt( length2 );
  153. x *= ilength;
  154. y *= ilength;
  155. }
  156. }
  157. return *this;
  158. }
  159. ID_INLINE void idVec2::Clamp( const idVec2 &min, const idVec2 &max ) {
  160. if ( x < min.x ) {
  161. x = min.x;
  162. } else if ( x > max.x ) {
  163. x = max.x;
  164. }
  165. if ( y < min.y ) {
  166. y = min.y;
  167. } else if ( y > max.y ) {
  168. y = max.y;
  169. }
  170. }
  171. ID_INLINE void idVec2::Snap( void ) {
  172. x = floor( x + 0.5f );
  173. y = floor( y + 0.5f );
  174. }
  175. ID_INLINE void idVec2::SnapInt( void ) {
  176. x = float( int( x ) );
  177. y = float( int( y ) );
  178. }
  179. ID_INLINE idVec2 idVec2::operator-() const {
  180. return idVec2( -x, -y );
  181. }
  182. ID_INLINE idVec2 idVec2::operator-( const idVec2 &a ) const {
  183. return idVec2( x - a.x, y - a.y );
  184. }
  185. ID_INLINE float idVec2::operator*( const idVec2 &a ) const {
  186. return x * a.x + y * a.y;
  187. }
  188. ID_INLINE idVec2 idVec2::operator*( const float a ) const {
  189. return idVec2( x * a, y * a );
  190. }
  191. ID_INLINE idVec2 idVec2::operator/( const float a ) const {
  192. float inva = 1.0f / a;
  193. return idVec2( x * inva, y * inva );
  194. }
  195. ID_INLINE idVec2 operator*( const float a, const idVec2 b ) {
  196. return idVec2( b.x * a, b.y * a );
  197. }
  198. ID_INLINE idVec2 idVec2::operator+( const idVec2 &a ) const {
  199. return idVec2( x + a.x, y + a.y );
  200. }
  201. ID_INLINE idVec2 &idVec2::operator+=( const idVec2 &a ) {
  202. x += a.x;
  203. y += a.y;
  204. return *this;
  205. }
  206. ID_INLINE idVec2 &idVec2::operator/=( const idVec2 &a ) {
  207. x /= a.x;
  208. y /= a.y;
  209. return *this;
  210. }
  211. ID_INLINE idVec2 &idVec2::operator/=( const float a ) {
  212. float inva = 1.0f / a;
  213. x *= inva;
  214. y *= inva;
  215. return *this;
  216. }
  217. ID_INLINE idVec2 &idVec2::operator-=( const idVec2 &a ) {
  218. x -= a.x;
  219. y -= a.y;
  220. return *this;
  221. }
  222. ID_INLINE idVec2 &idVec2::operator*=( const float a ) {
  223. x *= a;
  224. y *= a;
  225. return *this;
  226. }
  227. ID_INLINE int idVec2::GetDimension( void ) const {
  228. return 2;
  229. }
  230. ID_INLINE const float *idVec2::ToFloatPtr( void ) const {
  231. return &x;
  232. }
  233. ID_INLINE float *idVec2::ToFloatPtr( void ) {
  234. return &x;
  235. }
  236. //===============================================================
  237. //
  238. // idVec3 - 3D vector
  239. //
  240. //===============================================================
  241. class idVec3 {
  242. public:
  243. float x;
  244. float y;
  245. float z;
  246. idVec3( void );
  247. explicit idVec3( const float x, const float y, const float z );
  248. void Set( const float x, const float y, const float z );
  249. void Zero( void );
  250. float operator[]( const int index ) const;
  251. float & operator[]( const int index );
  252. idVec3 operator-() const;
  253. idVec3 & operator=( const idVec3 &a ); // required because of a msvc 6 & 7 bug
  254. float operator*( const idVec3 &a ) const;
  255. idVec3 operator*( const float a ) const;
  256. idVec3 operator/( const float a ) const;
  257. idVec3 operator+( const idVec3 &a ) const;
  258. idVec3 operator-( const idVec3 &a ) const;
  259. idVec3 & operator+=( const idVec3 &a );
  260. idVec3 & operator-=( const idVec3 &a );
  261. idVec3 & operator/=( const idVec3 &a );
  262. idVec3 & operator/=( const float a );
  263. idVec3 & operator*=( const float a );
  264. friend idVec3 operator*( const float a, const idVec3 b );
  265. bool Compare( const idVec3 &a ) const; // exact compare, no epsilon
  266. bool Compare( const idVec3 &a, const float epsilon ) const; // compare with epsilon
  267. bool operator==( const idVec3 &a ) const; // exact compare, no epsilon
  268. bool operator!=( const idVec3 &a ) const; // exact compare, no epsilon
  269. bool FixDegenerateNormal( void ); // fix degenerate axial cases
  270. bool FixDenormals( void ); // change tiny numbers to zero
  271. idVec3 Cross( const idVec3 &a ) const;
  272. idVec3 & Cross( const idVec3 &a, const idVec3 &b );
  273. float Length( void ) const;
  274. float LengthSqr( void ) const;
  275. float LengthFast( void ) const;
  276. float Normalize( void ); // returns length
  277. float NormalizeFast( void ); // returns length
  278. idVec3 & Truncate( float length ); // cap length
  279. void Clamp( const idVec3 &min, const idVec3 &max );
  280. void Snap( void ); // snap to closest integer value
  281. void SnapInt( void ); // snap towards integer (floor)
  282. int GetDimension( void ) const;
  283. float ToYaw( void ) const;
  284. float ToPitch( void ) const;
  285. idAngles ToAngles( void ) const;
  286. idPolar3 ToPolar( void ) const;
  287. idMat3 ToMat3( void ) const; // vector should be normalized
  288. const idVec2 & ToVec2( void ) const;
  289. idVec2 & ToVec2( void );
  290. const float * ToFloatPtr( void ) const;
  291. float * ToFloatPtr( void );
  292. const char * ToString( int precision = 2 ) const;
  293. void NormalVectors( idVec3 &left, idVec3 &down ) const; // vector should be normalized
  294. void OrthogonalBasis( idVec3 &left, idVec3 &up ) const;
  295. void ProjectOntoPlane( const idVec3 &normal, const float overBounce = 1.0f );
  296. bool ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce = 1.0f );
  297. void ProjectSelfOntoSphere( const float radius );
  298. void Lerp( const idVec3 &v1, const idVec3 &v2, const float l );
  299. void SLerp( const idVec3 &v1, const idVec3 &v2, const float l );
  300. };
  301. extern idVec3 vec3_origin;
  302. #define vec3_zero vec3_origin
  303. ID_INLINE idVec3::idVec3( void ) {
  304. }
  305. ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) {
  306. this->x = x;
  307. this->y = y;
  308. this->z = z;
  309. }
  310. ID_INLINE float idVec3::operator[]( const int index ) const {
  311. return ( &x )[ index ];
  312. }
  313. ID_INLINE float &idVec3::operator[]( const int index ) {
  314. return ( &x )[ index ];
  315. }
  316. ID_INLINE void idVec3::Set( const float x, const float y, const float z ) {
  317. this->x = x;
  318. this->y = y;
  319. this->z = z;
  320. }
  321. ID_INLINE void idVec3::Zero( void ) {
  322. x = y = z = 0.0f;
  323. }
  324. ID_INLINE idVec3 idVec3::operator-() const {
  325. return idVec3( -x, -y, -z );
  326. }
  327. ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) {
  328. x = a.x;
  329. y = a.y;
  330. z = a.z;
  331. return *this;
  332. }
  333. ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const {
  334. return idVec3( x - a.x, y - a.y, z - a.z );
  335. }
  336. ID_INLINE float idVec3::operator*( const idVec3 &a ) const {
  337. return x * a.x + y * a.y + z * a.z;
  338. }
  339. ID_INLINE idVec3 idVec3::operator*( const float a ) const {
  340. return idVec3( x * a, y * a, z * a );
  341. }
  342. ID_INLINE idVec3 idVec3::operator/( const float a ) const {
  343. float inva = 1.0f / a;
  344. return idVec3( x * inva, y * inva, z * inva );
  345. }
  346. ID_INLINE idVec3 operator*( const float a, const idVec3 b ) {
  347. return idVec3( b.x * a, b.y * a, b.z * a );
  348. }
  349. ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const {
  350. return idVec3( x + a.x, y + a.y, z + a.z );
  351. }
  352. ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) {
  353. x += a.x;
  354. y += a.y;
  355. z += a.z;
  356. return *this;
  357. }
  358. ID_INLINE idVec3 &idVec3::operator/=( const idVec3 &a ) {
  359. x /= a.x;
  360. y /= a.y;
  361. z /= a.z;
  362. return *this;
  363. }
  364. ID_INLINE idVec3 &idVec3::operator/=( const float a ) {
  365. float inva = 1.0f / a;
  366. x *= inva;
  367. y *= inva;
  368. z *= inva;
  369. return *this;
  370. }
  371. ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) {
  372. x -= a.x;
  373. y -= a.y;
  374. z -= a.z;
  375. return *this;
  376. }
  377. ID_INLINE idVec3 &idVec3::operator*=( const float a ) {
  378. x *= a;
  379. y *= a;
  380. z *= a;
  381. return *this;
  382. }
  383. ID_INLINE bool idVec3::Compare( const idVec3 &a ) const {
  384. return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) );
  385. }
  386. ID_INLINE bool idVec3::Compare( const idVec3 &a, const float epsilon ) const {
  387. if ( idMath::Fabs( x - a.x ) > epsilon ) {
  388. return false;
  389. }
  390. if ( idMath::Fabs( y - a.y ) > epsilon ) {
  391. return false;
  392. }
  393. if ( idMath::Fabs( z - a.z ) > epsilon ) {
  394. return false;
  395. }
  396. return true;
  397. }
  398. ID_INLINE bool idVec3::operator==( const idVec3 &a ) const {
  399. return Compare( a );
  400. }
  401. ID_INLINE bool idVec3::operator!=( const idVec3 &a ) const {
  402. return !Compare( a );
  403. }
  404. ID_INLINE float idVec3::NormalizeFast( void ) {
  405. float sqrLength, invLength;
  406. sqrLength = x * x + y * y + z * z;
  407. invLength = idMath::RSqrt( sqrLength );
  408. x *= invLength;
  409. y *= invLength;
  410. z *= invLength;
  411. return invLength * sqrLength;
  412. }
  413. ID_INLINE bool idVec3::FixDegenerateNormal( void ) {
  414. if ( x == 0.0f ) {
  415. if ( y == 0.0f ) {
  416. if ( z > 0.0f ) {
  417. if ( z != 1.0f ) {
  418. z = 1.0f;
  419. return true;
  420. }
  421. } else {
  422. if ( z != -1.0f ) {
  423. z = -1.0f;
  424. return true;
  425. }
  426. }
  427. return false;
  428. } else if ( z == 0.0f ) {
  429. if ( y > 0.0f ) {
  430. if ( y != 1.0f ) {
  431. y = 1.0f;
  432. return true;
  433. }
  434. } else {
  435. if ( y != -1.0f ) {
  436. y = -1.0f;
  437. return true;
  438. }
  439. }
  440. return false;
  441. }
  442. } else if ( y == 0.0f ) {
  443. if ( z == 0.0f ) {
  444. if ( x > 0.0f ) {
  445. if ( x != 1.0f ) {
  446. x = 1.0f;
  447. return true;
  448. }
  449. } else {
  450. if ( x != -1.0f ) {
  451. x = -1.0f;
  452. return true;
  453. }
  454. }
  455. return false;
  456. }
  457. }
  458. if ( idMath::Fabs( x ) == 1.0f ) {
  459. if ( y != 0.0f || z != 0.0f ) {
  460. y = z = 0.0f;
  461. return true;
  462. }
  463. return false;
  464. } else if ( idMath::Fabs( y ) == 1.0f ) {
  465. if ( x != 0.0f || z != 0.0f ) {
  466. x = z = 0.0f;
  467. return true;
  468. }
  469. return false;
  470. } else if ( idMath::Fabs( z ) == 1.0f ) {
  471. if ( x != 0.0f || y != 0.0f ) {
  472. x = y = 0.0f;
  473. return true;
  474. }
  475. return false;
  476. }
  477. return false;
  478. }
  479. ID_INLINE bool idVec3::FixDenormals( void ) {
  480. bool denormal = false;
  481. if ( fabs( x ) < 1e-30f ) {
  482. x = 0.0f;
  483. denormal = true;
  484. }
  485. if ( fabs( y ) < 1e-30f ) {
  486. y = 0.0f;
  487. denormal = true;
  488. }
  489. if ( fabs( z ) < 1e-30f ) {
  490. z = 0.0f;
  491. denormal = true;
  492. }
  493. return denormal;
  494. }
  495. ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const {
  496. return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x );
  497. }
  498. ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) {
  499. x = a.y * b.z - a.z * b.y;
  500. y = a.z * b.x - a.x * b.z;
  501. z = a.x * b.y - a.y * b.x;
  502. return *this;
  503. }
  504. ID_INLINE float idVec3::Length( void ) const {
  505. return ( float )idMath::Sqrt( x * x + y * y + z * z );
  506. }
  507. ID_INLINE float idVec3::LengthSqr( void ) const {
  508. return ( x * x + y * y + z * z );
  509. }
  510. ID_INLINE float idVec3::LengthFast( void ) const {
  511. float sqrLength;
  512. sqrLength = x * x + y * y + z * z;
  513. return sqrLength * idMath::RSqrt( sqrLength );
  514. }
  515. ID_INLINE float idVec3::Normalize( void ) {
  516. float sqrLength, invLength;
  517. sqrLength = x * x + y * y + z * z;
  518. invLength = idMath::InvSqrt( sqrLength );
  519. x *= invLength;
  520. y *= invLength;
  521. z *= invLength;
  522. return invLength * sqrLength;
  523. }
  524. ID_INLINE idVec3 &idVec3::Truncate( float length ) {
  525. float length2;
  526. float ilength;
  527. if ( !length ) {
  528. Zero();
  529. }
  530. else {
  531. length2 = LengthSqr();
  532. if ( length2 > length * length ) {
  533. ilength = length * idMath::InvSqrt( length2 );
  534. x *= ilength;
  535. y *= ilength;
  536. z *= ilength;
  537. }
  538. }
  539. return *this;
  540. }
  541. ID_INLINE void idVec3::Clamp( const idVec3 &min, const idVec3 &max ) {
  542. if ( x < min.x ) {
  543. x = min.x;
  544. } else if ( x > max.x ) {
  545. x = max.x;
  546. }
  547. if ( y < min.y ) {
  548. y = min.y;
  549. } else if ( y > max.y ) {
  550. y = max.y;
  551. }
  552. if ( z < min.z ) {
  553. z = min.z;
  554. } else if ( z > max.z ) {
  555. z = max.z;
  556. }
  557. }
  558. ID_INLINE void idVec3::Snap( void ) {
  559. x = floor( x + 0.5f );
  560. y = floor( y + 0.5f );
  561. z = floor( z + 0.5f );
  562. }
  563. ID_INLINE void idVec3::SnapInt( void ) {
  564. x = float( int( x ) );
  565. y = float( int( y ) );
  566. z = float( int( z ) );
  567. }
  568. ID_INLINE int idVec3::GetDimension( void ) const {
  569. return 3;
  570. }
  571. ID_INLINE const idVec2 &idVec3::ToVec2( void ) const {
  572. return *reinterpret_cast<const idVec2 *>(this);
  573. }
  574. ID_INLINE idVec2 &idVec3::ToVec2( void ) {
  575. return *reinterpret_cast<idVec2 *>(this);
  576. }
  577. ID_INLINE const float *idVec3::ToFloatPtr( void ) const {
  578. return &x;
  579. }
  580. ID_INLINE float *idVec3::ToFloatPtr( void ) {
  581. return &x;
  582. }
  583. ID_INLINE void idVec3::NormalVectors( idVec3 &left, idVec3 &down ) const {
  584. float d;
  585. d = x * x + y * y;
  586. if ( !d ) {
  587. left[0] = 1;
  588. left[1] = 0;
  589. left[2] = 0;
  590. } else {
  591. d = idMath::InvSqrt( d );
  592. left[0] = -y * d;
  593. left[1] = x * d;
  594. left[2] = 0;
  595. }
  596. down = left.Cross( *this );
  597. }
  598. ID_INLINE void idVec3::OrthogonalBasis( idVec3 &left, idVec3 &up ) const {
  599. float l, s;
  600. if ( idMath::Fabs( z ) > 0.7f ) {
  601. l = y * y + z * z;
  602. s = idMath::InvSqrt( l );
  603. up[0] = 0;
  604. up[1] = z * s;
  605. up[2] = -y * s;
  606. left[0] = l * s;
  607. left[1] = -x * up[2];
  608. left[2] = x * up[1];
  609. }
  610. else {
  611. l = x * x + y * y;
  612. s = idMath::InvSqrt( l );
  613. left[0] = -y * s;
  614. left[1] = x * s;
  615. left[2] = 0;
  616. up[0] = -z * left[1];
  617. up[1] = z * left[0];
  618. up[2] = l * s;
  619. }
  620. }
  621. ID_INLINE void idVec3::ProjectOntoPlane( const idVec3 &normal, const float overBounce ) {
  622. float backoff;
  623. backoff = *this * normal;
  624. if ( overBounce != 1.0 ) {
  625. if ( backoff < 0 ) {
  626. backoff *= overBounce;
  627. } else {
  628. backoff /= overBounce;
  629. }
  630. }
  631. *this -= backoff * normal;
  632. }
  633. ID_INLINE bool idVec3::ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce ) {
  634. idVec3 cross;
  635. float len;
  636. cross = this->Cross( normal ).Cross( (*this) );
  637. // normalize so a fixed epsilon can be used
  638. cross.Normalize();
  639. len = normal * cross;
  640. if ( idMath::Fabs( len ) < epsilon ) {
  641. return false;
  642. }
  643. cross *= overBounce * ( normal * (*this) ) / len;
  644. (*this) -= cross;
  645. return true;
  646. }
  647. //===============================================================
  648. //
  649. // idVec4 - 4D vector
  650. //
  651. //===============================================================
  652. class idVec4 {
  653. public:
  654. float x;
  655. float y;
  656. float z;
  657. float w;
  658. idVec4( void );
  659. explicit idVec4( const float x, const float y, const float z, const float w );
  660. void Set( const float x, const float y, const float z, const float w );
  661. void Zero( void );
  662. float operator[]( const int index ) const;
  663. float & operator[]( const int index );
  664. idVec4 operator-() const;
  665. float operator*( const idVec4 &a ) const;
  666. idVec4 operator*( const float a ) const;
  667. idVec4 operator/( const float a ) const;
  668. idVec4 operator+( const idVec4 &a ) const;
  669. idVec4 operator-( const idVec4 &a ) const;
  670. idVec4 & operator+=( const idVec4 &a );
  671. idVec4 & operator-=( const idVec4 &a );
  672. idVec4 & operator/=( const idVec4 &a );
  673. idVec4 & operator/=( const float a );
  674. idVec4 & operator*=( const float a );
  675. friend idVec4 operator*( const float a, const idVec4 b );
  676. bool Compare( const idVec4 &a ) const; // exact compare, no epsilon
  677. bool Compare( const idVec4 &a, const float epsilon ) const; // compare with epsilon
  678. bool operator==( const idVec4 &a ) const; // exact compare, no epsilon
  679. bool operator!=( const idVec4 &a ) const; // exact compare, no epsilon
  680. float Length( void ) const;
  681. float LengthSqr( void ) const;
  682. float Normalize( void ); // returns length
  683. float NormalizeFast( void ); // returns length
  684. int GetDimension( void ) const;
  685. const idVec2 & ToVec2( void ) const;
  686. idVec2 & ToVec2( void );
  687. const idVec3 & ToVec3( void ) const;
  688. idVec3 & ToVec3( void );
  689. const float * ToFloatPtr( void ) const;
  690. float * ToFloatPtr( void );
  691. const char * ToString( int precision = 2 ) const;
  692. void Lerp( const idVec4 &v1, const idVec4 &v2, const float l );
  693. };
  694. extern idVec4 vec4_origin;
  695. #define vec4_zero vec4_origin
  696. ID_INLINE idVec4::idVec4( void ) {
  697. }
  698. ID_INLINE idVec4::idVec4( const float x, const float y, const float z, const float w ) {
  699. this->x = x;
  700. this->y = y;
  701. this->z = z;
  702. this->w = w;
  703. }
  704. ID_INLINE void idVec4::Set( const float x, const float y, const float z, const float w ) {
  705. this->x = x;
  706. this->y = y;
  707. this->z = z;
  708. this->w = w;
  709. }
  710. ID_INLINE void idVec4::Zero( void ) {
  711. x = y = z = w = 0.0f;
  712. }
  713. ID_INLINE float idVec4::operator[]( int index ) const {
  714. return ( &x )[ index ];
  715. }
  716. ID_INLINE float& idVec4::operator[]( int index ) {
  717. return ( &x )[ index ];
  718. }
  719. ID_INLINE idVec4 idVec4::operator-() const {
  720. return idVec4( -x, -y, -z, -w );
  721. }
  722. ID_INLINE idVec4 idVec4::operator-( const idVec4 &a ) const {
  723. return idVec4( x - a.x, y - a.y, z - a.z, w - a.w );
  724. }
  725. ID_INLINE float idVec4::operator*( const idVec4 &a ) const {
  726. return x * a.x + y * a.y + z * a.z + w * a.w;
  727. }
  728. ID_INLINE idVec4 idVec4::operator*( const float a ) const {
  729. return idVec4( x * a, y * a, z * a, w * a );
  730. }
  731. ID_INLINE idVec4 idVec4::operator/( const float a ) const {
  732. float inva = 1.0f / a;
  733. return idVec4( x * inva, y * inva, z * inva, w * inva );
  734. }
  735. ID_INLINE idVec4 operator*( const float a, const idVec4 b ) {
  736. return idVec4( b.x * a, b.y * a, b.z * a, b.w * a );
  737. }
  738. ID_INLINE idVec4 idVec4::operator+( const idVec4 &a ) const {
  739. return idVec4( x + a.x, y + a.y, z + a.z, w + a.w );
  740. }
  741. ID_INLINE idVec4 &idVec4::operator+=( const idVec4 &a ) {
  742. x += a.x;
  743. y += a.y;
  744. z += a.z;
  745. w += a.w;
  746. return *this;
  747. }
  748. ID_INLINE idVec4 &idVec4::operator/=( const idVec4 &a ) {
  749. x /= a.x;
  750. y /= a.y;
  751. z /= a.z;
  752. w /= a.w;
  753. return *this;
  754. }
  755. ID_INLINE idVec4 &idVec4::operator/=( const float a ) {
  756. float inva = 1.0f / a;
  757. x *= inva;
  758. y *= inva;
  759. z *= inva;
  760. w *= inva;
  761. return *this;
  762. }
  763. ID_INLINE idVec4 &idVec4::operator-=( const idVec4 &a ) {
  764. x -= a.x;
  765. y -= a.y;
  766. z -= a.z;
  767. w -= a.w;
  768. return *this;
  769. }
  770. ID_INLINE idVec4 &idVec4::operator*=( const float a ) {
  771. x *= a;
  772. y *= a;
  773. z *= a;
  774. w *= a;
  775. return *this;
  776. }
  777. ID_INLINE bool idVec4::Compare( const idVec4 &a ) const {
  778. return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && w == a.w );
  779. }
  780. ID_INLINE bool idVec4::Compare( const idVec4 &a, const float epsilon ) const {
  781. if ( idMath::Fabs( x - a.x ) > epsilon ) {
  782. return false;
  783. }
  784. if ( idMath::Fabs( y - a.y ) > epsilon ) {
  785. return false;
  786. }
  787. if ( idMath::Fabs( z - a.z ) > epsilon ) {
  788. return false;
  789. }
  790. if ( idMath::Fabs( w - a.w ) > epsilon ) {
  791. return false;
  792. }
  793. return true;
  794. }
  795. ID_INLINE bool idVec4::operator==( const idVec4 &a ) const {
  796. return Compare( a );
  797. }
  798. ID_INLINE bool idVec4::operator!=( const idVec4 &a ) const {
  799. return !Compare( a );
  800. }
  801. ID_INLINE float idVec4::Length( void ) const {
  802. return ( float )idMath::Sqrt( x * x + y * y + z * z + w * w );
  803. }
  804. ID_INLINE float idVec4::LengthSqr( void ) const {
  805. return ( x * x + y * y + z * z + w * w );
  806. }
  807. ID_INLINE float idVec4::Normalize( void ) {
  808. float sqrLength, invLength;
  809. sqrLength = x * x + y * y + z * z + w * w;
  810. invLength = idMath::InvSqrt( sqrLength );
  811. x *= invLength;
  812. y *= invLength;
  813. z *= invLength;
  814. w *= invLength;
  815. return invLength * sqrLength;
  816. }
  817. ID_INLINE float idVec4::NormalizeFast( void ) {
  818. float sqrLength, invLength;
  819. sqrLength = x * x + y * y + z * z + w * w;
  820. invLength = idMath::RSqrt( sqrLength );
  821. x *= invLength;
  822. y *= invLength;
  823. z *= invLength;
  824. w *= invLength;
  825. return invLength * sqrLength;
  826. }
  827. ID_INLINE int idVec4::GetDimension( void ) const {
  828. return 4;
  829. }
  830. ID_INLINE const idVec2 &idVec4::ToVec2( void ) const {
  831. return *reinterpret_cast<const idVec2 *>(this);
  832. }
  833. ID_INLINE idVec2 &idVec4::ToVec2( void ) {
  834. return *reinterpret_cast<idVec2 *>(this);
  835. }
  836. ID_INLINE const idVec3 &idVec4::ToVec3( void ) const {
  837. return *reinterpret_cast<const idVec3 *>(this);
  838. }
  839. ID_INLINE idVec3 &idVec4::ToVec3( void ) {
  840. return *reinterpret_cast<idVec3 *>(this);
  841. }
  842. ID_INLINE const float *idVec4::ToFloatPtr( void ) const {
  843. return &x;
  844. }
  845. ID_INLINE float *idVec4::ToFloatPtr( void ) {
  846. return &x;
  847. }
  848. //===============================================================
  849. //
  850. // idVec5 - 5D vector
  851. //
  852. //===============================================================
  853. class idVec5 {
  854. public:
  855. float x;
  856. float y;
  857. float z;
  858. float s;
  859. float t;
  860. idVec5( void );
  861. explicit idVec5( const idVec3 &xyz, const idVec2 &st );
  862. explicit idVec5( const float x, const float y, const float z, const float s, const float t );
  863. float operator[]( int index ) const;
  864. float & operator[]( int index );
  865. idVec5 & operator=( const idVec3 &a );
  866. int GetDimension( void ) const;
  867. const idVec3 & ToVec3( void ) const;
  868. idVec3 & ToVec3( void );
  869. const float * ToFloatPtr( void ) const;
  870. float * ToFloatPtr( void );
  871. const char * ToString( int precision = 2 ) const;
  872. void Lerp( const idVec5 &v1, const idVec5 &v2, const float l );
  873. };
  874. extern idVec5 vec5_origin;
  875. #define vec5_zero vec5_origin
  876. ID_INLINE idVec5::idVec5( void ) {
  877. }
  878. ID_INLINE idVec5::idVec5( const idVec3 &xyz, const idVec2 &st ) {
  879. x = xyz.x;
  880. y = xyz.y;
  881. z = xyz.z;
  882. s = st[0];
  883. t = st[1];
  884. }
  885. ID_INLINE idVec5::idVec5( const float x, const float y, const float z, const float s, const float t ) {
  886. this->x = x;
  887. this->y = y;
  888. this->z = z;
  889. this->s = s;
  890. this->t = t;
  891. }
  892. ID_INLINE float idVec5::operator[]( int index ) const {
  893. return ( &x )[ index ];
  894. }
  895. ID_INLINE float& idVec5::operator[]( int index ) {
  896. return ( &x )[ index ];
  897. }
  898. ID_INLINE idVec5 &idVec5::operator=( const idVec3 &a ) {
  899. x = a.x;
  900. y = a.y;
  901. z = a.z;
  902. s = t = 0;
  903. return *this;
  904. }
  905. ID_INLINE int idVec5::GetDimension( void ) const {
  906. return 5;
  907. }
  908. ID_INLINE const idVec3 &idVec5::ToVec3( void ) const {
  909. return *reinterpret_cast<const idVec3 *>(this);
  910. }
  911. ID_INLINE idVec3 &idVec5::ToVec3( void ) {
  912. return *reinterpret_cast<idVec3 *>(this);
  913. }
  914. ID_INLINE const float *idVec5::ToFloatPtr( void ) const {
  915. return &x;
  916. }
  917. ID_INLINE float *idVec5::ToFloatPtr( void ) {
  918. return &x;
  919. }
  920. //===============================================================
  921. //
  922. // idVec6 - 6D vector
  923. //
  924. //===============================================================
  925. class idVec6 {
  926. public:
  927. idVec6( void );
  928. explicit idVec6( const float *a );
  929. explicit idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 );
  930. void Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 );
  931. void Zero( void );
  932. float operator[]( const int index ) const;
  933. float & operator[]( const int index );
  934. idVec6 operator-() const;
  935. idVec6 operator*( const float a ) const;
  936. idVec6 operator/( const float a ) const;
  937. float operator*( const idVec6 &a ) const;
  938. idVec6 operator-( const idVec6 &a ) const;
  939. idVec6 operator+( const idVec6 &a ) const;
  940. idVec6 & operator*=( const float a );
  941. idVec6 & operator/=( const float a );
  942. idVec6 & operator+=( const idVec6 &a );
  943. idVec6 & operator-=( const idVec6 &a );
  944. friend idVec6 operator*( const float a, const idVec6 b );
  945. bool Compare( const idVec6 &a ) const; // exact compare, no epsilon
  946. bool Compare( const idVec6 &a, const float epsilon ) const; // compare with epsilon
  947. bool operator==( const idVec6 &a ) const; // exact compare, no epsilon
  948. bool operator!=( const idVec6 &a ) const; // exact compare, no epsilon
  949. float Length( void ) const;
  950. float LengthSqr( void ) const;
  951. float Normalize( void ); // returns length
  952. float NormalizeFast( void ); // returns length
  953. int GetDimension( void ) const;
  954. const idVec3 & SubVec3( int index ) const;
  955. idVec3 & SubVec3( int index );
  956. const float * ToFloatPtr( void ) const;
  957. float * ToFloatPtr( void );
  958. const char * ToString( int precision = 2 ) const;
  959. private:
  960. float p[6];
  961. };
  962. extern idVec6 vec6_origin;
  963. #define vec6_zero vec6_origin
  964. extern idVec6 vec6_infinity;
  965. ID_INLINE idVec6::idVec6( void ) {
  966. }
  967. ID_INLINE idVec6::idVec6( const float *a ) {
  968. memcpy( p, a, 6 * sizeof( float ) );
  969. }
  970. ID_INLINE idVec6::idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) {
  971. p[0] = a1;
  972. p[1] = a2;
  973. p[2] = a3;
  974. p[3] = a4;
  975. p[4] = a5;
  976. p[5] = a6;
  977. }
  978. ID_INLINE idVec6 idVec6::operator-() const {
  979. return idVec6( -p[0], -p[1], -p[2], -p[3], -p[4], -p[5] );
  980. }
  981. ID_INLINE float idVec6::operator[]( const int index ) const {
  982. return p[index];
  983. }
  984. ID_INLINE float &idVec6::operator[]( const int index ) {
  985. return p[index];
  986. }
  987. ID_INLINE idVec6 idVec6::operator*( const float a ) const {
  988. return idVec6( p[0]*a, p[1]*a, p[2]*a, p[3]*a, p[4]*a, p[5]*a );
  989. }
  990. ID_INLINE float idVec6::operator*( const idVec6 &a ) const {
  991. return p[0] * a[0] + p[1] * a[1] + p[2] * a[2] + p[3] * a[3] + p[4] * a[4] + p[5] * a[5];
  992. }
  993. ID_INLINE idVec6 idVec6::operator/( const float a ) const {
  994. float inva;
  995. assert( a != 0.0f );
  996. inva = 1.0f / a;
  997. return idVec6( p[0]*inva, p[1]*inva, p[2]*inva, p[3]*inva, p[4]*inva, p[5]*inva );
  998. }
  999. ID_INLINE idVec6 idVec6::operator+( const idVec6 &a ) const {
  1000. return idVec6( p[0] + a[0], p[1] + a[1], p[2] + a[2], p[3] + a[3], p[4] + a[4], p[5] + a[5] );
  1001. }
  1002. ID_INLINE idVec6 idVec6::operator-( const idVec6 &a ) const {
  1003. return idVec6( p[0] - a[0], p[1] - a[1], p[2] - a[2], p[3] - a[3], p[4] - a[4], p[5] - a[5] );
  1004. }
  1005. ID_INLINE idVec6 &idVec6::operator*=( const float a ) {
  1006. p[0] *= a;
  1007. p[1] *= a;
  1008. p[2] *= a;
  1009. p[3] *= a;
  1010. p[4] *= a;
  1011. p[5] *= a;
  1012. return *this;
  1013. }
  1014. ID_INLINE idVec6 &idVec6::operator/=( const float a ) {
  1015. float inva;
  1016. assert( a != 0.0f );
  1017. inva = 1.0f / a;
  1018. p[0] *= inva;
  1019. p[1] *= inva;
  1020. p[2] *= inva;
  1021. p[3] *= inva;
  1022. p[4] *= inva;
  1023. p[5] *= inva;
  1024. return *this;
  1025. }
  1026. ID_INLINE idVec6 &idVec6::operator+=( const idVec6 &a ) {
  1027. p[0] += a[0];
  1028. p[1] += a[1];
  1029. p[2] += a[2];
  1030. p[3] += a[3];
  1031. p[4] += a[4];
  1032. p[5] += a[5];
  1033. return *this;
  1034. }
  1035. ID_INLINE idVec6 &idVec6::operator-=( const idVec6 &a ) {
  1036. p[0] -= a[0];
  1037. p[1] -= a[1];
  1038. p[2] -= a[2];
  1039. p[3] -= a[3];
  1040. p[4] -= a[4];
  1041. p[5] -= a[5];
  1042. return *this;
  1043. }
  1044. ID_INLINE idVec6 operator*( const float a, const idVec6 b ) {
  1045. return b * a;
  1046. }
  1047. ID_INLINE bool idVec6::Compare( const idVec6 &a ) const {
  1048. return ( ( p[0] == a[0] ) && ( p[1] == a[1] ) && ( p[2] == a[2] ) &&
  1049. ( p[3] == a[3] ) && ( p[4] == a[4] ) && ( p[5] == a[5] ) );
  1050. }
  1051. ID_INLINE bool idVec6::Compare( const idVec6 &a, const float epsilon ) const {
  1052. if ( idMath::Fabs( p[0] - a[0] ) > epsilon ) {
  1053. return false;
  1054. }
  1055. if ( idMath::Fabs( p[1] - a[1] ) > epsilon ) {
  1056. return false;
  1057. }
  1058. if ( idMath::Fabs( p[2] - a[2] ) > epsilon ) {
  1059. return false;
  1060. }
  1061. if ( idMath::Fabs( p[3] - a[3] ) > epsilon ) {
  1062. return false;
  1063. }
  1064. if ( idMath::Fabs( p[4] - a[4] ) > epsilon ) {
  1065. return false;
  1066. }
  1067. if ( idMath::Fabs( p[5] - a[5] ) > epsilon ) {
  1068. return false;
  1069. }
  1070. return true;
  1071. }
  1072. ID_INLINE bool idVec6::operator==( const idVec6 &a ) const {
  1073. return Compare( a );
  1074. }
  1075. ID_INLINE bool idVec6::operator!=( const idVec6 &a ) const {
  1076. return !Compare( a );
  1077. }
  1078. ID_INLINE void idVec6::Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) {
  1079. p[0] = a1;
  1080. p[1] = a2;
  1081. p[2] = a3;
  1082. p[3] = a4;
  1083. p[4] = a5;
  1084. p[5] = a6;
  1085. }
  1086. ID_INLINE void idVec6::Zero( void ) {
  1087. p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0.0f;
  1088. }
  1089. ID_INLINE float idVec6::Length( void ) const {
  1090. return ( float )idMath::Sqrt( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] );
  1091. }
  1092. ID_INLINE float idVec6::LengthSqr( void ) const {
  1093. return ( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] );
  1094. }
  1095. ID_INLINE float idVec6::Normalize( void ) {
  1096. float sqrLength, invLength;
  1097. sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5];
  1098. invLength = idMath::InvSqrt( sqrLength );
  1099. p[0] *= invLength;
  1100. p[1] *= invLength;
  1101. p[2] *= invLength;
  1102. p[3] *= invLength;
  1103. p[4] *= invLength;
  1104. p[5] *= invLength;
  1105. return invLength * sqrLength;
  1106. }
  1107. ID_INLINE float idVec6::NormalizeFast( void ) {
  1108. float sqrLength, invLength;
  1109. sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5];
  1110. invLength = idMath::RSqrt( sqrLength );
  1111. p[0] *= invLength;
  1112. p[1] *= invLength;
  1113. p[2] *= invLength;
  1114. p[3] *= invLength;
  1115. p[4] *= invLength;
  1116. p[5] *= invLength;
  1117. return invLength * sqrLength;
  1118. }
  1119. ID_INLINE int idVec6::GetDimension( void ) const {
  1120. return 6;
  1121. }
  1122. ID_INLINE const idVec3 &idVec6::SubVec3( int index ) const {
  1123. return *reinterpret_cast<const idVec3 *>(p + index * 3);
  1124. }
  1125. ID_INLINE idVec3 &idVec6::SubVec3( int index ) {
  1126. return *reinterpret_cast<idVec3 *>(p + index * 3);
  1127. }
  1128. ID_INLINE const float *idVec6::ToFloatPtr( void ) const {
  1129. return p;
  1130. }
  1131. ID_INLINE float *idVec6::ToFloatPtr( void ) {
  1132. return p;
  1133. }
  1134. //===============================================================
  1135. //
  1136. // idVecX - arbitrary sized vector
  1137. //
  1138. // The vector lives on 16 byte aligned and 16 byte padded memory.
  1139. //
  1140. // NOTE: due to the temporary memory pool idVecX cannot be used by multiple threads
  1141. //
  1142. //===============================================================
  1143. #define VECX_MAX_TEMP 1024
  1144. #define VECX_QUAD( x ) ( ( ( ( x ) + 3 ) & ~3 ) * sizeof( float ) )
  1145. #define VECX_CLEAREND() int s = size; while( s < ( ( s + 3) & ~3 ) ) { p[s++] = 0.0f; }
  1146. #define VECX_ALLOCA( n ) ( (float *) _alloca16( VECX_QUAD( n ) ) )
  1147. #define VECX_SIMD
  1148. class idVecX {
  1149. friend class idMatX;
  1150. public:
  1151. idVecX( void );
  1152. explicit idVecX( int length );
  1153. explicit idVecX( int length, float *data );
  1154. ~idVecX( void );
  1155. float operator[]( const int index ) const;
  1156. float & operator[]( const int index );
  1157. idVecX operator-() const;
  1158. idVecX & operator=( const idVecX &a );
  1159. idVecX operator*( const float a ) const;
  1160. idVecX operator/( const float a ) const;
  1161. float operator*( const idVecX &a ) const;
  1162. idVecX operator-( const idVecX &a ) const;
  1163. idVecX operator+( const idVecX &a ) const;
  1164. idVecX & operator*=( const float a );
  1165. idVecX & operator/=( const float a );
  1166. idVecX & operator+=( const idVecX &a );
  1167. idVecX & operator-=( const idVecX &a );
  1168. friend idVecX operator*( const float a, const idVecX b );
  1169. bool Compare( const idVecX &a ) const; // exact compare, no epsilon
  1170. bool Compare( const idVecX &a, const float epsilon ) const; // compare with epsilon
  1171. bool operator==( const idVecX &a ) const; // exact compare, no epsilon
  1172. bool operator!=( const idVecX &a ) const; // exact compare, no epsilon
  1173. void SetSize( int size );
  1174. void ChangeSize( int size, bool makeZero = false );
  1175. int GetSize( void ) const { return size; }
  1176. void SetData( int length, float *data );
  1177. void Zero( void );
  1178. void Zero( int length );
  1179. void Random( int seed, float l = 0.0f, float u = 1.0f );
  1180. void Random( int length, int seed, float l = 0.0f, float u = 1.0f );
  1181. void Negate( void );
  1182. void Clamp( float min, float max );
  1183. idVecX & SwapElements( int e1, int e2 );
  1184. float Length( void ) const;
  1185. float LengthSqr( void ) const;
  1186. idVecX Normalize( void ) const;
  1187. float NormalizeSelf( void );
  1188. int GetDimension( void ) const;
  1189. const idVec3 & SubVec3( int index ) const;
  1190. idVec3 & SubVec3( int index );
  1191. const idVec6 & SubVec6( int index ) const;
  1192. idVec6 & SubVec6( int index );
  1193. const float * ToFloatPtr( void ) const;
  1194. float * ToFloatPtr( void );
  1195. const char * ToString( int precision = 2 ) const;
  1196. private:
  1197. int size; // size of the vector
  1198. int alloced; // if -1 p points to data set with SetData
  1199. float * p; // memory the vector is stored
  1200. static float temp[VECX_MAX_TEMP+4]; // used to store intermediate results
  1201. static float * tempPtr; // pointer to 16 byte aligned temporary memory
  1202. static int tempIndex; // index into memory pool, wraps around
  1203. private:
  1204. void SetTempSize( int size );
  1205. };
  1206. ID_INLINE idVecX::idVecX( void ) {
  1207. size = alloced = 0;
  1208. p = NULL;
  1209. }
  1210. ID_INLINE idVecX::idVecX( int length ) {
  1211. size = alloced = 0;
  1212. p = NULL;
  1213. SetSize( length );
  1214. }
  1215. ID_INLINE idVecX::idVecX( int length, float *data ) {
  1216. size = alloced = 0;
  1217. p = NULL;
  1218. SetData( length, data );
  1219. }
  1220. ID_INLINE idVecX::~idVecX( void ) {
  1221. // if not temp memory
  1222. if ( p && ( p < idVecX::tempPtr || p >= idVecX::tempPtr + VECX_MAX_TEMP ) && alloced != -1 ) {
  1223. Mem_Free16( p );
  1224. }
  1225. }
  1226. ID_INLINE float idVecX::operator[]( const int index ) const {
  1227. assert( index >= 0 && index < size );
  1228. return p[index];
  1229. }
  1230. ID_INLINE float &idVecX::operator[]( const int index ) {
  1231. assert( index >= 0 && index < size );
  1232. return p[index];
  1233. }
  1234. ID_INLINE idVecX idVecX::operator-() const {
  1235. int i;
  1236. idVecX m;
  1237. m.SetTempSize( size );
  1238. for ( i = 0; i < size; i++ ) {
  1239. m.p[i] = -p[i];
  1240. }
  1241. return m;
  1242. }
  1243. ID_INLINE idVecX &idVecX::operator=( const idVecX &a ) {
  1244. SetSize( a.size );
  1245. #ifdef VECX_SIMD
  1246. SIMDProcessor->Copy16( p, a.p, a.size );
  1247. #else
  1248. memcpy( p, a.p, a.size * sizeof( float ) );
  1249. #endif
  1250. idVecX::tempIndex = 0;
  1251. return *this;
  1252. }
  1253. ID_INLINE idVecX idVecX::operator+( const idVecX &a ) const {
  1254. idVecX m;
  1255. assert( size == a.size );
  1256. m.SetTempSize( size );
  1257. #ifdef VECX_SIMD
  1258. SIMDProcessor->Add16( m.p, p, a.p, size );
  1259. #else
  1260. int i;
  1261. for ( i = 0; i < size; i++ ) {
  1262. m.p[i] = p[i] + a.p[i];
  1263. }
  1264. #endif
  1265. return m;
  1266. }
  1267. ID_INLINE idVecX idVecX::operator-( const idVecX &a ) const {
  1268. idVecX m;
  1269. assert( size == a.size );
  1270. m.SetTempSize( size );
  1271. #ifdef VECX_SIMD
  1272. SIMDProcessor->Sub16( m.p, p, a.p, size );
  1273. #else
  1274. int i;
  1275. for ( i = 0; i < size; i++ ) {
  1276. m.p[i] = p[i] - a.p[i];
  1277. }
  1278. #endif
  1279. return m;
  1280. }
  1281. ID_INLINE idVecX &idVecX::operator+=( const idVecX &a ) {
  1282. assert( size == a.size );
  1283. #ifdef VECX_SIMD
  1284. SIMDProcessor->AddAssign16( p, a.p, size );
  1285. #else
  1286. int i;
  1287. for ( i = 0; i < size; i++ ) {
  1288. p[i] += a.p[i];
  1289. }
  1290. #endif
  1291. idVecX::tempIndex = 0;
  1292. return *this;
  1293. }
  1294. ID_INLINE idVecX &idVecX::operator-=( const idVecX &a ) {
  1295. assert( size == a.size );
  1296. #ifdef VECX_SIMD
  1297. SIMDProcessor->SubAssign16( p, a.p, size );
  1298. #else
  1299. int i;
  1300. for ( i = 0; i < size; i++ ) {
  1301. p[i] -= a.p[i];
  1302. }
  1303. #endif
  1304. idVecX::tempIndex = 0;
  1305. return *this;
  1306. }
  1307. ID_INLINE idVecX idVecX::operator*( const float a ) const {
  1308. idVecX m;
  1309. m.SetTempSize( size );
  1310. #ifdef VECX_SIMD
  1311. SIMDProcessor->Mul16( m.p, p, a, size );
  1312. #else
  1313. int i;
  1314. for ( i = 0; i < size; i++ ) {
  1315. m.p[i] = p[i] * a;
  1316. }
  1317. #endif
  1318. return m;
  1319. }
  1320. ID_INLINE idVecX &idVecX::operator*=( const float a ) {
  1321. #ifdef VECX_SIMD
  1322. SIMDProcessor->MulAssign16( p, a, size );
  1323. #else
  1324. int i;
  1325. for ( i = 0; i < size; i++ ) {
  1326. p[i] *= a;
  1327. }
  1328. #endif
  1329. return *this;
  1330. }
  1331. ID_INLINE idVecX idVecX::operator/( const float a ) const {
  1332. assert( a != 0.0f );
  1333. return (*this) * ( 1.0f / a );
  1334. }
  1335. ID_INLINE idVecX &idVecX::operator/=( const float a ) {
  1336. assert( a != 0.0f );
  1337. (*this) *= ( 1.0f / a );
  1338. return *this;
  1339. }
  1340. ID_INLINE idVecX operator*( const float a, const idVecX b ) {
  1341. return b * a;
  1342. }
  1343. ID_INLINE float idVecX::operator*( const idVecX &a ) const {
  1344. int i;
  1345. float sum = 0.0f;
  1346. assert( size == a.size );
  1347. for ( i = 0; i < size; i++ ) {
  1348. sum += p[i] * a.p[i];
  1349. }
  1350. return sum;
  1351. }
  1352. ID_INLINE bool idVecX::Compare( const idVecX &a ) const {
  1353. int i;
  1354. assert( size == a.size );
  1355. for ( i = 0; i < size; i++ ) {
  1356. if ( p[i] != a.p[i] ) {
  1357. return false;
  1358. }
  1359. }
  1360. return true;
  1361. }
  1362. ID_INLINE bool idVecX::Compare( const idVecX &a, const float epsilon ) const {
  1363. int i;
  1364. assert( size == a.size );
  1365. for ( i = 0; i < size; i++ ) {
  1366. if ( idMath::Fabs( p[i] - a.p[i] ) > epsilon ) {
  1367. return false;
  1368. }
  1369. }
  1370. return true;
  1371. }
  1372. ID_INLINE bool idVecX::operator==( const idVecX &a ) const {
  1373. return Compare( a );
  1374. }
  1375. ID_INLINE bool idVecX::operator!=( const idVecX &a ) const {
  1376. return !Compare( a );
  1377. }
  1378. ID_INLINE void idVecX::SetSize( int newSize ) {
  1379. int alloc = ( newSize + 3 ) & ~3;
  1380. if ( alloc > alloced && alloced != -1 ) {
  1381. if ( p ) {
  1382. Mem_Free16( p );
  1383. }
  1384. p = (float *) Mem_Alloc16( alloc * sizeof( float ) );
  1385. alloced = alloc;
  1386. }
  1387. size = newSize;
  1388. VECX_CLEAREND();
  1389. }
  1390. ID_INLINE void idVecX::ChangeSize( int newSize, bool makeZero ) {
  1391. int alloc = ( newSize + 3 ) & ~3;
  1392. if ( alloc > alloced && alloced != -1 ) {
  1393. float *oldVec = p;
  1394. p = (float *) Mem_Alloc16( alloc * sizeof( float ) );
  1395. alloced = alloc;
  1396. if ( oldVec ) {
  1397. for ( int i = 0; i < size; i++ ) {
  1398. p[i] = oldVec[i];
  1399. }
  1400. Mem_Free16( oldVec );
  1401. }
  1402. if ( makeZero ) {
  1403. // zero any new elements
  1404. for ( int i = size; i < newSize; i++ ) {
  1405. p[i] = 0.0f;
  1406. }
  1407. }
  1408. }
  1409. size = newSize;
  1410. VECX_CLEAREND();
  1411. }
  1412. ID_INLINE void idVecX::SetTempSize( int newSize ) {
  1413. size = newSize;
  1414. alloced = ( newSize + 3 ) & ~3;
  1415. assert( alloced < VECX_MAX_TEMP );
  1416. if ( idVecX::tempIndex + alloced > VECX_MAX_TEMP ) {
  1417. idVecX::tempIndex = 0;
  1418. }
  1419. p = idVecX::tempPtr + idVecX::tempIndex;
  1420. idVecX::tempIndex += alloced;
  1421. VECX_CLEAREND();
  1422. }
  1423. ID_INLINE void idVecX::SetData( int length, float *data ) {
  1424. if ( p && ( p < idVecX::tempPtr || p >= idVecX::tempPtr + VECX_MAX_TEMP ) && alloced != -1 ) {
  1425. Mem_Free16( p );
  1426. }
  1427. assert( ( ( (int) data ) & 15 ) == 0 ); // data must be 16 byte aligned
  1428. p = data;
  1429. size = length;
  1430. alloced = -1;
  1431. VECX_CLEAREND();
  1432. }
  1433. ID_INLINE void idVecX::Zero( void ) {
  1434. #ifdef VECX_SIMD
  1435. SIMDProcessor->Zero16( p, size );
  1436. #else
  1437. memset( p, 0, size * sizeof( float ) );
  1438. #endif
  1439. }
  1440. ID_INLINE void idVecX::Zero( int length ) {
  1441. SetSize( length );
  1442. #ifdef VECX_SIMD
  1443. SIMDProcessor->Zero16( p, length );
  1444. #else
  1445. memset( p, 0, size * sizeof( float ) );
  1446. #endif
  1447. }
  1448. ID_INLINE void idVecX::Random( int seed, float l, float u ) {
  1449. int i;
  1450. float c;
  1451. idRandom rnd( seed );
  1452. c = u - l;
  1453. for ( i = 0; i < size; i++ ) {
  1454. p[i] = l + rnd.RandomFloat() * c;
  1455. }
  1456. }
  1457. ID_INLINE void idVecX::Random( int length, int seed, float l, float u ) {
  1458. int i;
  1459. float c;
  1460. idRandom rnd( seed );
  1461. SetSize( length );
  1462. c = u - l;
  1463. for ( i = 0; i < size; i++ ) {
  1464. p[i] = l + rnd.RandomFloat() * c;
  1465. }
  1466. }
  1467. ID_INLINE void idVecX::Negate( void ) {
  1468. #ifdef VECX_SIMD
  1469. SIMDProcessor->Negate16( p, size );
  1470. #else
  1471. int i;
  1472. for ( i = 0; i < size; i++ ) {
  1473. p[i] = -p[i];
  1474. }
  1475. #endif
  1476. }
  1477. ID_INLINE void idVecX::Clamp( float min, float max ) {
  1478. int i;
  1479. for ( i = 0; i < size; i++ ) {
  1480. if ( p[i] < min ) {
  1481. p[i] = min;
  1482. } else if ( p[i] > max ) {
  1483. p[i] = max;
  1484. }
  1485. }
  1486. }
  1487. ID_INLINE idVecX &idVecX::SwapElements( int e1, int e2 ) {
  1488. float tmp;
  1489. tmp = p[e1];
  1490. p[e1] = p[e2];
  1491. p[e2] = tmp;
  1492. return *this;
  1493. }
  1494. ID_INLINE float idVecX::Length( void ) const {
  1495. int i;
  1496. float sum = 0.0f;
  1497. for ( i = 0; i < size; i++ ) {
  1498. sum += p[i] * p[i];
  1499. }
  1500. return idMath::Sqrt( sum );
  1501. }
  1502. ID_INLINE float idVecX::LengthSqr( void ) const {
  1503. int i;
  1504. float sum = 0.0f;
  1505. for ( i = 0; i < size; i++ ) {
  1506. sum += p[i] * p[i];
  1507. }
  1508. return sum;
  1509. }
  1510. ID_INLINE idVecX idVecX::Normalize( void ) const {
  1511. int i;
  1512. idVecX m;
  1513. float invSqrt, sum = 0.0f;
  1514. m.SetTempSize( size );
  1515. for ( i = 0; i < size; i++ ) {
  1516. sum += p[i] * p[i];
  1517. }
  1518. invSqrt = idMath::InvSqrt( sum );
  1519. for ( i = 0; i < size; i++ ) {
  1520. m.p[i] = p[i] * invSqrt;
  1521. }
  1522. return m;
  1523. }
  1524. ID_INLINE float idVecX::NormalizeSelf( void ) {
  1525. float invSqrt, sum = 0.0f;
  1526. int i;
  1527. for ( i = 0; i < size; i++ ) {
  1528. sum += p[i] * p[i];
  1529. }
  1530. invSqrt = idMath::InvSqrt( sum );
  1531. for ( i = 0; i < size; i++ ) {
  1532. p[i] *= invSqrt;
  1533. }
  1534. return invSqrt * sum;
  1535. }
  1536. ID_INLINE int idVecX::GetDimension( void ) const {
  1537. return size;
  1538. }
  1539. ID_INLINE idVec3 &idVecX::SubVec3( int index ) {
  1540. assert( index >= 0 && index * 3 + 3 <= size );
  1541. return *reinterpret_cast<idVec3 *>(p + index * 3);
  1542. }
  1543. ID_INLINE const idVec3 &idVecX::SubVec3( int index ) const {
  1544. assert( index >= 0 && index * 3 + 3 <= size );
  1545. return *reinterpret_cast<const idVec3 *>(p + index * 3);
  1546. }
  1547. ID_INLINE idVec6 &idVecX::SubVec6( int index ) {
  1548. assert( index >= 0 && index * 6 + 6 <= size );
  1549. return *reinterpret_cast<idVec6 *>(p + index * 6);
  1550. }
  1551. ID_INLINE const idVec6 &idVecX::SubVec6( int index ) const {
  1552. assert( index >= 0 && index * 6 + 6 <= size );
  1553. return *reinterpret_cast<const idVec6 *>(p + index * 6);
  1554. }
  1555. ID_INLINE const float *idVecX::ToFloatPtr( void ) const {
  1556. return p;
  1557. }
  1558. ID_INLINE float *idVecX::ToFloatPtr( void ) {
  1559. return p;
  1560. }
  1561. //===============================================================
  1562. //
  1563. // idPolar3
  1564. //
  1565. //===============================================================
  1566. class idPolar3 {
  1567. public:
  1568. float radius, theta, phi;
  1569. idPolar3( void );
  1570. explicit idPolar3( const float radius, const float theta, const float phi );
  1571. void Set( const float radius, const float theta, const float phi );
  1572. float operator[]( const int index ) const;
  1573. float & operator[]( const int index );
  1574. idPolar3 operator-() const;
  1575. idPolar3 & operator=( const idPolar3 &a );
  1576. idVec3 ToVec3( void ) const;
  1577. };
  1578. ID_INLINE idPolar3::idPolar3( void ) {
  1579. }
  1580. ID_INLINE idPolar3::idPolar3( const float radius, const float theta, const float phi ) {
  1581. assert( radius > 0 );
  1582. this->radius = radius;
  1583. this->theta = theta;
  1584. this->phi = phi;
  1585. }
  1586. ID_INLINE void idPolar3::Set( const float radius, const float theta, const float phi ) {
  1587. assert( radius > 0 );
  1588. this->radius = radius;
  1589. this->theta = theta;
  1590. this->phi = phi;
  1591. }
  1592. ID_INLINE float idPolar3::operator[]( const int index ) const {
  1593. return ( &radius )[ index ];
  1594. }
  1595. ID_INLINE float &idPolar3::operator[]( const int index ) {
  1596. return ( &radius )[ index ];
  1597. }
  1598. ID_INLINE idPolar3 idPolar3::operator-() const {
  1599. return idPolar3( radius, -theta, -phi );
  1600. }
  1601. ID_INLINE idPolar3 &idPolar3::operator=( const idPolar3 &a ) {
  1602. radius = a.radius;
  1603. theta = a.theta;
  1604. phi = a.phi;
  1605. return *this;
  1606. }
  1607. ID_INLINE idVec3 idPolar3::ToVec3( void ) const {
  1608. float sp, cp, st, ct;
  1609. idMath::SinCos( phi, sp, cp );
  1610. idMath::SinCos( theta, st, ct );
  1611. return idVec3( cp * radius * ct, cp * radius * st, radius * sp );
  1612. }
  1613. /*
  1614. ===============================================================================
  1615. Old 3D vector macros, should no longer be used.
  1616. ===============================================================================
  1617. */
  1618. #define DotProduct( a, b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
  1619. #define VectorSubtract( a, b, c ) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
  1620. #define VectorAdd( a, b, c ) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
  1621. #define VectorScale( v, s, o ) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
  1622. #define VectorMA( v, s, b, o ) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
  1623. #define VectorCopy( a, b ) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
  1624. #endif /* !__MATH_VECTOR_H__ */