OVR_Math.h 126 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785
  1. /********************************************************************************//**
  2. \file OVR_Math.h
  3. \brief Implementation of 3D primitives such as vectors, matrices.
  4. \copyright Copyright 2014 Oculus VR, LLC All Rights reserved.
  5. *************************************************************************************/
  6. #ifndef OVR_Math_h
  7. #define OVR_Math_h
  8. // This file is intended to be independent of the rest of LibOVR and LibOVRKernel and thus
  9. // has no #include dependencies on either.
  10. #include <math.h>
  11. #include <stdint.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <float.h>
  16. #include "../OVR_CAPI.h" // Currently required due to a dependence on the ovrFovPort_ declaration.
  17. #if defined(_MSC_VER)
  18. #pragma warning(push)
  19. #pragma warning(disable: 4127) // conditional expression is constant
  20. #endif
  21. #if defined(_MSC_VER)
  22. #define OVRMath_sprintf sprintf_s
  23. #else
  24. #define OVRMath_sprintf snprintf
  25. #endif
  26. //-------------------------------------------------------------------------------------
  27. // ***** OVR_MATH_ASSERT
  28. //
  29. // Independent debug break implementation for OVR_Math.h.
  30. #if !defined(OVR_MATH_DEBUG_BREAK)
  31. #if defined(_DEBUG)
  32. #if defined(_MSC_VER)
  33. #define OVR_MATH_DEBUG_BREAK __debugbreak()
  34. #else
  35. #define OVR_MATH_DEBUG_BREAK __builtin_trap()
  36. #endif
  37. #else
  38. #define OVR_MATH_DEBUG_BREAK ((void)0)
  39. #endif
  40. #endif
  41. //-------------------------------------------------------------------------------------
  42. // ***** OVR_MATH_ASSERT
  43. //
  44. // Independent OVR_MATH_ASSERT implementation for OVR_Math.h.
  45. #if !defined(OVR_MATH_ASSERT)
  46. #if defined(_DEBUG)
  47. #define OVR_MATH_ASSERT(p) if (!(p)) { OVR_MATH_DEBUG_BREAK; }
  48. #else
  49. #define OVR_MATH_ASSERT(p) ((void)0)
  50. #endif
  51. #endif
  52. //-------------------------------------------------------------------------------------
  53. // ***** OVR_MATH_STATIC_ASSERT
  54. //
  55. // Independent OVR_MATH_ASSERT implementation for OVR_Math.h.
  56. #if !defined(OVR_MATH_STATIC_ASSERT)
  57. #if defined(__cplusplus) && ((defined(_MSC_VER) && (defined(_MSC_VER) >= 1600)) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L))
  58. #define OVR_MATH_STATIC_ASSERT static_assert
  59. #else
  60. #if !defined(OVR_SA_UNUSED)
  61. #if defined(__GNUC__) || defined(__clang__)
  62. #define OVR_SA_UNUSED __attribute__((unused))
  63. #else
  64. #define OVR_SA_UNUSED
  65. #endif
  66. #define OVR_SA_PASTE(a,b) a##b
  67. #define OVR_SA_HELP(a,b) OVR_SA_PASTE(a,b)
  68. #endif
  69. #define OVR_MATH_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED
  70. #endif
  71. #endif
  72. namespace OVR {
  73. template<class T>
  74. const T OVRMath_Min(const T a, const T b)
  75. { return (a < b) ? a : b; }
  76. template<class T>
  77. const T OVRMath_Max(const T a, const T b)
  78. { return (b < a) ? a : b; }
  79. template<class T>
  80. void OVRMath_Swap(T& a, T& b)
  81. { T temp(a); a = b; b = temp; }
  82. //-------------------------------------------------------------------------------------
  83. // ***** Constants for 3D world/axis definitions.
  84. // Definitions of axes for coordinate and rotation conversions.
  85. enum Axis
  86. {
  87. Axis_X = 0, Axis_Y = 1, Axis_Z = 2
  88. };
  89. // RotateDirection describes the rotation direction around an axis, interpreted as follows:
  90. // CW - Clockwise while looking "down" from positive axis towards the origin.
  91. // CCW - Counter-clockwise while looking from the positive axis towards the origin,
  92. // which is in the negative axis direction.
  93. // CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate
  94. // system defines Y up, X right, and Z back (pointing out from the screen). In this
  95. // system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane.
  96. enum RotateDirection
  97. {
  98. Rotate_CCW = 1,
  99. Rotate_CW = -1
  100. };
  101. // Constants for right handed and left handed coordinate systems
  102. enum HandedSystem
  103. {
  104. Handed_R = 1, Handed_L = -1
  105. };
  106. // AxisDirection describes which way the coordinate axis points. Used by WorldAxes.
  107. enum AxisDirection
  108. {
  109. Axis_Up = 2,
  110. Axis_Down = -2,
  111. Axis_Right = 1,
  112. Axis_Left = -1,
  113. Axis_In = 3,
  114. Axis_Out = -3
  115. };
  116. struct WorldAxes
  117. {
  118. AxisDirection XAxis, YAxis, ZAxis;
  119. WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z)
  120. : XAxis(x), YAxis(y), ZAxis(z)
  121. { OVR_MATH_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));}
  122. };
  123. } // namespace OVR
  124. //------------------------------------------------------------------------------------//
  125. // ***** C Compatibility Types
  126. // These declarations are used to support conversion between C types used in
  127. // LibOVR C interfaces and their C++ versions. As an example, they allow passing
  128. // Vector3f into a function that expects ovrVector3f.
  129. typedef struct ovrQuatf_ ovrQuatf;
  130. typedef struct ovrQuatd_ ovrQuatd;
  131. typedef struct ovrSizei_ ovrSizei;
  132. typedef struct ovrSizef_ ovrSizef;
  133. typedef struct ovrSized_ ovrSized;
  134. typedef struct ovrRecti_ ovrRecti;
  135. typedef struct ovrVector2i_ ovrVector2i;
  136. typedef struct ovrVector2f_ ovrVector2f;
  137. typedef struct ovrVector2d_ ovrVector2d;
  138. typedef struct ovrVector3f_ ovrVector3f;
  139. typedef struct ovrVector3d_ ovrVector3d;
  140. typedef struct ovrVector4f_ ovrVector4f;
  141. typedef struct ovrVector4d_ ovrVector4d;
  142. typedef struct ovrMatrix2f_ ovrMatrix2f;
  143. typedef struct ovrMatrix2d_ ovrMatrix2d;
  144. typedef struct ovrMatrix3f_ ovrMatrix3f;
  145. typedef struct ovrMatrix3d_ ovrMatrix3d;
  146. typedef struct ovrMatrix4f_ ovrMatrix4f;
  147. typedef struct ovrMatrix4d_ ovrMatrix4d;
  148. typedef struct ovrPosef_ ovrPosef;
  149. typedef struct ovrPosed_ ovrPosed;
  150. typedef struct ovrPoseStatef_ ovrPoseStatef;
  151. typedef struct ovrPoseStated_ ovrPoseStated;
  152. namespace OVR {
  153. // Forward-declare our templates.
  154. template<class T> class Quat;
  155. template<class T> class Size;
  156. template<class T> class Rect;
  157. template<class T> class Vector2;
  158. template<class T> class Vector3;
  159. template<class T> class Vector4;
  160. template<class T> class Matrix2;
  161. template<class T> class Matrix3;
  162. template<class T> class Matrix4;
  163. template<class T> class Pose;
  164. template<class T> class PoseState;
  165. // CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class.
  166. template<class C>
  167. struct CompatibleTypes
  168. {
  169. // Declaration here seems necessary for MSVC; specializations are
  170. // used instead.
  171. typedef struct {} Type;
  172. };
  173. // Specializations providing CompatibleTypes::Type value.
  174. template<> struct CompatibleTypes<Quat<float> > { typedef ovrQuatf Type; };
  175. template<> struct CompatibleTypes<Quat<double> > { typedef ovrQuatd Type; };
  176. template<> struct CompatibleTypes<Matrix2<float> > { typedef ovrMatrix2f Type; };
  177. template<> struct CompatibleTypes<Matrix2<double> > { typedef ovrMatrix2d Type; };
  178. template<> struct CompatibleTypes<Matrix3<float> > { typedef ovrMatrix3f Type; };
  179. template<> struct CompatibleTypes<Matrix3<double> > { typedef ovrMatrix3d Type; };
  180. template<> struct CompatibleTypes<Matrix4<float> > { typedef ovrMatrix4f Type; };
  181. template<> struct CompatibleTypes<Matrix4<double> > { typedef ovrMatrix4d Type; };
  182. template<> struct CompatibleTypes<Size<int> > { typedef ovrSizei Type; };
  183. template<> struct CompatibleTypes<Size<float> > { typedef ovrSizef Type; };
  184. template<> struct CompatibleTypes<Size<double> > { typedef ovrSized Type; };
  185. template<> struct CompatibleTypes<Rect<int> > { typedef ovrRecti Type; };
  186. template<> struct CompatibleTypes<Vector2<int> > { typedef ovrVector2i Type; };
  187. template<> struct CompatibleTypes<Vector2<float> > { typedef ovrVector2f Type; };
  188. template<> struct CompatibleTypes<Vector2<double> > { typedef ovrVector2d Type; };
  189. template<> struct CompatibleTypes<Vector3<float> > { typedef ovrVector3f Type; };
  190. template<> struct CompatibleTypes<Vector3<double> > { typedef ovrVector3d Type; };
  191. template<> struct CompatibleTypes<Vector4<float> > { typedef ovrVector4f Type; };
  192. template<> struct CompatibleTypes<Vector4<double> > { typedef ovrVector4d Type; };
  193. template<> struct CompatibleTypes<Pose<float> > { typedef ovrPosef Type; };
  194. template<> struct CompatibleTypes<Pose<double> > { typedef ovrPosed Type; };
  195. //------------------------------------------------------------------------------------//
  196. // ***** Math
  197. //
  198. // Math class contains constants and functions. This class is a template specialized
  199. // per type, with Math<float> and Math<double> being distinct.
  200. template<class T>
  201. class Math
  202. {
  203. public:
  204. // By default, support explicit conversion to float. This allows Vector2<int> to
  205. // compile, for example.
  206. typedef float OtherFloatType;
  207. static int Tolerance() { return 0; } // Default value so integer types compile
  208. };
  209. //------------------------------------------------------------------------------------//
  210. // ***** double constants
  211. #define MATH_DOUBLE_PI 3.14159265358979323846
  212. #define MATH_DOUBLE_TWOPI (2*MATH_DOUBLE_PI)
  213. #define MATH_DOUBLE_PIOVER2 (0.5*MATH_DOUBLE_PI)
  214. #define MATH_DOUBLE_PIOVER4 (0.25*MATH_DOUBLE_PI)
  215. #define MATH_FLOAT_MAXVALUE (FLT_MAX)
  216. #define MATH_DOUBLE_RADTODEGREEFACTOR (360.0 / MATH_DOUBLE_TWOPI)
  217. #define MATH_DOUBLE_DEGREETORADFACTOR (MATH_DOUBLE_TWOPI / 360.0)
  218. #define MATH_DOUBLE_E 2.71828182845904523536
  219. #define MATH_DOUBLE_LOG2E 1.44269504088896340736
  220. #define MATH_DOUBLE_LOG10E 0.434294481903251827651
  221. #define MATH_DOUBLE_LN2 0.693147180559945309417
  222. #define MATH_DOUBLE_LN10 2.30258509299404568402
  223. #define MATH_DOUBLE_SQRT2 1.41421356237309504880
  224. #define MATH_DOUBLE_SQRT1_2 0.707106781186547524401
  225. #define MATH_DOUBLE_TOLERANCE 1e-12 // a default number for value equality tolerance: about 4500*Epsilon;
  226. #define MATH_DOUBLE_SINGULARITYRADIUS 1e-12 // about 1-cos(.0001 degree), for gimbal lock numerical problems
  227. //------------------------------------------------------------------------------------//
  228. // ***** float constants
  229. #define MATH_FLOAT_PI float(MATH_DOUBLE_PI)
  230. #define MATH_FLOAT_TWOPI float(MATH_DOUBLE_TWOPI)
  231. #define MATH_FLOAT_PIOVER2 float(MATH_DOUBLE_PIOVER2)
  232. #define MATH_FLOAT_PIOVER4 float(MATH_DOUBLE_PIOVER4)
  233. #define MATH_FLOAT_RADTODEGREEFACTOR float(MATH_DOUBLE_RADTODEGREEFACTOR)
  234. #define MATH_FLOAT_DEGREETORADFACTOR float(MATH_DOUBLE_DEGREETORADFACTOR)
  235. #define MATH_FLOAT_E float(MATH_DOUBLE_E)
  236. #define MATH_FLOAT_LOG2E float(MATH_DOUBLE_LOG2E)
  237. #define MATH_FLOAT_LOG10E float(MATH_DOUBLE_LOG10E)
  238. #define MATH_FLOAT_LN2 float(MATH_DOUBLE_LN2)
  239. #define MATH_FLOAT_LN10 float(MATH_DOUBLE_LN10)
  240. #define MATH_FLOAT_SQRT2 float(MATH_DOUBLE_SQRT2)
  241. #define MATH_FLOAT_SQRT1_2 float(MATH_DOUBLE_SQRT1_2)
  242. #define MATH_FLOAT_TOLERANCE 1e-5f // a default number for value equality tolerance: 1e-5, about 84*EPSILON;
  243. #define MATH_FLOAT_SINGULARITYRADIUS 1e-7f // about 1-cos(.025 degree), for gimbal lock numerical problems
  244. // Single-precision Math constants class.
  245. template<>
  246. class Math<float>
  247. {
  248. public:
  249. typedef double OtherFloatType;
  250. static inline float Tolerance() { return MATH_FLOAT_TOLERANCE; }; // a default number for value equality tolerance
  251. static inline float SingularityRadius() { return MATH_FLOAT_SINGULARITYRADIUS; }; // for gimbal lock numerical problems
  252. };
  253. // Double-precision Math constants class
  254. template<>
  255. class Math<double>
  256. {
  257. public:
  258. typedef float OtherFloatType;
  259. static inline double Tolerance() { return MATH_DOUBLE_TOLERANCE; }; // a default number for value equality tolerance
  260. static inline double SingularityRadius() { return MATH_DOUBLE_SINGULARITYRADIUS; }; // for gimbal lock numerical problems
  261. };
  262. typedef Math<float> Mathf;
  263. typedef Math<double> Mathd;
  264. // Conversion functions between degrees and radians
  265. // (non-templated to ensure passing int arguments causes warning)
  266. inline float RadToDegree(float rad) { return rad * MATH_FLOAT_RADTODEGREEFACTOR; }
  267. inline double RadToDegree(double rad) { return rad * MATH_DOUBLE_RADTODEGREEFACTOR; }
  268. inline float DegreeToRad(float deg) { return deg * MATH_FLOAT_DEGREETORADFACTOR; }
  269. inline double DegreeToRad(double deg) { return deg * MATH_DOUBLE_DEGREETORADFACTOR; }
  270. // Square function
  271. template<class T>
  272. inline T Sqr(T x) { return x*x; }
  273. // Sign: returns 0 if x == 0, -1 if x < 0, and 1 if x > 0
  274. template<class T>
  275. inline T Sign(T x) { return (x != T(0)) ? (x < T(0) ? T(-1) : T(1)) : T(0); }
  276. // Numerically stable acos function
  277. inline float Acos(float x) { return (x > 1.0f) ? 0.0f : (x < -1.0f) ? MATH_FLOAT_PI : acosf(x); }
  278. inline double Acos(double x) { return (x > 1.0) ? 0.0 : (x < -1.0) ? MATH_DOUBLE_PI : acos(x); }
  279. // Numerically stable asin function
  280. inline float Asin(float x) { return (x > 1.0f) ? MATH_FLOAT_PIOVER2 : (x < -1.0f) ? -MATH_FLOAT_PIOVER2 : asinf(x); }
  281. inline double Asin(double x) { return (x > 1.0) ? MATH_DOUBLE_PIOVER2 : (x < -1.0) ? -MATH_DOUBLE_PIOVER2 : asin(x); }
  282. #if defined(_MSC_VER)
  283. inline int isnan(double x) { return ::_isnan(x); }
  284. #elif !defined(isnan) // Some libraries #define isnan.
  285. inline int isnan(double x) { return ::isnan(x); }
  286. #endif
  287. template<class T>
  288. class Quat;
  289. //-------------------------------------------------------------------------------------
  290. // ***** Vector2<>
  291. // Vector2f (Vector2d) represents a 2-dimensional vector or point in space,
  292. // consisting of coordinates x and y
  293. template<class T>
  294. class Vector2
  295. {
  296. public:
  297. typedef T ElementType;
  298. static const size_t ElementCount = 2;
  299. T x, y;
  300. Vector2() : x(0), y(0) { }
  301. Vector2(T x_, T y_) : x(x_), y(y_) { }
  302. explicit Vector2(T s) : x(s), y(s) { }
  303. explicit Vector2(const Vector2<typename Math<T>::OtherFloatType> &src)
  304. : x((T)src.x), y((T)src.y) { }
  305. static Vector2 Zero() { return Vector2(0, 0); }
  306. // C-interop support.
  307. typedef typename CompatibleTypes<Vector2<T> >::Type CompatibleType;
  308. Vector2(const CompatibleType& s) : x(s.x), y(s.y) { }
  309. operator const CompatibleType& () const
  310. {
  311. OVR_MATH_STATIC_ASSERT(sizeof(Vector2<T>) == sizeof(CompatibleType), "sizeof(Vector2<T>) failure");
  312. return reinterpret_cast<const CompatibleType&>(*this);
  313. }
  314. bool operator== (const Vector2& b) const { return x == b.x && y == b.y; }
  315. bool operator!= (const Vector2& b) const { return x != b.x || y != b.y; }
  316. Vector2 operator+ (const Vector2& b) const { return Vector2(x + b.x, y + b.y); }
  317. Vector2& operator+= (const Vector2& b) { x += b.x; y += b.y; return *this; }
  318. Vector2 operator- (const Vector2& b) const { return Vector2(x - b.x, y - b.y); }
  319. Vector2& operator-= (const Vector2& b) { x -= b.x; y -= b.y; return *this; }
  320. Vector2 operator- () const { return Vector2(-x, -y); }
  321. // Scalar multiplication/division scales vector.
  322. Vector2 operator* (T s) const { return Vector2(x*s, y*s); }
  323. Vector2& operator*= (T s) { x *= s; y *= s; return *this; }
  324. Vector2 operator/ (T s) const { T rcp = T(1)/s;
  325. return Vector2(x*rcp, y*rcp); }
  326. Vector2& operator/= (T s) { T rcp = T(1)/s;
  327. x *= rcp; y *= rcp;
  328. return *this; }
  329. static Vector2 Min(const Vector2& a, const Vector2& b) { return Vector2((a.x < b.x) ? a.x : b.x,
  330. (a.y < b.y) ? a.y : b.y); }
  331. static Vector2 Max(const Vector2& a, const Vector2& b) { return Vector2((a.x > b.x) ? a.x : b.x,
  332. (a.y > b.y) ? a.y : b.y); }
  333. Vector2 Clamped(T maxMag) const
  334. {
  335. T magSquared = LengthSq();
  336. if (magSquared <= Sqr(maxMag))
  337. return *this;
  338. else
  339. return *this * (maxMag / sqrt(magSquared));
  340. }
  341. // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
  342. bool IsEqual(const Vector2& b, T tolerance =Math<T>::Tolerance()) const
  343. {
  344. return (fabs(b.x-x) <= tolerance) &&
  345. (fabs(b.y-y) <= tolerance);
  346. }
  347. bool Compare(const Vector2& b, T tolerance = Math<T>::Tolerance()) const
  348. {
  349. return IsEqual(b, tolerance);
  350. }
  351. // Access element by index
  352. T& operator[] (int idx)
  353. {
  354. OVR_MATH_ASSERT(0 <= idx && idx < 2);
  355. return *(&x + idx);
  356. }
  357. const T& operator[] (int idx) const
  358. {
  359. OVR_MATH_ASSERT(0 <= idx && idx < 2);
  360. return *(&x + idx);
  361. }
  362. // Entry-wise product of two vectors
  363. Vector2 EntrywiseMultiply(const Vector2& b) const { return Vector2(x * b.x, y * b.y);}
  364. // Multiply and divide operators do entry-wise math. Used Dot() for dot product.
  365. Vector2 operator* (const Vector2& b) const { return Vector2(x * b.x, y * b.y); }
  366. Vector2 operator/ (const Vector2& b) const { return Vector2(x / b.x, y / b.y); }
  367. // Dot product
  368. // Used to calculate angle q between two vectors among other things,
  369. // as (A dot B) = |a||b|cos(q).
  370. T Dot(const Vector2& b) const { return x*b.x + y*b.y; }
  371. // Returns the angle from this vector to b, in radians.
  372. T Angle(const Vector2& b) const
  373. {
  374. T div = LengthSq()*b.LengthSq();
  375. OVR_MATH_ASSERT(div != T(0));
  376. T result = Acos((this->Dot(b))/sqrt(div));
  377. return result;
  378. }
  379. // Return Length of the vector squared.
  380. T LengthSq() const { return (x * x + y * y); }
  381. // Return vector length.
  382. T Length() const { return sqrt(LengthSq()); }
  383. // Returns squared distance between two points represented by vectors.
  384. T DistanceSq(const Vector2& b) const { return (*this - b).LengthSq(); }
  385. // Returns distance between two points represented by vectors.
  386. T Distance(const Vector2& b) const { return (*this - b).Length(); }
  387. // Determine if this a unit vector.
  388. bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
  389. // Normalize, convention vector length to 1.
  390. void Normalize()
  391. {
  392. T s = Length();
  393. if (s != T(0))
  394. s = T(1) / s;
  395. *this *= s;
  396. }
  397. // Returns normalized (unit) version of the vector without modifying itself.
  398. Vector2 Normalized() const
  399. {
  400. T s = Length();
  401. if (s != T(0))
  402. s = T(1) / s;
  403. return *this * s;
  404. }
  405. // Linearly interpolates from this vector to another.
  406. // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
  407. Vector2 Lerp(const Vector2& b, T f) const { return *this*(T(1) - f) + b*f; }
  408. // Projects this vector onto the argument; in other words,
  409. // A.Project(B) returns projection of vector A onto B.
  410. Vector2 ProjectTo(const Vector2& b) const
  411. {
  412. T l2 = b.LengthSq();
  413. OVR_MATH_ASSERT(l2 != T(0));
  414. return b * ( Dot(b) / l2 );
  415. }
  416. // returns true if vector b is clockwise from this vector
  417. bool IsClockwise(const Vector2& b) const
  418. {
  419. return (x * b.y - y * b.x) < 0;
  420. }
  421. };
  422. typedef Vector2<float> Vector2f;
  423. typedef Vector2<double> Vector2d;
  424. typedef Vector2<int> Vector2i;
  425. typedef Vector2<float> Point2f;
  426. typedef Vector2<double> Point2d;
  427. typedef Vector2<int> Point2i;
  428. //-------------------------------------------------------------------------------------
  429. // ***** Vector3<> - 3D vector of {x, y, z}
  430. //
  431. // Vector3f (Vector3d) represents a 3-dimensional vector or point in space,
  432. // consisting of coordinates x, y and z.
  433. template<class T>
  434. class Vector3
  435. {
  436. public:
  437. typedef T ElementType;
  438. static const size_t ElementCount = 3;
  439. T x, y, z;
  440. // FIXME: default initialization of a vector class can be very expensive in a full-blown
  441. // application. A few hundred thousand vector constructions is not unlikely and can add
  442. // up to milliseconds of time on processors like the PS3 PPU.
  443. Vector3() : x(0), y(0), z(0) { }
  444. Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { }
  445. explicit Vector3(T s) : x(s), y(s), z(s) { }
  446. explicit Vector3(const Vector3<typename Math<T>::OtherFloatType> &src)
  447. : x((T)src.x), y((T)src.y), z((T)src.z) { }
  448. static Vector3 Zero() { return Vector3(0, 0, 0); }
  449. // C-interop support.
  450. typedef typename CompatibleTypes<Vector3<T> >::Type CompatibleType;
  451. Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) { }
  452. operator const CompatibleType& () const
  453. {
  454. OVR_MATH_STATIC_ASSERT(sizeof(Vector3<T>) == sizeof(CompatibleType), "sizeof(Vector3<T>) failure");
  455. return reinterpret_cast<const CompatibleType&>(*this);
  456. }
  457. bool operator== (const Vector3& b) const { return x == b.x && y == b.y && z == b.z; }
  458. bool operator!= (const Vector3& b) const { return x != b.x || y != b.y || z != b.z; }
  459. Vector3 operator+ (const Vector3& b) const { return Vector3(x + b.x, y + b.y, z + b.z); }
  460. Vector3& operator+= (const Vector3& b) { x += b.x; y += b.y; z += b.z; return *this; }
  461. Vector3 operator- (const Vector3& b) const { return Vector3(x - b.x, y - b.y, z - b.z); }
  462. Vector3& operator-= (const Vector3& b) { x -= b.x; y -= b.y; z -= b.z; return *this; }
  463. Vector3 operator- () const { return Vector3(-x, -y, -z); }
  464. // Scalar multiplication/division scales vector.
  465. Vector3 operator* (T s) const { return Vector3(x*s, y*s, z*s); }
  466. Vector3& operator*= (T s) { x *= s; y *= s; z *= s; return *this; }
  467. Vector3 operator/ (T s) const { T rcp = T(1)/s;
  468. return Vector3(x*rcp, y*rcp, z*rcp); }
  469. Vector3& operator/= (T s) { T rcp = T(1)/s;
  470. x *= rcp; y *= rcp; z *= rcp;
  471. return *this; }
  472. static Vector3 Min(const Vector3& a, const Vector3& b)
  473. {
  474. return Vector3((a.x < b.x) ? a.x : b.x,
  475. (a.y < b.y) ? a.y : b.y,
  476. (a.z < b.z) ? a.z : b.z);
  477. }
  478. static Vector3 Max(const Vector3& a, const Vector3& b)
  479. {
  480. return Vector3((a.x > b.x) ? a.x : b.x,
  481. (a.y > b.y) ? a.y : b.y,
  482. (a.z > b.z) ? a.z : b.z);
  483. }
  484. Vector3 Clamped(T maxMag) const
  485. {
  486. T magSquared = LengthSq();
  487. if (magSquared <= Sqr(maxMag))
  488. return *this;
  489. else
  490. return *this * (maxMag / sqrt(magSquared));
  491. }
  492. // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
  493. bool IsEqual(const Vector3& b, T tolerance = Math<T>::Tolerance()) const
  494. {
  495. return (fabs(b.x-x) <= tolerance) &&
  496. (fabs(b.y-y) <= tolerance) &&
  497. (fabs(b.z-z) <= tolerance);
  498. }
  499. bool Compare(const Vector3& b, T tolerance = Math<T>::Tolerance()) const
  500. {
  501. return IsEqual(b, tolerance);
  502. }
  503. T& operator[] (int idx)
  504. {
  505. OVR_MATH_ASSERT(0 <= idx && idx < 3);
  506. return *(&x + idx);
  507. }
  508. const T& operator[] (int idx) const
  509. {
  510. OVR_MATH_ASSERT(0 <= idx && idx < 3);
  511. return *(&x + idx);
  512. }
  513. // Entrywise product of two vectors
  514. Vector3 EntrywiseMultiply(const Vector3& b) const { return Vector3(x * b.x,
  515. y * b.y,
  516. z * b.z);}
  517. // Multiply and divide operators do entry-wise math
  518. Vector3 operator* (const Vector3& b) const { return Vector3(x * b.x,
  519. y * b.y,
  520. z * b.z); }
  521. Vector3 operator/ (const Vector3& b) const { return Vector3(x / b.x,
  522. y / b.y,
  523. z / b.z); }
  524. // Dot product
  525. // Used to calculate angle q between two vectors among other things,
  526. // as (A dot B) = |a||b|cos(q).
  527. T Dot(const Vector3& b) const { return x*b.x + y*b.y + z*b.z; }
  528. // Compute cross product, which generates a normal vector.
  529. // Direction vector can be determined by right-hand rule: Pointing index finder in
  530. // direction a and middle finger in direction b, thumb will point in a.Cross(b).
  531. Vector3 Cross(const Vector3& b) const { return Vector3(y*b.z - z*b.y,
  532. z*b.x - x*b.z,
  533. x*b.y - y*b.x); }
  534. // Returns the angle from this vector to b, in radians.
  535. T Angle(const Vector3& b) const
  536. {
  537. T div = LengthSq()*b.LengthSq();
  538. OVR_MATH_ASSERT(div != T(0));
  539. T result = Acos((this->Dot(b))/sqrt(div));
  540. return result;
  541. }
  542. // Return Length of the vector squared.
  543. T LengthSq() const { return (x * x + y * y + z * z); }
  544. // Return vector length.
  545. T Length() const { return sqrt(LengthSq()); }
  546. // Returns squared distance between two points represented by vectors.
  547. T DistanceSq(Vector3 const& b) const { return (*this - b).LengthSq(); }
  548. // Returns distance between two points represented by vectors.
  549. T Distance(Vector3 const& b) const { return (*this - b).Length(); }
  550. bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
  551. // Normalize, convention vector length to 1.
  552. void Normalize()
  553. {
  554. T s = Length();
  555. if (s != T(0))
  556. s = T(1) / s;
  557. *this *= s;
  558. }
  559. // Returns normalized (unit) version of the vector without modifying itself.
  560. Vector3 Normalized() const
  561. {
  562. T s = Length();
  563. if (s != T(0))
  564. s = T(1) / s;
  565. return *this * s;
  566. }
  567. // Linearly interpolates from this vector to another.
  568. // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
  569. Vector3 Lerp(const Vector3& b, T f) const { return *this*(T(1) - f) + b*f; }
  570. // Projects this vector onto the argument; in other words,
  571. // A.Project(B) returns projection of vector A onto B.
  572. Vector3 ProjectTo(const Vector3& b) const
  573. {
  574. T l2 = b.LengthSq();
  575. OVR_MATH_ASSERT(l2 != T(0));
  576. return b * ( Dot(b) / l2 );
  577. }
  578. // Projects this vector onto a plane defined by a normal vector
  579. Vector3 ProjectToPlane(const Vector3& normal) const { return *this - this->ProjectTo(normal); }
  580. };
  581. typedef Vector3<float> Vector3f;
  582. typedef Vector3<double> Vector3d;
  583. typedef Vector3<int32_t> Vector3i;
  584. OVR_MATH_STATIC_ASSERT((sizeof(Vector3f) == 3*sizeof(float)), "sizeof(Vector3f) failure");
  585. OVR_MATH_STATIC_ASSERT((sizeof(Vector3d) == 3*sizeof(double)), "sizeof(Vector3d) failure");
  586. OVR_MATH_STATIC_ASSERT((sizeof(Vector3i) == 3*sizeof(int32_t)), "sizeof(Vector3i) failure");
  587. typedef Vector3<float> Point3f;
  588. typedef Vector3<double> Point3d;
  589. typedef Vector3<int32_t> Point3i;
  590. //-------------------------------------------------------------------------------------
  591. // ***** Vector4<> - 4D vector of {x, y, z, w}
  592. //
  593. // Vector4f (Vector4d) represents a 3-dimensional vector or point in space,
  594. // consisting of coordinates x, y, z and w.
  595. template<class T>
  596. class Vector4
  597. {
  598. public:
  599. typedef T ElementType;
  600. static const size_t ElementCount = 4;
  601. T x, y, z, w;
  602. // FIXME: default initialization of a vector class can be very expensive in a full-blown
  603. // application. A few hundred thousand vector constructions is not unlikely and can add
  604. // up to milliseconds of time on processors like the PS3 PPU.
  605. Vector4() : x(0), y(0), z(0), w(0) { }
  606. Vector4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { }
  607. explicit Vector4(T s) : x(s), y(s), z(s), w(s) { }
  608. explicit Vector4(const Vector3<T>& v, const T w_=T(1)) : x(v.x), y(v.y), z(v.z), w(w_) { }
  609. explicit Vector4(const Vector4<typename Math<T>::OtherFloatType> &src)
  610. : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { }
  611. static Vector4 Zero() { return Vector4(0, 0, 0, 0); }
  612. // C-interop support.
  613. typedef typename CompatibleTypes< Vector4<T> >::Type CompatibleType;
  614. Vector4(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { }
  615. operator const CompatibleType& () const
  616. {
  617. OVR_MATH_STATIC_ASSERT(sizeof(Vector4<T>) == sizeof(CompatibleType), "sizeof(Vector4<T>) failure");
  618. return reinterpret_cast<const CompatibleType&>(*this);
  619. }
  620. Vector4& operator= (const Vector3<T>& other) { x=other.x; y=other.y; z=other.z; w=1; return *this; }
  621. bool operator== (const Vector4& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; }
  622. bool operator!= (const Vector4& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; }
  623. Vector4 operator+ (const Vector4& b) const { return Vector4(x + b.x, y + b.y, z + b.z, w + b.w); }
  624. Vector4& operator+= (const Vector4& b) { x += b.x; y += b.y; z += b.z; w += b.w; return *this; }
  625. Vector4 operator- (const Vector4& b) const { return Vector4(x - b.x, y - b.y, z - b.z, w - b.w); }
  626. Vector4& operator-= (const Vector4& b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; return *this; }
  627. Vector4 operator- () const { return Vector4(-x, -y, -z, -w); }
  628. // Scalar multiplication/division scales vector.
  629. Vector4 operator* (T s) const { return Vector4(x*s, y*s, z*s, w*s); }
  630. Vector4& operator*= (T s) { x *= s; y *= s; z *= s; w *= s;return *this; }
  631. Vector4 operator/ (T s) const { T rcp = T(1)/s;
  632. return Vector4(x*rcp, y*rcp, z*rcp, w*rcp); }
  633. Vector4& operator/= (T s) { T rcp = T(1)/s;
  634. x *= rcp; y *= rcp; z *= rcp; w *= rcp;
  635. return *this; }
  636. static Vector4 Min(const Vector4& a, const Vector4& b)
  637. {
  638. return Vector4((a.x < b.x) ? a.x : b.x,
  639. (a.y < b.y) ? a.y : b.y,
  640. (a.z < b.z) ? a.z : b.z,
  641. (a.w < b.w) ? a.w : b.w);
  642. }
  643. static Vector4 Max(const Vector4& a, const Vector4& b)
  644. {
  645. return Vector4((a.x > b.x) ? a.x : b.x,
  646. (a.y > b.y) ? a.y : b.y,
  647. (a.z > b.z) ? a.z : b.z,
  648. (a.w > b.w) ? a.w : b.w);
  649. }
  650. Vector4 Clamped(T maxMag) const
  651. {
  652. T magSquared = LengthSq();
  653. if (magSquared <= Sqr(maxMag))
  654. return *this;
  655. else
  656. return *this * (maxMag / sqrt(magSquared));
  657. }
  658. // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
  659. bool IsEqual(const Vector4& b, T tolerance = Math<T>::Tolerance()) const
  660. {
  661. return (fabs(b.x-x) <= tolerance) &&
  662. (fabs(b.y-y) <= tolerance) &&
  663. (fabs(b.z-z) <= tolerance) &&
  664. (fabs(b.w-w) <= tolerance);
  665. }
  666. bool Compare(const Vector4& b, T tolerance = Math<T>::Tolerance()) const
  667. {
  668. return IsEqual(b, tolerance);
  669. }
  670. T& operator[] (int idx)
  671. {
  672. OVR_MATH_ASSERT(0 <= idx && idx < 4);
  673. return *(&x + idx);
  674. }
  675. const T& operator[] (int idx) const
  676. {
  677. OVR_MATH_ASSERT(0 <= idx && idx < 4);
  678. return *(&x + idx);
  679. }
  680. // Entry wise product of two vectors
  681. Vector4 EntrywiseMultiply(const Vector4& b) const { return Vector4(x * b.x,
  682. y * b.y,
  683. z * b.z,
  684. w * b.w);}
  685. // Multiply and divide operators do entry-wise math
  686. Vector4 operator* (const Vector4& b) const { return Vector4(x * b.x,
  687. y * b.y,
  688. z * b.z,
  689. w * b.w); }
  690. Vector4 operator/ (const Vector4& b) const { return Vector4(x / b.x,
  691. y / b.y,
  692. z / b.z,
  693. w / b.w); }
  694. // Dot product
  695. T Dot(const Vector4& b) const { return x*b.x + y*b.y + z*b.z + w*b.w; }
  696. // Return Length of the vector squared.
  697. T LengthSq() const { return (x * x + y * y + z * z + w * w); }
  698. // Return vector length.
  699. T Length() const { return sqrt(LengthSq()); }
  700. bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
  701. // Normalize, convention vector length to 1.
  702. void Normalize()
  703. {
  704. T s = Length();
  705. if (s != T(0))
  706. s = T(1) / s;
  707. *this *= s;
  708. }
  709. // Returns normalized (unit) version of the vector without modifying itself.
  710. Vector4 Normalized() const
  711. {
  712. T s = Length();
  713. if (s != T(0))
  714. s = T(1) / s;
  715. return *this * s;
  716. }
  717. // Linearly interpolates from this vector to another.
  718. // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
  719. Vector4 Lerp(const Vector4& b, T f) const { return *this*(T(1) - f) + b*f; }
  720. };
  721. typedef Vector4<float> Vector4f;
  722. typedef Vector4<double> Vector4d;
  723. typedef Vector4<int> Vector4i;
  724. //-------------------------------------------------------------------------------------
  725. // ***** Bounds3
  726. // Bounds class used to describe a 3D axis aligned bounding box.
  727. template<class T>
  728. class Bounds3
  729. {
  730. public:
  731. Vector3<T> b[2];
  732. Bounds3()
  733. {
  734. }
  735. Bounds3( const Vector3<T> & mins, const Vector3<T> & maxs )
  736. {
  737. b[0] = mins;
  738. b[1] = maxs;
  739. }
  740. void Clear()
  741. {
  742. b[0].x = b[0].y = b[0].z = Math<T>::MaxValue;
  743. b[1].x = b[1].y = b[1].z = -Math<T>::MaxValue;
  744. }
  745. void AddPoint( const Vector3<T> & v )
  746. {
  747. b[0].x = (b[0].x < v.x ? b[0].x : v.x);
  748. b[0].y = (b[0].y < v.y ? b[0].y : v.y);
  749. b[0].z = (b[0].z < v.z ? b[0].z : v.z);
  750. b[1].x = (v.x < b[1].x ? b[1].x : v.x);
  751. b[1].y = (v.y < b[1].y ? b[1].y : v.y);
  752. b[1].z = (v.z < b[1].z ? b[1].z : v.z);
  753. }
  754. const Vector3<T> & GetMins() const { return b[0]; }
  755. const Vector3<T> & GetMaxs() const { return b[1]; }
  756. Vector3<T> & GetMins() { return b[0]; }
  757. Vector3<T> & GetMaxs() { return b[1]; }
  758. };
  759. typedef Bounds3<float> Bounds3f;
  760. typedef Bounds3<double> Bounds3d;
  761. //-------------------------------------------------------------------------------------
  762. // ***** Size
  763. // Size class represents 2D size with Width, Height components.
  764. // Used to describe distentions of render targets, etc.
  765. template<class T>
  766. class Size
  767. {
  768. public:
  769. T w, h;
  770. Size() : w(0), h(0) { }
  771. Size(T w_, T h_) : w(w_), h(h_) { }
  772. explicit Size(T s) : w(s), h(s) { }
  773. explicit Size(const Size<typename Math<T>::OtherFloatType> &src)
  774. : w((T)src.w), h((T)src.h) { }
  775. // C-interop support.
  776. typedef typename CompatibleTypes<Size<T> >::Type CompatibleType;
  777. Size(const CompatibleType& s) : w(s.w), h(s.h) { }
  778. operator const CompatibleType& () const
  779. {
  780. OVR_MATH_STATIC_ASSERT(sizeof(Size<T>) == sizeof(CompatibleType), "sizeof(Size<T>) failure");
  781. return reinterpret_cast<const CompatibleType&>(*this);
  782. }
  783. bool operator== (const Size& b) const { return w == b.w && h == b.h; }
  784. bool operator!= (const Size& b) const { return w != b.w || h != b.h; }
  785. Size operator+ (const Size& b) const { return Size(w + b.w, h + b.h); }
  786. Size& operator+= (const Size& b) { w += b.w; h += b.h; return *this; }
  787. Size operator- (const Size& b) const { return Size(w - b.w, h - b.h); }
  788. Size& operator-= (const Size& b) { w -= b.w; h -= b.h; return *this; }
  789. Size operator- () const { return Size(-w, -h); }
  790. Size operator* (const Size& b) const { return Size(w * b.w, h * b.h); }
  791. Size& operator*= (const Size& b) { w *= b.w; h *= b.h; return *this; }
  792. Size operator/ (const Size& b) const { return Size(w / b.w, h / b.h); }
  793. Size& operator/= (const Size& b) { w /= b.w; h /= b.h; return *this; }
  794. // Scalar multiplication/division scales both components.
  795. Size operator* (T s) const { return Size(w*s, h*s); }
  796. Size& operator*= (T s) { w *= s; h *= s; return *this; }
  797. Size operator/ (T s) const { return Size(w/s, h/s); }
  798. Size& operator/= (T s) { w /= s; h /= s; return *this; }
  799. static Size Min(const Size& a, const Size& b) { return Size((a.w < b.w) ? a.w : b.w,
  800. (a.h < b.h) ? a.h : b.h); }
  801. static Size Max(const Size& a, const Size& b) { return Size((a.w > b.w) ? a.w : b.w,
  802. (a.h > b.h) ? a.h : b.h); }
  803. T Area() const { return w * h; }
  804. inline Vector2<T> ToVector() const { return Vector2<T>(w, h); }
  805. };
  806. typedef Size<int> Sizei;
  807. typedef Size<unsigned> Sizeu;
  808. typedef Size<float> Sizef;
  809. typedef Size<double> Sized;
  810. //-----------------------------------------------------------------------------------
  811. // ***** Rect
  812. // Rect describes a rectangular area for rendering, that includes position and size.
  813. template<class T>
  814. class Rect
  815. {
  816. public:
  817. T x, y;
  818. T w, h;
  819. Rect() { }
  820. Rect(T x1, T y1, T w1, T h1) : x(x1), y(y1), w(w1), h(h1) { }
  821. Rect(const Vector2<T>& pos, const Size<T>& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) { }
  822. Rect(const Size<T>& sz) : x(0), y(0), w(sz.w), h(sz.h) { }
  823. // C-interop support.
  824. typedef typename CompatibleTypes<Rect<T> >::Type CompatibleType;
  825. Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) { }
  826. operator const CompatibleType& () const
  827. {
  828. OVR_MATH_STATIC_ASSERT(sizeof(Rect<T>) == sizeof(CompatibleType), "sizeof(Rect<T>) failure");
  829. return reinterpret_cast<const CompatibleType&>(*this);
  830. }
  831. Vector2<T> GetPos() const { return Vector2<T>(x, y); }
  832. Size<T> GetSize() const { return Size<T>(w, h); }
  833. void SetPos(const Vector2<T>& pos) { x = pos.x; y = pos.y; }
  834. void SetSize(const Size<T>& sz) { w = sz.w; h = sz.h; }
  835. bool operator == (const Rect& vp) const
  836. { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
  837. bool operator != (const Rect& vp) const
  838. { return !operator == (vp); }
  839. };
  840. typedef Rect<int> Recti;
  841. //-------------------------------------------------------------------------------------//
  842. // ***** Quat
  843. //
  844. // Quatf represents a quaternion class used for rotations.
  845. //
  846. // Quaternion multiplications are done in right-to-left order, to match the
  847. // behavior of matrices.
  848. template<class T>
  849. class Quat
  850. {
  851. public:
  852. typedef T ElementType;
  853. static const size_t ElementCount = 4;
  854. // x,y,z = axis*sin(angle), w = cos(angle)
  855. T x, y, z, w;
  856. Quat() : x(0), y(0), z(0), w(1) { }
  857. Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { }
  858. explicit Quat(const Quat<typename Math<T>::OtherFloatType> &src)
  859. : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w)
  860. {
  861. // NOTE: Converting a normalized Quat<float> to Quat<double>
  862. // will generally result in an un-normalized quaternion.
  863. // But we don't normalize here in case the quaternion
  864. // being converted is not a normalized rotation quaternion.
  865. }
  866. typedef typename CompatibleTypes<Quat<T> >::Type CompatibleType;
  867. // C-interop support.
  868. Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { }
  869. operator CompatibleType () const
  870. {
  871. CompatibleType result;
  872. result.x = x;
  873. result.y = y;
  874. result.z = z;
  875. result.w = w;
  876. return result;
  877. }
  878. // Constructs quaternion for rotation around the axis by an angle.
  879. Quat(const Vector3<T>& axis, T angle)
  880. {
  881. // Make sure we don't divide by zero.
  882. if (axis.LengthSq() == T(0))
  883. {
  884. // Assert if the axis is zero, but the angle isn't
  885. OVR_MATH_ASSERT(angle == T(0));
  886. x = y = z = T(0); w = T(1);
  887. return;
  888. }
  889. Vector3<T> unitAxis = axis.Normalized();
  890. T sinHalfAngle = sin(angle * T(0.5));
  891. w = cos(angle * T(0.5));
  892. x = unitAxis.x * sinHalfAngle;
  893. y = unitAxis.y * sinHalfAngle;
  894. z = unitAxis.z * sinHalfAngle;
  895. }
  896. // Constructs quaternion for rotation around one of the coordinate axis by an angle.
  897. Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R)
  898. {
  899. T sinHalfAngle = s * d *sin(angle * T(0.5));
  900. T v[3];
  901. v[0] = v[1] = v[2] = T(0);
  902. v[A] = sinHalfAngle;
  903. w = cos(angle * T(0.5));
  904. x = v[0];
  905. y = v[1];
  906. z = v[2];
  907. }
  908. Quat operator-() { return Quat(-x, -y, -z, -w); } // unary minus
  909. static Quat Identity() { return Quat(0, 0, 0, 1); }
  910. // Compute axis and angle from quaternion
  911. void GetAxisAngle(Vector3<T>* axis, T* angle) const
  912. {
  913. if ( x*x + y*y + z*z > Math<T>::Tolerance() * Math<T>::Tolerance() ) {
  914. *axis = Vector3<T>(x, y, z).Normalized();
  915. *angle = 2 * Acos(w);
  916. if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary
  917. {
  918. *angle = ((T)MATH_DOUBLE_TWOPI) - *angle;
  919. *axis = *axis * (-1);
  920. }
  921. }
  922. else
  923. {
  924. *axis = Vector3<T>(1, 0, 0);
  925. *angle= T(0);
  926. }
  927. }
  928. // Convert a quaternion to a rotation vector, also known as
  929. // Rodrigues vector, AxisAngle vector, SORA vector, exponential map.
  930. // A rotation vector describes a rotation about an axis:
  931. // the axis of rotation is the vector normalized,
  932. // the angle of rotation is the magnitude of the vector.
  933. Vector3<T> ToRotationVector() const
  934. {
  935. OVR_MATH_ASSERT(IsNormalized() || LengthSq() == 0);
  936. T s = T(0);
  937. T sinHalfAngle = sqrt(x*x + y*y + z*z);
  938. if (sinHalfAngle > T(0))
  939. {
  940. T cosHalfAngle = w;
  941. T halfAngle = atan2(sinHalfAngle, cosHalfAngle);
  942. // Ensure minimum rotation magnitude
  943. if (cosHalfAngle < 0)
  944. halfAngle -= T(MATH_DOUBLE_PI);
  945. s = T(2) * halfAngle / sinHalfAngle;
  946. }
  947. return Vector3<T>(x*s, y*s, z*s);
  948. }
  949. // Faster version of the above, optimized for use with small rotations, where rotation angle ~= sin(angle)
  950. inline OVR::Vector3<T> FastToRotationVector() const
  951. {
  952. OVR_MATH_ASSERT(IsNormalized());
  953. T s;
  954. T sinHalfSquared = x*x + y*y + z*z;
  955. if (sinHalfSquared < T(.0037)) // =~ sin(7/2 degrees)^2
  956. {
  957. // Max rotation magnitude error is about .062% at 7 degrees rotation, or about .0043 degrees
  958. s = T(2) * Sign(w);
  959. }
  960. else
  961. {
  962. T sinHalfAngle = sqrt(sinHalfSquared);
  963. T cosHalfAngle = w;
  964. T halfAngle = atan2(sinHalfAngle, cosHalfAngle);
  965. // Ensure minimum rotation magnitude
  966. if (cosHalfAngle < 0)
  967. halfAngle -= T(MATH_DOUBLE_PI);
  968. s = T(2) * halfAngle / sinHalfAngle;
  969. }
  970. return Vector3<T>(x*s, y*s, z*s);
  971. }
  972. // Given a rotation vector of form unitRotationAxis * angle,
  973. // returns the equivalent quaternion (unitRotationAxis * sin(angle), cos(Angle)).
  974. static Quat FromRotationVector(const Vector3<T>& v)
  975. {
  976. T angleSquared = v.LengthSq();
  977. T s = T(0);
  978. T c = T(1);
  979. if (angleSquared > T(0))
  980. {
  981. T angle = sqrt(angleSquared);
  982. s = sin(angle * T(0.5)) / angle; // normalize
  983. c = cos(angle * T(0.5));
  984. }
  985. return Quat(s*v.x, s*v.y, s*v.z, c);
  986. }
  987. // Faster version of above, optimized for use with small rotation magnitudes, where rotation angle =~ sin(angle).
  988. // If normalize is false, small-angle quaternions are returned un-normalized.
  989. inline static Quat FastFromRotationVector(const OVR::Vector3<T>& v, bool normalize = true)
  990. {
  991. T s, c;
  992. T angleSquared = v.LengthSq();
  993. if (angleSquared < T(0.0076)) // =~ (5 degrees*pi/180)^2
  994. {
  995. s = T(0.5);
  996. c = T(1.0);
  997. // Max rotation magnitude error (after normalization) is about .064% at 5 degrees rotation, or .0032 degrees
  998. if (normalize && angleSquared > 0)
  999. {
  1000. // sin(angle/2)^2 ~= (angle/2)^2 and cos(angle/2)^2 ~= 1
  1001. T invLen = T(1) / sqrt(angleSquared * T(0.25) + T(1)); // normalize
  1002. s = s * invLen;
  1003. c = c * invLen;
  1004. }
  1005. }
  1006. else
  1007. {
  1008. T angle = sqrt(angleSquared);
  1009. s = sin(angle * T(0.5)) / angle;
  1010. c = cos(angle * T(0.5));
  1011. }
  1012. return Quat(s*v.x, s*v.y, s*v.z, c);
  1013. }
  1014. // Constructs the quaternion from a rotation matrix
  1015. explicit Quat(const Matrix4<T>& m)
  1016. {
  1017. T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
  1018. // In almost all cases, the first part is executed.
  1019. // However, if the trace is not positive, the other
  1020. // cases arise.
  1021. if (trace > T(0))
  1022. {
  1023. T s = sqrt(trace + T(1)) * T(2); // s=4*qw
  1024. w = T(0.25) * s;
  1025. x = (m.M[2][1] - m.M[1][2]) / s;
  1026. y = (m.M[0][2] - m.M[2][0]) / s;
  1027. z = (m.M[1][0] - m.M[0][1]) / s;
  1028. }
  1029. else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
  1030. {
  1031. T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
  1032. w = (m.M[2][1] - m.M[1][2]) / s;
  1033. x = T(0.25) * s;
  1034. y = (m.M[0][1] + m.M[1][0]) / s;
  1035. z = (m.M[2][0] + m.M[0][2]) / s;
  1036. }
  1037. else if (m.M[1][1] > m.M[2][2])
  1038. {
  1039. T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
  1040. w = (m.M[0][2] - m.M[2][0]) / s;
  1041. x = (m.M[0][1] + m.M[1][0]) / s;
  1042. y = T(0.25) * s;
  1043. z = (m.M[1][2] + m.M[2][1]) / s;
  1044. }
  1045. else
  1046. {
  1047. T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
  1048. w = (m.M[1][0] - m.M[0][1]) / s;
  1049. x = (m.M[0][2] + m.M[2][0]) / s;
  1050. y = (m.M[1][2] + m.M[2][1]) / s;
  1051. z = T(0.25) * s;
  1052. }
  1053. OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal
  1054. }
  1055. // Constructs the quaternion from a rotation matrix
  1056. explicit Quat(const Matrix3<T>& m)
  1057. {
  1058. T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
  1059. // In almost all cases, the first part is executed.
  1060. // However, if the trace is not positive, the other
  1061. // cases arise.
  1062. if (trace > T(0))
  1063. {
  1064. T s = sqrt(trace + T(1)) * T(2); // s=4*qw
  1065. w = T(0.25) * s;
  1066. x = (m.M[2][1] - m.M[1][2]) / s;
  1067. y = (m.M[0][2] - m.M[2][0]) / s;
  1068. z = (m.M[1][0] - m.M[0][1]) / s;
  1069. }
  1070. else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
  1071. {
  1072. T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
  1073. w = (m.M[2][1] - m.M[1][2]) / s;
  1074. x = T(0.25) * s;
  1075. y = (m.M[0][1] + m.M[1][0]) / s;
  1076. z = (m.M[2][0] + m.M[0][2]) / s;
  1077. }
  1078. else if (m.M[1][1] > m.M[2][2])
  1079. {
  1080. T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
  1081. w = (m.M[0][2] - m.M[2][0]) / s;
  1082. x = (m.M[0][1] + m.M[1][0]) / s;
  1083. y = T(0.25) * s;
  1084. z = (m.M[1][2] + m.M[2][1]) / s;
  1085. }
  1086. else
  1087. {
  1088. T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
  1089. w = (m.M[1][0] - m.M[0][1]) / s;
  1090. x = (m.M[0][2] + m.M[2][0]) / s;
  1091. y = (m.M[1][2] + m.M[2][1]) / s;
  1092. z = T(0.25) * s;
  1093. }
  1094. OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal
  1095. }
  1096. bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; }
  1097. bool operator!= (const Quat& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; }
  1098. Quat operator+ (const Quat& b) const { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
  1099. Quat& operator+= (const Quat& b) { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
  1100. Quat operator- (const Quat& b) const { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
  1101. Quat& operator-= (const Quat& b) { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
  1102. Quat operator* (T s) const { return Quat(x * s, y * s, z * s, w * s); }
  1103. Quat& operator*= (T s) { w *= s; x *= s; y *= s; z *= s; return *this; }
  1104. Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
  1105. Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
  1106. // Compare two quats for equality within tolerance. Returns true if quats match withing tolerance.
  1107. bool IsEqual(const Quat& b, T tolerance = Math<T>::Tolerance()) const
  1108. {
  1109. return Abs(Dot(b)) >= T(1) - tolerance;
  1110. }
  1111. static T Abs(const T v) { return (v >= 0) ? v : -v; }
  1112. // Get Imaginary part vector
  1113. Vector3<T> Imag() const { return Vector3<T>(x,y,z); }
  1114. // Get quaternion length.
  1115. T Length() const { return sqrt(LengthSq()); }
  1116. // Get quaternion length squared.
  1117. T LengthSq() const { return (x * x + y * y + z * z + w * w); }
  1118. // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
  1119. T Distance(const Quat& q) const
  1120. {
  1121. T d1 = (*this - q).Length();
  1122. T d2 = (*this + q).Length(); // Antipodal point check
  1123. return (d1 < d2) ? d1 : d2;
  1124. }
  1125. T DistanceSq(const Quat& q) const
  1126. {
  1127. T d1 = (*this - q).LengthSq();
  1128. T d2 = (*this + q).LengthSq(); // Antipodal point check
  1129. return (d1 < d2) ? d1 : d2;
  1130. }
  1131. T Dot(const Quat& q) const
  1132. {
  1133. return x * q.x + y * q.y + z * q.z + w * q.w;
  1134. }
  1135. // Angle between two quaternions in radians
  1136. T Angle(const Quat& q) const
  1137. {
  1138. return T(2) * Acos(Abs(Dot(q)));
  1139. }
  1140. // Angle of quaternion
  1141. T Angle() const
  1142. {
  1143. return T(2) * Acos(Abs(w));
  1144. }
  1145. // Normalize
  1146. bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
  1147. void Normalize()
  1148. {
  1149. T s = Length();
  1150. if (s != T(0))
  1151. s = T(1) / s;
  1152. *this *= s;
  1153. }
  1154. Quat Normalized() const
  1155. {
  1156. T s = Length();
  1157. if (s != T(0))
  1158. s = T(1) / s;
  1159. return *this * s;
  1160. }
  1161. inline void EnsureSameHemisphere(const Quat& o)
  1162. {
  1163. if (Dot(o) < T(0))
  1164. {
  1165. x = -x;
  1166. y = -y;
  1167. z = -z;
  1168. w = -w;
  1169. }
  1170. }
  1171. // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
  1172. Quat Conj() const { return Quat(-x, -y, -z, w); }
  1173. // Quaternion multiplication. Combines quaternion rotations, performing the one on the
  1174. // right hand side first.
  1175. Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
  1176. w * b.y - x * b.z + y * b.w + z * b.x,
  1177. w * b.z + x * b.y - y * b.x + z * b.w,
  1178. w * b.w - x * b.x - y * b.y - z * b.z); }
  1179. const Quat& operator*= (const Quat& b) { *this = *this * b; return *this; }
  1180. //
  1181. // this^p normalized; same as rotating by this p times.
  1182. Quat PowNormalized(T p) const
  1183. {
  1184. Vector3<T> v;
  1185. T a;
  1186. GetAxisAngle(&v, &a);
  1187. return Quat(v, a * p);
  1188. }
  1189. // Compute quaternion that rotates v into alignTo: alignTo = Quat::Align(alignTo, v).Rotate(v).
  1190. // NOTE: alignTo and v must be normalized.
  1191. static Quat Align(const Vector3<T>& alignTo, const Vector3<T>& v)
  1192. {
  1193. OVR_MATH_ASSERT(alignTo.IsNormalized() && v.IsNormalized());
  1194. Vector3<T> bisector = (v + alignTo);
  1195. bisector.Normalize();
  1196. T cosHalfAngle = v.Dot(bisector); // 0..1
  1197. if (cosHalfAngle > T(0))
  1198. {
  1199. Vector3<T> imag = v.Cross(bisector);
  1200. return Quat(imag.x, imag.y, imag.z, cosHalfAngle);
  1201. }
  1202. else
  1203. {
  1204. // cosHalfAngle == 0: a 180 degree rotation.
  1205. // sinHalfAngle == 1, rotation axis is any axis perpendicular
  1206. // to alignTo. Choose axis to include largest magnitude components
  1207. if (fabs(v.x) > fabs(v.y))
  1208. {
  1209. // x or z is max magnitude component
  1210. // = Cross(v, (0,1,0)).Normalized();
  1211. T invLen = sqrt(v.x*v.x + v.z*v.z);
  1212. if (invLen > T(0))
  1213. invLen = T(1) / invLen;
  1214. return Quat(-v.z*invLen, 0, v.x*invLen, 0);
  1215. }
  1216. else
  1217. {
  1218. // y or z is max magnitude component
  1219. // = Cross(v, (1,0,0)).Normalized();
  1220. T invLen = sqrt(v.y*v.y + v.z*v.z);
  1221. if (invLen > T(0))
  1222. invLen = T(1) / invLen;
  1223. return Quat(0, v.z*invLen, -v.y*invLen, 0);
  1224. }
  1225. }
  1226. }
  1227. // Normalized linear interpolation of quaternions
  1228. // NOTE: This function is a bad approximation of Slerp()
  1229. // when the angle between the *this and b is large.
  1230. // Use FastSlerp() or Slerp() instead.
  1231. Quat Lerp(const Quat& b, T s) const
  1232. {
  1233. return (*this * (T(1) - s) + b * (Dot(b) < 0 ? -s : s)).Normalized();
  1234. }
  1235. // Spherical linear interpolation between rotations
  1236. Quat Slerp(const Quat& b, T s) const
  1237. {
  1238. Vector3<T> delta = (b * this->Inverted()).ToRotationVector();
  1239. return FromRotationVector(delta * s) * *this;
  1240. }
  1241. // Spherical linear interpolation: much faster for small rotations, accurate for large rotations. See FastTo/FromRotationVector
  1242. Quat FastSlerp(const Quat& b, T s) const
  1243. {
  1244. Vector3<T> delta = (b * this->Inverted()).FastToRotationVector();
  1245. return (FastFromRotationVector(delta * s, false) * *this).Normalized();
  1246. }
  1247. // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
  1248. // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1.
  1249. Vector3<T> Rotate(const Vector3<T>& v) const
  1250. {
  1251. OVR_MATH_ASSERT(IsNormalized());
  1252. // rv = q * (v,0) * q'
  1253. // Same as rv = v + real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2);
  1254. // uv = 2 * Imag().Cross(v);
  1255. T uvx = T(2) * (y*v.z - z*v.y);
  1256. T uvy = T(2) * (z*v.x - x*v.z);
  1257. T uvz = T(2) * (x*v.y - y*v.x);
  1258. // return v + Real()*uv + Imag().Cross(uv);
  1259. return Vector3<T>(v.x + w*uvx + y*uvz - z*uvy,
  1260. v.y + w*uvy + z*uvx - x*uvz,
  1261. v.z + w*uvz + x*uvy - y*uvx);
  1262. }
  1263. // Rotation by inverse of *this
  1264. Vector3<T> InverseRotate(const Vector3<T>& v) const
  1265. {
  1266. OVR_MATH_ASSERT(IsNormalized());
  1267. // rv = q' * (v,0) * q
  1268. // Same as rv = v + real * cross(-imag,v)*2 + cross(-imag, cross(-imag,v)*2);
  1269. // or rv = v - real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2);
  1270. // uv = 2 * Imag().Cross(v);
  1271. T uvx = T(2) * (y*v.z - z*v.y);
  1272. T uvy = T(2) * (z*v.x - x*v.z);
  1273. T uvz = T(2) * (x*v.y - y*v.x);
  1274. // return v - Real()*uv + Imag().Cross(uv);
  1275. return Vector3<T>(v.x - w*uvx + y*uvz - z*uvy,
  1276. v.y - w*uvy + z*uvx - x*uvz,
  1277. v.z - w*uvz + x*uvy - y*uvx);
  1278. }
  1279. // Inversed quaternion rotates in the opposite direction.
  1280. Quat Inverted() const
  1281. {
  1282. return Quat(-x, -y, -z, w);
  1283. }
  1284. Quat Inverse() const
  1285. {
  1286. return Quat(-x, -y, -z, w);
  1287. }
  1288. // Sets this quaternion to the one rotates in the opposite direction.
  1289. void Invert()
  1290. {
  1291. *this = Quat(-x, -y, -z, w);
  1292. }
  1293. // Time integration of constant angular velocity over dt
  1294. Quat TimeIntegrate(Vector3<T> angularVelocity, T dt) const
  1295. {
  1296. // solution is: this * exp( omega*dt/2 ); FromRotationVector(v) gives exp(v*.5).
  1297. return (*this * FastFromRotationVector(angularVelocity * dt, false)).Normalized();
  1298. }
  1299. // Time integration of constant angular acceleration and velocity over dt
  1300. // These are the first two terms of the "Magnus expansion" of the solution
  1301. //
  1302. // o = o * exp( W=(W1 + W2 + W3+...) * 0.5 );
  1303. //
  1304. // omega1 = (omega + omegaDot*dt)
  1305. // W1 = (omega + omega1)*dt/2
  1306. // W2 = cross(omega, omega1)/12*dt^2 % (= -cross(omega_dot, omega)/12*dt^3)
  1307. // Terms 3 and beyond are vanishingly small:
  1308. // W3 = cross(omega_dot, cross(omega_dot, omega))/240*dt^5
  1309. //
  1310. Quat TimeIntegrate(Vector3<T> angularVelocity, Vector3<T> angularAcceleration, T dt) const
  1311. {
  1312. const Vector3<T>& omega = angularVelocity;
  1313. const Vector3<T>& omegaDot = angularAcceleration;
  1314. Vector3<T> omega1 = (omega + omegaDot * dt);
  1315. Vector3<T> W = ( (omega + omega1) + omega.Cross(omega1) * (dt/T(6)) ) * (dt/T(2));
  1316. // FromRotationVector(v) is exp(v*.5)
  1317. return (*this * FastFromRotationVector(W, false)).Normalized();
  1318. }
  1319. // Decompose rotation into three rotations:
  1320. // roll radians about Z axis, then pitch radians about X axis, then yaw radians about Y axis.
  1321. // Call with nullptr if a return value is not needed.
  1322. void GetYawPitchRoll(T* yaw, T* pitch, T* roll) const
  1323. {
  1324. return GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(yaw, pitch, roll);
  1325. }
  1326. // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
  1327. // axis rotations and the specified coordinate system. Right-handed coordinate system
  1328. // is the default, with CCW rotations while looking in the negative axis direction.
  1329. // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
  1330. // Rotation order is c, b, a:
  1331. // rotation c around axis A3
  1332. // is followed by rotation b around axis A2
  1333. // is followed by rotation a around axis A1
  1334. // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  1335. //
  1336. template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
  1337. void GetEulerAngles(T *a, T *b, T *c) const
  1338. {
  1339. OVR_MATH_ASSERT(IsNormalized());
  1340. OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)");
  1341. T Q[3] = { x, y, z }; //Quaternion components x,y,z
  1342. T ww = w*w;
  1343. T Q11 = Q[A1]*Q[A1];
  1344. T Q22 = Q[A2]*Q[A2];
  1345. T Q33 = Q[A3]*Q[A3];
  1346. T psign = T(-1);
  1347. // Determine whether even permutation
  1348. if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
  1349. psign = T(1);
  1350. T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
  1351. T singularityRadius = Math<T>::SingularityRadius();
  1352. if (s2 < T(-1) + singularityRadius)
  1353. { // South pole singularity
  1354. if (a) *a = T(0);
  1355. if (b) *b = -S*D*((T)MATH_DOUBLE_PIOVER2);
  1356. if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33 );
  1357. }
  1358. else if (s2 > T(1) - singularityRadius)
  1359. { // North pole singularity
  1360. if (a) *a = T(0);
  1361. if (b) *b = S*D*((T)MATH_DOUBLE_PIOVER2);
  1362. if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33);
  1363. }
  1364. else
  1365. {
  1366. if (a) *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2] * Q[A3]), ww + Q33 - Q11 - Q22);
  1367. if (b) *b = S*D*asin(s2);
  1368. if (c) *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1] * Q[A2]), ww + Q11 - Q22 - Q33);
  1369. }
  1370. }
  1371. template <Axis A1, Axis A2, Axis A3, RotateDirection D>
  1372. void GetEulerAngles(T *a, T *b, T *c) const
  1373. { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
  1374. template <Axis A1, Axis A2, Axis A3>
  1375. void GetEulerAngles(T *a, T *b, T *c) const
  1376. { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
  1377. // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
  1378. // axis rotations and the specified coordinate system. Right-handed coordinate system
  1379. // is the default, with CCW rotations while looking in the negative axis direction.
  1380. // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
  1381. // rotation a around axis A1
  1382. // is followed by rotation b around axis A2
  1383. // is followed by rotation c around axis A1
  1384. // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
  1385. template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
  1386. void GetEulerAnglesABA(T *a, T *b, T *c) const
  1387. {
  1388. OVR_MATH_ASSERT(IsNormalized());
  1389. OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2");
  1390. T Q[3] = {x, y, z}; // Quaternion components
  1391. // Determine the missing axis that was not supplied
  1392. int m = 3 - A1 - A2;
  1393. T ww = w*w;
  1394. T Q11 = Q[A1]*Q[A1];
  1395. T Q22 = Q[A2]*Q[A2];
  1396. T Qmm = Q[m]*Q[m];
  1397. T psign = T(-1);
  1398. if ((A1 + 1) % 3 == A2) // Determine whether even permutation
  1399. {
  1400. psign = T(1);
  1401. }
  1402. T c2 = ww + Q11 - Q22 - Qmm;
  1403. T singularityRadius = Math<T>::SingularityRadius();
  1404. if (c2 < T(-1) + singularityRadius)
  1405. { // South pole singularity
  1406. if (a) *a = T(0);
  1407. if (b) *b = S*D*((T)MATH_DOUBLE_PI);
  1408. if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]),
  1409. ww + Q22 - Q11 - Qmm);
  1410. }
  1411. else if (c2 > T(1) - singularityRadius)
  1412. { // North pole singularity
  1413. if (a) *a = T(0);
  1414. if (b) *b = T(0);
  1415. if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]),
  1416. ww + Q22 - Q11 - Qmm);
  1417. }
  1418. else
  1419. {
  1420. if (a) *a = S*D*atan2(psign*w*Q[m] + Q[A1] * Q[A2],
  1421. w*Q[A2] -psign*Q[A1]*Q[m]);
  1422. if (b) *b = S*D*acos(c2);
  1423. if (c) *c = S*D*atan2(-psign*w*Q[m] + Q[A1] * Q[A2],
  1424. w*Q[A2] + psign*Q[A1]*Q[m]);
  1425. }
  1426. }
  1427. };
  1428. typedef Quat<float> Quatf;
  1429. typedef Quat<double> Quatd;
  1430. OVR_MATH_STATIC_ASSERT((sizeof(Quatf) == 4*sizeof(float)), "sizeof(Quatf) failure");
  1431. OVR_MATH_STATIC_ASSERT((sizeof(Quatd) == 4*sizeof(double)), "sizeof(Quatd) failure");
  1432. //-------------------------------------------------------------------------------------
  1433. // ***** Pose
  1434. //
  1435. // Position and orientation combined.
  1436. //
  1437. // This structure needs to be the same size and layout on 32-bit and 64-bit arch.
  1438. // Update OVR_PadCheck.cpp when updating this object.
  1439. template<class T>
  1440. class Pose
  1441. {
  1442. public:
  1443. typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType;
  1444. Pose() { }
  1445. Pose(const Quat<T>& orientation, const Vector3<T>& pos)
  1446. : Rotation(orientation), Translation(pos) { }
  1447. Pose(const Pose& s)
  1448. : Rotation(s.Rotation), Translation(s.Translation) { }
  1449. Pose(const Matrix3<T>& R, const Vector3<T>& t)
  1450. : Rotation((Quat<T>)R), Translation(t) { }
  1451. Pose(const CompatibleType& s)
  1452. : Rotation(s.Orientation), Translation(s.Position) { }
  1453. explicit Pose(const Pose<typename Math<T>::OtherFloatType> &s)
  1454. : Rotation(s.Rotation), Translation(s.Translation)
  1455. {
  1456. // Ensure normalized rotation if converting from float to double
  1457. if (sizeof(T) > sizeof(Math<T>::OtherFloatType))
  1458. Rotation.Normalize();
  1459. }
  1460. static Pose Identity() { return Pose(Quat<T>(0, 0, 0, 1), Vector3<T>(0, 0, 0)); }
  1461. void SetIdentity() { Rotation = Quat<T>(0, 0, 0, 1); Translation = Vector3<T>(0, 0, 0); }
  1462. // used to make things obviously broken if someone tries to use the value
  1463. void SetInvalid() { Rotation = Quat<T>(NAN, NAN, NAN, NAN); Translation = Vector3<T>(NAN, NAN, NAN); }
  1464. bool IsEqual(const Pose&b, T tolerance = Math<T>::Tolerance()) const
  1465. {
  1466. return Translation.IsEqual(b.Translation, tolerance) && Rotation.IsEqual(b.Rotation, tolerance);
  1467. }
  1468. operator typename CompatibleTypes<Pose<T> >::Type () const
  1469. {
  1470. typename CompatibleTypes<Pose<T> >::Type result;
  1471. result.Orientation = Rotation;
  1472. result.Position = Translation;
  1473. return result;
  1474. }
  1475. Quat<T> Rotation;
  1476. Vector3<T> Translation;
  1477. OVR_MATH_STATIC_ASSERT((sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))");
  1478. void ToArray(T* arr) const
  1479. {
  1480. T temp[7] = { Rotation.x, Rotation.y, Rotation.z, Rotation.w, Translation.x, Translation.y, Translation.z };
  1481. for (int i = 0; i < 7; i++) arr[i] = temp[i];
  1482. }
  1483. static Pose<T> FromArray(const T* v)
  1484. {
  1485. Quat<T> rotation(v[0], v[1], v[2], v[3]);
  1486. Vector3<T> translation(v[4], v[5], v[6]);
  1487. // Ensure rotation is normalized, in case it was originally a float, stored in a .json file, etc.
  1488. return Pose<T>(rotation.Normalized(), translation);
  1489. }
  1490. Vector3<T> Rotate(const Vector3<T>& v) const
  1491. {
  1492. return Rotation.Rotate(v);
  1493. }
  1494. Vector3<T> InverseRotate(const Vector3<T>& v) const
  1495. {
  1496. return Rotation.InverseRotate(v);
  1497. }
  1498. Vector3<T> Translate(const Vector3<T>& v) const
  1499. {
  1500. return v + Translation;
  1501. }
  1502. Vector3<T> Transform(const Vector3<T>& v) const
  1503. {
  1504. return Rotate(v) + Translation;
  1505. }
  1506. Vector3<T> InverseTransform(const Vector3<T>& v) const
  1507. {
  1508. return InverseRotate(v - Translation);
  1509. }
  1510. Vector3<T> Apply(const Vector3<T>& v) const
  1511. {
  1512. return Transform(v);
  1513. }
  1514. Pose operator*(const Pose& other) const
  1515. {
  1516. return Pose(Rotation * other.Rotation, Apply(other.Translation));
  1517. }
  1518. Pose Inverted() const
  1519. {
  1520. Quat<T> inv = Rotation.Inverted();
  1521. return Pose(inv, inv.Rotate(-Translation));
  1522. }
  1523. // Interpolation between two poses: translation is interpolated with Lerp(),
  1524. // and rotations are interpolated with Slerp().
  1525. Pose Lerp(const Pose& b, T s)
  1526. {
  1527. return Pose(Rotation.Slerp(b.Rotation, s), Translation.Lerp(b.Translation, s));
  1528. }
  1529. // Similar to Lerp above, except faster in case of small rotation differences. See Quat<T>::FastSlerp.
  1530. Pose FastLerp(const Pose& b, T s)
  1531. {
  1532. return Pose(Rotation.FastSlerp(b.Rotation, s), Translation.Lerp(b.Translation, s));
  1533. }
  1534. Pose TimeIntegrate(const Vector3<T>& linearVelocity, const Vector3<T>& angularVelocity, T dt) const
  1535. {
  1536. return Pose(
  1537. (Rotation * Quat<T>::FastFromRotationVector(angularVelocity * dt, false)).Normalized(),
  1538. Translation + linearVelocity * dt);
  1539. }
  1540. Pose TimeIntegrate(const Vector3<T>& linearVelocity, const Vector3<T>& linearAcceleration,
  1541. const Vector3<T>& angularVelocity, const Vector3<T>& angularAcceleration,
  1542. T dt) const
  1543. {
  1544. return Pose(Rotation.TimeIntegrate(angularVelocity, angularAcceleration, dt),
  1545. Translation + linearVelocity*dt + linearAcceleration*dt*dt * T(0.5));
  1546. }
  1547. };
  1548. typedef Pose<float> Posef;
  1549. typedef Pose<double> Posed;
  1550. OVR_MATH_STATIC_ASSERT((sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), "sizeof(Posed) failure");
  1551. OVR_MATH_STATIC_ASSERT((sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), "sizeof(Posef) failure");
  1552. //-------------------------------------------------------------------------------------
  1553. // ***** Matrix4
  1554. //
  1555. // Matrix4 is a 4x4 matrix used for 3d transformations and projections.
  1556. // Translation stored in the last column.
  1557. // The matrix is stored in row-major order in memory, meaning that values
  1558. // of the first row are stored before the next one.
  1559. //
  1560. // The arrangement of the matrix is chosen to be in Right-Handed
  1561. // coordinate system and counterclockwise rotations when looking down
  1562. // the axis
  1563. //
  1564. // Transformation Order:
  1565. // - Transformations are applied from right to left, so the expression
  1566. // M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
  1567. // followed by M2 and M1.
  1568. //
  1569. // Coordinate system: Right Handed
  1570. //
  1571. // Rotations: Counterclockwise when looking down the axis. All angles are in radians.
  1572. //
  1573. // | sx 01 02 tx | // First column (sx, 10, 20): Axis X basis vector.
  1574. // | 10 sy 12 ty | // Second column (01, sy, 21): Axis Y basis vector.
  1575. // | 20 21 sz tz | // Third columnt (02, 12, sz): Axis Z basis vector.
  1576. // | 30 31 32 33 |
  1577. //
  1578. // The basis vectors are first three columns.
  1579. template<class T>
  1580. class Matrix4
  1581. {
  1582. public:
  1583. typedef T ElementType;
  1584. static const size_t Dimension = 4;
  1585. T M[4][4];
  1586. enum NoInitType { NoInit };
  1587. // Construct with no memory initialization.
  1588. Matrix4(NoInitType) { }
  1589. // By default, we construct identity matrix.
  1590. Matrix4()
  1591. {
  1592. M[0][0] = M[1][1] = M[2][2] = M[3][3] = T(1);
  1593. M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0);
  1594. M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0);
  1595. M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(0);
  1596. }
  1597. Matrix4(T m11, T m12, T m13, T m14,
  1598. T m21, T m22, T m23, T m24,
  1599. T m31, T m32, T m33, T m34,
  1600. T m41, T m42, T m43, T m44)
  1601. {
  1602. M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14;
  1603. M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24;
  1604. M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34;
  1605. M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44;
  1606. }
  1607. Matrix4(T m11, T m12, T m13,
  1608. T m21, T m22, T m23,
  1609. T m31, T m32, T m33)
  1610. {
  1611. M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = T(0);
  1612. M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = T(0);
  1613. M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = T(0);
  1614. M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(1);
  1615. }
  1616. explicit Matrix4(const Matrix3<T>& m)
  1617. {
  1618. M[0][0] = m.M[0][0]; M[0][1] = m.M[0][1]; M[0][2] = m.M[0][2]; M[0][3] = T(0);
  1619. M[1][0] = m.M[1][0]; M[1][1] = m.M[1][1]; M[1][2] = m.M[1][2]; M[1][3] = T(0);
  1620. M[2][0] = m.M[2][0]; M[2][1] = m.M[2][1]; M[2][2] = m.M[2][2]; M[2][3] = T(0);
  1621. M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(1);
  1622. }
  1623. explicit Matrix4(const Quat<T>& q)
  1624. {
  1625. OVR_MATH_ASSERT(q.IsNormalized());
  1626. T ww = q.w*q.w;
  1627. T xx = q.x*q.x;
  1628. T yy = q.y*q.y;
  1629. T zz = q.z*q.z;
  1630. M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); M[0][3] = T(0);
  1631. M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); M[1][3] = T(0);
  1632. M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; M[2][3] = T(0);
  1633. M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(1);
  1634. }
  1635. explicit Matrix4(const Pose<T>& p)
  1636. {
  1637. Matrix4 result(p.Rotation);
  1638. result.SetTranslation(p.Translation);
  1639. *this = result;
  1640. }
  1641. // C-interop support
  1642. explicit Matrix4(const Matrix4<typename Math<T>::OtherFloatType> &src)
  1643. {
  1644. for (int i = 0; i < 4; i++)
  1645. for (int j = 0; j < 4; j++)
  1646. M[i][j] = (T)src.M[i][j];
  1647. }
  1648. // C-interop support.
  1649. Matrix4(const typename CompatibleTypes<Matrix4<T> >::Type& s)
  1650. {
  1651. OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)");
  1652. memcpy(M, s.M, sizeof(M));
  1653. }
  1654. operator typename CompatibleTypes<Matrix4<T> >::Type () const
  1655. {
  1656. typename CompatibleTypes<Matrix4<T> >::Type result;
  1657. OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)");
  1658. memcpy(result.M, M, sizeof(M));
  1659. return result;
  1660. }
  1661. void ToString(char* dest, size_t destsize) const
  1662. {
  1663. size_t pos = 0;
  1664. for (int r=0; r<4; r++)
  1665. {
  1666. for (int c=0; c<4; c++)
  1667. {
  1668. pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
  1669. }
  1670. }
  1671. }
  1672. static Matrix4 FromString(const char* src)
  1673. {
  1674. Matrix4 result;
  1675. if (src)
  1676. {
  1677. for (int r = 0; r < 4; r++)
  1678. {
  1679. for (int c = 0; c < 4; c++)
  1680. {
  1681. result.M[r][c] = (T)atof(src);
  1682. while (*src && *src != ' ')
  1683. {
  1684. src++;
  1685. }
  1686. while (*src && *src == ' ')
  1687. {
  1688. src++;
  1689. }
  1690. }
  1691. }
  1692. }
  1693. return result;
  1694. }
  1695. static Matrix4 Identity() { return Matrix4(); }
  1696. void SetIdentity()
  1697. {
  1698. M[0][0] = M[1][1] = M[2][2] = M[3][3] = T(1);
  1699. M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0);
  1700. M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0);
  1701. M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(0);
  1702. }
  1703. void SetXBasis(const Vector3<T>& v)
  1704. {
  1705. M[0][0] = v.x;
  1706. M[1][0] = v.y;
  1707. M[2][0] = v.z;
  1708. }
  1709. Vector3<T> GetXBasis() const
  1710. {
  1711. return Vector3<T>(M[0][0], M[1][0], M[2][0]);
  1712. }
  1713. void SetYBasis(const Vector3<T> & v)
  1714. {
  1715. M[0][1] = v.x;
  1716. M[1][1] = v.y;
  1717. M[2][1] = v.z;
  1718. }
  1719. Vector3<T> GetYBasis() const
  1720. {
  1721. return Vector3<T>(M[0][1], M[1][1], M[2][1]);
  1722. }
  1723. void SetZBasis(const Vector3<T> & v)
  1724. {
  1725. M[0][2] = v.x;
  1726. M[1][2] = v.y;
  1727. M[2][2] = v.z;
  1728. }
  1729. Vector3<T> GetZBasis() const
  1730. {
  1731. return Vector3<T>(M[0][2], M[1][2], M[2][2]);
  1732. }
  1733. bool operator== (const Matrix4& b) const
  1734. {
  1735. bool isEqual = true;
  1736. for (int i = 0; i < 4; i++)
  1737. for (int j = 0; j < 4; j++)
  1738. isEqual &= (M[i][j] == b.M[i][j]);
  1739. return isEqual;
  1740. }
  1741. Matrix4 operator+ (const Matrix4& b) const
  1742. {
  1743. Matrix4 result(*this);
  1744. result += b;
  1745. return result;
  1746. }
  1747. Matrix4& operator+= (const Matrix4& b)
  1748. {
  1749. for (int i = 0; i < 4; i++)
  1750. for (int j = 0; j < 4; j++)
  1751. M[i][j] += b.M[i][j];
  1752. return *this;
  1753. }
  1754. Matrix4 operator- (const Matrix4& b) const
  1755. {
  1756. Matrix4 result(*this);
  1757. result -= b;
  1758. return result;
  1759. }
  1760. Matrix4& operator-= (const Matrix4& b)
  1761. {
  1762. for (int i = 0; i < 4; i++)
  1763. for (int j = 0; j < 4; j++)
  1764. M[i][j] -= b.M[i][j];
  1765. return *this;
  1766. }
  1767. // Multiplies two matrices into destination with minimum copying.
  1768. static Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b)
  1769. {
  1770. OVR_MATH_ASSERT((d != &a) && (d != &b));
  1771. int i = 0;
  1772. do {
  1773. d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0] + a.M[i][3] * b.M[3][0];
  1774. d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1] + a.M[i][3] * b.M[3][1];
  1775. d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2] + a.M[i][3] * b.M[3][2];
  1776. d->M[i][3] = a.M[i][0] * b.M[0][3] + a.M[i][1] * b.M[1][3] + a.M[i][2] * b.M[2][3] + a.M[i][3] * b.M[3][3];
  1777. } while((++i) < 4);
  1778. return *d;
  1779. }
  1780. Matrix4 operator* (const Matrix4& b) const
  1781. {
  1782. Matrix4 result(Matrix4::NoInit);
  1783. Multiply(&result, *this, b);
  1784. return result;
  1785. }
  1786. Matrix4& operator*= (const Matrix4& b)
  1787. {
  1788. return Multiply(this, Matrix4(*this), b);
  1789. }
  1790. Matrix4 operator* (T s) const
  1791. {
  1792. Matrix4 result(*this);
  1793. result *= s;
  1794. return result;
  1795. }
  1796. Matrix4& operator*= (T s)
  1797. {
  1798. for (int i = 0; i < 4; i++)
  1799. for (int j = 0; j < 4; j++)
  1800. M[i][j] *= s;
  1801. return *this;
  1802. }
  1803. Matrix4 operator/ (T s) const
  1804. {
  1805. Matrix4 result(*this);
  1806. result /= s;
  1807. return result;
  1808. }
  1809. Matrix4& operator/= (T s)
  1810. {
  1811. for (int i = 0; i < 4; i++)
  1812. for (int j = 0; j < 4; j++)
  1813. M[i][j] /= s;
  1814. return *this;
  1815. }
  1816. Vector3<T> Transform(const Vector3<T>& v) const
  1817. {
  1818. const T rcpW = T(1) / (M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3]);
  1819. return Vector3<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3]) * rcpW,
  1820. (M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3]) * rcpW,
  1821. (M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]) * rcpW);
  1822. }
  1823. Vector4<T> Transform(const Vector4<T>& v) const
  1824. {
  1825. return Vector4<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3] * v.w,
  1826. M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3] * v.w,
  1827. M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3] * v.w,
  1828. M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3] * v.w);
  1829. }
  1830. Matrix4 Transposed() const
  1831. {
  1832. return Matrix4(M[0][0], M[1][0], M[2][0], M[3][0],
  1833. M[0][1], M[1][1], M[2][1], M[3][1],
  1834. M[0][2], M[1][2], M[2][2], M[3][2],
  1835. M[0][3], M[1][3], M[2][3], M[3][3]);
  1836. }
  1837. void Transpose()
  1838. {
  1839. *this = Transposed();
  1840. }
  1841. T SubDet (const size_t* rows, const size_t* cols) const
  1842. {
  1843. return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]])
  1844. - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]])
  1845. + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]);
  1846. }
  1847. T Cofactor(size_t I, size_t J) const
  1848. {
  1849. const size_t indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
  1850. return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]);
  1851. }
  1852. T Determinant() const
  1853. {
  1854. return M[0][0] * Cofactor(0,0) + M[0][1] * Cofactor(0,1) + M[0][2] * Cofactor(0,2) + M[0][3] * Cofactor(0,3);
  1855. }
  1856. Matrix4 Adjugated() const
  1857. {
  1858. return Matrix4(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0),
  1859. Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1),
  1860. Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2),
  1861. Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3));
  1862. }
  1863. Matrix4 Inverted() const
  1864. {
  1865. T det = Determinant();
  1866. OVR_MATH_ASSERT(det != 0);
  1867. return Adjugated() * (T(1)/det);
  1868. }
  1869. void Invert()
  1870. {
  1871. *this = Inverted();
  1872. }
  1873. // This is more efficient than general inverse, but ONLY works
  1874. // correctly if it is a homogeneous transform matrix (rot + trans)
  1875. Matrix4 InvertedHomogeneousTransform() const
  1876. {
  1877. // Make the inverse rotation matrix
  1878. Matrix4 rinv = this->Transposed();
  1879. rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = T(0);
  1880. // Make the inverse translation matrix
  1881. Vector3<T> tvinv(-M[0][3],-M[1][3],-M[2][3]);
  1882. Matrix4 tinv = Matrix4::Translation(tvinv);
  1883. return rinv * tinv; // "untranslate", then "unrotate"
  1884. }
  1885. // This is more efficient than general inverse, but ONLY works
  1886. // correctly if it is a homogeneous transform matrix (rot + trans)
  1887. void InvertHomogeneousTransform()
  1888. {
  1889. *this = InvertedHomogeneousTransform();
  1890. }
  1891. // Matrix to Euler Angles conversion
  1892. // a,b,c, are the YawPitchRoll angles to be returned
  1893. // rotation a around axis A1
  1894. // is followed by rotation b around axis A2
  1895. // is followed by rotation c around axis A3
  1896. // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  1897. template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
  1898. void ToEulerAngles(T *a, T *b, T *c) const
  1899. {
  1900. OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)");
  1901. T psign = T(-1);
  1902. if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation
  1903. psign = T(1);
  1904. T pm = psign*M[A1][A3];
  1905. T singularityRadius = Math<T>::SingularityRadius();
  1906. if (pm < T(-1) + singularityRadius)
  1907. { // South pole singularity
  1908. *a = T(0);
  1909. *b = -S*D*((T)MATH_DOUBLE_PIOVER2);
  1910. *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
  1911. }
  1912. else if (pm > T(1) - singularityRadius)
  1913. { // North pole singularity
  1914. *a = T(0);
  1915. *b = S*D*((T)MATH_DOUBLE_PIOVER2);
  1916. *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
  1917. }
  1918. else
  1919. { // Normal case (nonsingular)
  1920. *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] );
  1921. *b = S*D*asin(pm);
  1922. *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] );
  1923. }
  1924. }
  1925. // Matrix to Euler Angles conversion
  1926. // a,b,c, are the YawPitchRoll angles to be returned
  1927. // rotation a around axis A1
  1928. // is followed by rotation b around axis A2
  1929. // is followed by rotation c around axis A1
  1930. // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  1931. template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
  1932. void ToEulerAnglesABA(T *a, T *b, T *c) const
  1933. {
  1934. OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2");
  1935. // Determine the axis that was not supplied
  1936. int m = 3 - A1 - A2;
  1937. T psign = T(-1);
  1938. if ((A1 + 1) % 3 == A2) // Determine whether even permutation
  1939. psign = T(1);
  1940. T c2 = M[A1][A1];
  1941. T singularityRadius = Math<T>::SingularityRadius();
  1942. if (c2 < T(-1) + singularityRadius)
  1943. { // South pole singularity
  1944. *a = T(0);
  1945. *b = S*D*((T)MATH_DOUBLE_PI);
  1946. *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
  1947. }
  1948. else if (c2 > T(1) - singularityRadius)
  1949. { // North pole singularity
  1950. *a = T(0);
  1951. *b = T(0);
  1952. *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
  1953. }
  1954. else
  1955. { // Normal case (nonsingular)
  1956. *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]);
  1957. *b = S*D*acos(c2);
  1958. *c = S*D*atan2( M[A1][A2],psign*M[A1][m]);
  1959. }
  1960. }
  1961. // Creates a matrix that converts the vertices from one coordinate system
  1962. // to another.
  1963. static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from)
  1964. {
  1965. // Holds axis values from the 'to' structure
  1966. int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis };
  1967. // The inverse of the toArray
  1968. int inv[4];
  1969. inv[0] = inv[abs(to.XAxis)] = 0;
  1970. inv[abs(to.YAxis)] = 1;
  1971. inv[abs(to.ZAxis)] = 2;
  1972. Matrix4 m(0, 0, 0,
  1973. 0, 0, 0,
  1974. 0, 0, 0);
  1975. // Only three values in the matrix need to be changed to 1 or -1.
  1976. m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis/toArray[inv[abs(from.XAxis)]]);
  1977. m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis/toArray[inv[abs(from.YAxis)]]);
  1978. m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
  1979. return m;
  1980. }
  1981. // Creates a matrix for translation by vector
  1982. static Matrix4 Translation(const Vector3<T>& v)
  1983. {
  1984. Matrix4 t;
  1985. t.M[0][3] = v.x;
  1986. t.M[1][3] = v.y;
  1987. t.M[2][3] = v.z;
  1988. return t;
  1989. }
  1990. // Creates a matrix for translation by vector
  1991. static Matrix4 Translation(T x, T y, T z = T(0))
  1992. {
  1993. Matrix4 t;
  1994. t.M[0][3] = x;
  1995. t.M[1][3] = y;
  1996. t.M[2][3] = z;
  1997. return t;
  1998. }
  1999. // Sets the translation part
  2000. void SetTranslation(const Vector3<T>& v)
  2001. {
  2002. M[0][3] = v.x;
  2003. M[1][3] = v.y;
  2004. M[2][3] = v.z;
  2005. }
  2006. Vector3<T> GetTranslation() const
  2007. {
  2008. return Vector3<T>( M[0][3], M[1][3], M[2][3] );
  2009. }
  2010. // Creates a matrix for scaling by vector
  2011. static Matrix4 Scaling(const Vector3<T>& v)
  2012. {
  2013. Matrix4 t;
  2014. t.M[0][0] = v.x;
  2015. t.M[1][1] = v.y;
  2016. t.M[2][2] = v.z;
  2017. return t;
  2018. }
  2019. // Creates a matrix for scaling by vector
  2020. static Matrix4 Scaling(T x, T y, T z)
  2021. {
  2022. Matrix4 t;
  2023. t.M[0][0] = x;
  2024. t.M[1][1] = y;
  2025. t.M[2][2] = z;
  2026. return t;
  2027. }
  2028. // Creates a matrix for scaling by constant
  2029. static Matrix4 Scaling(T s)
  2030. {
  2031. Matrix4 t;
  2032. t.M[0][0] = s;
  2033. t.M[1][1] = s;
  2034. t.M[2][2] = s;
  2035. return t;
  2036. }
  2037. // Simple L1 distance in R^12
  2038. T Distance(const Matrix4& m2) const
  2039. {
  2040. T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]);
  2041. d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]);
  2042. d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]);
  2043. d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]);
  2044. d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]);
  2045. d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]);
  2046. d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]);
  2047. d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]);
  2048. return d;
  2049. }
  2050. // Creates a rotation matrix rotating around the X axis by 'angle' radians.
  2051. // Just for quick testing. Not for final API. Need to remove case.
  2052. static Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s)
  2053. {
  2054. T sina = s * d *sin(angle);
  2055. T cosa = cos(angle);
  2056. switch(A)
  2057. {
  2058. case Axis_X:
  2059. return Matrix4(1, 0, 0,
  2060. 0, cosa, -sina,
  2061. 0, sina, cosa);
  2062. case Axis_Y:
  2063. return Matrix4(cosa, 0, sina,
  2064. 0, 1, 0,
  2065. -sina, 0, cosa);
  2066. case Axis_Z:
  2067. return Matrix4(cosa, -sina, 0,
  2068. sina, cosa, 0,
  2069. 0, 0, 1);
  2070. default:
  2071. return Matrix4();
  2072. }
  2073. }
  2074. // Creates a rotation matrix rotating around the X axis by 'angle' radians.
  2075. // Rotation direction is depends on the coordinate system:
  2076. // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  2077. // while looking in the negative axis direction. This is the
  2078. // same as looking down from positive axis values towards origin.
  2079. // LHS: Positive angle values rotate clock-wise (CW), while looking in the
  2080. // negative axis direction.
  2081. static Matrix4 RotationX(T angle)
  2082. {
  2083. T sina = sin(angle);
  2084. T cosa = cos(angle);
  2085. return Matrix4(1, 0, 0,
  2086. 0, cosa, -sina,
  2087. 0, sina, cosa);
  2088. }
  2089. // Creates a rotation matrix rotating around the Y axis by 'angle' radians.
  2090. // Rotation direction is depends on the coordinate system:
  2091. // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  2092. // while looking in the negative axis direction. This is the
  2093. // same as looking down from positive axis values towards origin.
  2094. // LHS: Positive angle values rotate clock-wise (CW), while looking in the
  2095. // negative axis direction.
  2096. static Matrix4 RotationY(T angle)
  2097. {
  2098. T sina = sin(angle);
  2099. T cosa = cos(angle);
  2100. return Matrix4(cosa, 0, sina,
  2101. 0, 1, 0,
  2102. -sina, 0, cosa);
  2103. }
  2104. // Creates a rotation matrix rotating around the Z axis by 'angle' radians.
  2105. // Rotation direction is depends on the coordinate system:
  2106. // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  2107. // while looking in the negative axis direction. This is the
  2108. // same as looking down from positive axis values towards origin.
  2109. // LHS: Positive angle values rotate clock-wise (CW), while looking in the
  2110. // negative axis direction.
  2111. static Matrix4 RotationZ(T angle)
  2112. {
  2113. T sina = sin(angle);
  2114. T cosa = cos(angle);
  2115. return Matrix4(cosa, -sina, 0,
  2116. sina, cosa, 0,
  2117. 0, 0, 1);
  2118. }
  2119. // LookAtRH creates a View transformation matrix for right-handed coordinate system.
  2120. // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
  2121. // specifying the up vector. The resulting matrix should be used with PerspectiveRH
  2122. // projection.
  2123. static Matrix4 LookAtRH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
  2124. {
  2125. Vector3<T> z = (eye - at).Normalized(); // Forward
  2126. Vector3<T> x = up.Cross(z).Normalized(); // Right
  2127. Vector3<T> y = z.Cross(x);
  2128. Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)),
  2129. y.x, y.y, y.z, -(y.Dot(eye)),
  2130. z.x, z.y, z.z, -(z.Dot(eye)),
  2131. 0, 0, 0, 1 );
  2132. return m;
  2133. }
  2134. // LookAtLH creates a View transformation matrix for left-handed coordinate system.
  2135. // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
  2136. // specifying the up vector.
  2137. static Matrix4 LookAtLH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
  2138. {
  2139. Vector3<T> z = (at - eye).Normalized(); // Forward
  2140. Vector3<T> x = up.Cross(z).Normalized(); // Right
  2141. Vector3<T> y = z.Cross(x);
  2142. Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)),
  2143. y.x, y.y, y.z, -(y.Dot(eye)),
  2144. z.x, z.y, z.z, -(z.Dot(eye)),
  2145. 0, 0, 0, 1 );
  2146. return m;
  2147. }
  2148. // PerspectiveRH creates a right-handed perspective projection matrix that can be
  2149. // used with the Oculus sample renderer.
  2150. // yfov - Specifies vertical field of view in radians.
  2151. // aspect - Screen aspect ration, which is usually width/height for square pixels.
  2152. // Note that xfov = yfov * aspect.
  2153. // znear - Absolute value of near Z clipping clipping range.
  2154. // zfar - Absolute value of far Z clipping clipping range (larger then near).
  2155. // Even though RHS usually looks in the direction of negative Z, positive values
  2156. // are expected for znear and zfar.
  2157. static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar)
  2158. {
  2159. Matrix4 m;
  2160. T tanHalfFov = tan(yfov * T(0.5));
  2161. m.M[0][0] = T(1) / (aspect * tanHalfFov);
  2162. m.M[1][1] = T(1) / tanHalfFov;
  2163. m.M[2][2] = zfar / (znear - zfar);
  2164. m.M[3][2] = T(-1);
  2165. m.M[2][3] = (zfar * znear) / (znear - zfar);
  2166. m.M[3][3] = T(0);
  2167. // Note: Post-projection matrix result assumes Left-Handed coordinate system,
  2168. // with Y up, X right and Z forward. This supports positive z-buffer values.
  2169. // This is the case even for RHS coordinate input.
  2170. return m;
  2171. }
  2172. // PerspectiveLH creates a left-handed perspective projection matrix that can be
  2173. // used with the Oculus sample renderer.
  2174. // yfov - Specifies vertical field of view in radians.
  2175. // aspect - Screen aspect ration, which is usually width/height for square pixels.
  2176. // Note that xfov = yfov * aspect.
  2177. // znear - Absolute value of near Z clipping clipping range.
  2178. // zfar - Absolute value of far Z clipping clipping range (larger then near).
  2179. static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar)
  2180. {
  2181. Matrix4 m;
  2182. T tanHalfFov = tan(yfov * T(0.5));
  2183. m.M[0][0] = T(1) / (aspect * tanHalfFov);
  2184. m.M[1][1] = T(1) / tanHalfFov;
  2185. //m.M[2][2] = zfar / (znear - zfar);
  2186. m.M[2][2] = zfar / (zfar - znear);
  2187. m.M[3][2] = T(-1);
  2188. m.M[2][3] = (zfar * znear) / (znear - zfar);
  2189. m.M[3][3] = T(0);
  2190. // Note: Post-projection matrix result assumes Left-Handed coordinate system,
  2191. // with Y up, X right and Z forward. This supports positive z-buffer values.
  2192. // This is the case even for RHS coordinate input.
  2193. return m;
  2194. }
  2195. static Matrix4 Ortho2D(T w, T h)
  2196. {
  2197. Matrix4 m;
  2198. m.M[0][0] = T(2.0)/w;
  2199. m.M[1][1] = T(-2.0)/h;
  2200. m.M[0][3] = T(-1.0);
  2201. m.M[1][3] = T(1.0);
  2202. m.M[2][2] = T(0);
  2203. return m;
  2204. }
  2205. };
  2206. typedef Matrix4<float> Matrix4f;
  2207. typedef Matrix4<double> Matrix4d;
  2208. //-------------------------------------------------------------------------------------
  2209. // ***** Matrix3
  2210. //
  2211. // Matrix3 is a 3x3 matrix used for representing a rotation matrix.
  2212. // The matrix is stored in row-major order in memory, meaning that values
  2213. // of the first row are stored before the next one.
  2214. //
  2215. // The arrangement of the matrix is chosen to be in Right-Handed
  2216. // coordinate system and counterclockwise rotations when looking down
  2217. // the axis
  2218. //
  2219. // Transformation Order:
  2220. // - Transformations are applied from right to left, so the expression
  2221. // M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
  2222. // followed by M2 and M1.
  2223. //
  2224. // Coordinate system: Right Handed
  2225. //
  2226. // Rotations: Counterclockwise when looking down the axis. All angles are in radians.
  2227. template<class T>
  2228. class Matrix3
  2229. {
  2230. public:
  2231. typedef T ElementType;
  2232. static const size_t Dimension = 3;
  2233. T M[3][3];
  2234. enum NoInitType { NoInit };
  2235. // Construct with no memory initialization.
  2236. Matrix3(NoInitType) { }
  2237. // By default, we construct identity matrix.
  2238. Matrix3()
  2239. {
  2240. M[0][0] = M[1][1] = M[2][2] = T(1);
  2241. M[0][1] = M[1][0] = M[2][0] = T(0);
  2242. M[0][2] = M[1][2] = M[2][1] = T(0);
  2243. }
  2244. Matrix3(T m11, T m12, T m13,
  2245. T m21, T m22, T m23,
  2246. T m31, T m32, T m33)
  2247. {
  2248. M[0][0] = m11; M[0][1] = m12; M[0][2] = m13;
  2249. M[1][0] = m21; M[1][1] = m22; M[1][2] = m23;
  2250. M[2][0] = m31; M[2][1] = m32; M[2][2] = m33;
  2251. }
  2252. // Construction from X, Y, Z basis vectors
  2253. Matrix3(const Vector3<T>& xBasis, const Vector3<T>& yBasis, const Vector3<T>& zBasis)
  2254. {
  2255. M[0][0] = xBasis.x; M[0][1] = yBasis.x; M[0][2] = zBasis.x;
  2256. M[1][0] = xBasis.y; M[1][1] = yBasis.y; M[1][2] = zBasis.y;
  2257. M[2][0] = xBasis.z; M[2][1] = yBasis.z; M[2][2] = zBasis.z;
  2258. }
  2259. explicit Matrix3(const Quat<T>& q)
  2260. {
  2261. OVR_MATH_ASSERT(q.IsNormalized());
  2262. const T tx = q.x+q.x, ty = q.y+q.y, tz = q.z+q.z;
  2263. const T twx = q.w*tx, twy = q.w*ty, twz = q.w*tz;
  2264. const T txx = q.x*tx, txy = q.x*ty, txz = q.x*tz;
  2265. const T tyy = q.y*ty, tyz = q.y*tz, tzz = q.z*tz;
  2266. M[0][0] = T(1) - (tyy + tzz); M[0][1] = txy - twz; M[0][2] = txz + twy;
  2267. M[1][0] = txy + twz; M[1][1] = T(1) - (txx + tzz); M[1][2] = tyz - twx;
  2268. M[2][0] = txz - twy; M[2][1] = tyz + twx; M[2][2] = T(1) - (txx + tyy);
  2269. }
  2270. inline explicit Matrix3(T s)
  2271. {
  2272. M[0][0] = M[1][1] = M[2][2] = s;
  2273. M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = T(0);
  2274. }
  2275. Matrix3(T m11, T m22, T m33)
  2276. {
  2277. M[0][0] = m11; M[0][1] = T(0); M[0][2] = T(0);
  2278. M[1][0] = T(0); M[1][1] = m22; M[1][2] = T(0);
  2279. M[2][0] = T(0); M[2][1] = T(0); M[2][2] = m33;
  2280. }
  2281. explicit Matrix3(const Matrix3<typename Math<T>::OtherFloatType> &src)
  2282. {
  2283. for (int i = 0; i < 3; i++)
  2284. for (int j = 0; j < 3; j++)
  2285. M[i][j] = (T)src.M[i][j];
  2286. }
  2287. // C-interop support.
  2288. Matrix3(const typename CompatibleTypes<Matrix3<T> >::Type& s)
  2289. {
  2290. OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)");
  2291. memcpy(M, s.M, sizeof(M));
  2292. }
  2293. operator const typename CompatibleTypes<Matrix3<T> >::Type () const
  2294. {
  2295. typename CompatibleTypes<Matrix3<T> >::Type result;
  2296. OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)");
  2297. memcpy(result.M, M, sizeof(M));
  2298. return result;
  2299. }
  2300. T operator()(int i, int j) const { return M[i][j]; }
  2301. T& operator()(int i, int j) { return M[i][j]; }
  2302. void ToString(char* dest, size_t destsize) const
  2303. {
  2304. size_t pos = 0;
  2305. for (int r=0; r<3; r++)
  2306. {
  2307. for (int c=0; c<3; c++)
  2308. pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
  2309. }
  2310. }
  2311. static Matrix3 FromString(const char* src)
  2312. {
  2313. Matrix3 result;
  2314. if (src)
  2315. {
  2316. for (int r=0; r<3; r++)
  2317. {
  2318. for (int c=0; c<3; c++)
  2319. {
  2320. result.M[r][c] = (T)atof(src);
  2321. while (*src && *src != ' ')
  2322. src++;
  2323. while (*src && *src == ' ')
  2324. src++;
  2325. }
  2326. }
  2327. }
  2328. return result;
  2329. }
  2330. static Matrix3 Identity() { return Matrix3(); }
  2331. void SetIdentity()
  2332. {
  2333. M[0][0] = M[1][1] = M[2][2] = T(1);
  2334. M[0][1] = M[1][0] = M[2][0] = T(0);
  2335. M[0][2] = M[1][2] = M[2][1] = T(0);
  2336. }
  2337. static Matrix3 Diagonal(T m00, T m11, T m22)
  2338. {
  2339. return Matrix3(m00, 0, 0,
  2340. 0, m11, 0,
  2341. 0, 0, m22);
  2342. }
  2343. static Matrix3 Diagonal(const Vector3<T>& v) { return Diagonal(v.x, v.y, v.z); }
  2344. T Trace() const { return M[0][0] + M[1][1] + M[2][2]; }
  2345. bool operator== (const Matrix3& b) const
  2346. {
  2347. bool isEqual = true;
  2348. for (int i = 0; i < 3; i++)
  2349. {
  2350. for (int j = 0; j < 3; j++)
  2351. isEqual &= (M[i][j] == b.M[i][j]);
  2352. }
  2353. return isEqual;
  2354. }
  2355. Matrix3 operator+ (const Matrix3& b) const
  2356. {
  2357. Matrix3<T> result(*this);
  2358. result += b;
  2359. return result;
  2360. }
  2361. Matrix3& operator+= (const Matrix3& b)
  2362. {
  2363. for (int i = 0; i < 3; i++)
  2364. for (int j = 0; j < 3; j++)
  2365. M[i][j] += b.M[i][j];
  2366. return *this;
  2367. }
  2368. void operator= (const Matrix3& b)
  2369. {
  2370. for (int i = 0; i < 3; i++)
  2371. for (int j = 0; j < 3; j++)
  2372. M[i][j] = b.M[i][j];
  2373. }
  2374. Matrix3 operator- (const Matrix3& b) const
  2375. {
  2376. Matrix3 result(*this);
  2377. result -= b;
  2378. return result;
  2379. }
  2380. Matrix3& operator-= (const Matrix3& b)
  2381. {
  2382. for (int i = 0; i < 3; i++)
  2383. {
  2384. for (int j = 0; j < 3; j++)
  2385. M[i][j] -= b.M[i][j];
  2386. }
  2387. return *this;
  2388. }
  2389. // Multiplies two matrices into destination with minimum copying.
  2390. static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b)
  2391. {
  2392. OVR_MATH_ASSERT((d != &a) && (d != &b));
  2393. int i = 0;
  2394. do {
  2395. d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0];
  2396. d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1];
  2397. d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2];
  2398. } while((++i) < 3);
  2399. return *d;
  2400. }
  2401. Matrix3 operator* (const Matrix3& b) const
  2402. {
  2403. Matrix3 result(Matrix3::NoInit);
  2404. Multiply(&result, *this, b);
  2405. return result;
  2406. }
  2407. Matrix3& operator*= (const Matrix3& b)
  2408. {
  2409. return Multiply(this, Matrix3(*this), b);
  2410. }
  2411. Matrix3 operator* (T s) const
  2412. {
  2413. Matrix3 result(*this);
  2414. result *= s;
  2415. return result;
  2416. }
  2417. Matrix3& operator*= (T s)
  2418. {
  2419. for (int i = 0; i < 3; i++)
  2420. {
  2421. for (int j = 0; j < 3; j++)
  2422. M[i][j] *= s;
  2423. }
  2424. return *this;
  2425. }
  2426. Vector3<T> operator* (const Vector3<T> &b) const
  2427. {
  2428. Vector3<T> result;
  2429. result.x = M[0][0]*b.x + M[0][1]*b.y + M[0][2]*b.z;
  2430. result.y = M[1][0]*b.x + M[1][1]*b.y + M[1][2]*b.z;
  2431. result.z = M[2][0]*b.x + M[2][1]*b.y + M[2][2]*b.z;
  2432. return result;
  2433. }
  2434. Matrix3 operator/ (T s) const
  2435. {
  2436. Matrix3 result(*this);
  2437. result /= s;
  2438. return result;
  2439. }
  2440. Matrix3& operator/= (T s)
  2441. {
  2442. for (int i = 0; i < 3; i++)
  2443. {
  2444. for (int j = 0; j < 3; j++)
  2445. M[i][j] /= s;
  2446. }
  2447. return *this;
  2448. }
  2449. Vector2<T> Transform(const Vector2<T>& v) const
  2450. {
  2451. const T rcpZ = T(1) / (M[2][0] * v.x + M[2][1] * v.y + M[2][2]);
  2452. return Vector2<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2]) * rcpZ,
  2453. (M[1][0] * v.x + M[1][1] * v.y + M[1][2]) * rcpZ);
  2454. }
  2455. Vector3<T> Transform(const Vector3<T>& v) const
  2456. {
  2457. return Vector3<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z,
  2458. M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z,
  2459. M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z);
  2460. }
  2461. Matrix3 Transposed() const
  2462. {
  2463. return Matrix3(M[0][0], M[1][0], M[2][0],
  2464. M[0][1], M[1][1], M[2][1],
  2465. M[0][2], M[1][2], M[2][2]);
  2466. }
  2467. void Transpose()
  2468. {
  2469. *this = Transposed();
  2470. }
  2471. T SubDet (const size_t* rows, const size_t* cols) const
  2472. {
  2473. return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]])
  2474. - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]])
  2475. + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]);
  2476. }
  2477. // M += a*b.t()
  2478. inline void Rank1Add(const Vector3<T> &a, const Vector3<T> &b)
  2479. {
  2480. M[0][0] += a.x*b.x; M[0][1] += a.x*b.y; M[0][2] += a.x*b.z;
  2481. M[1][0] += a.y*b.x; M[1][1] += a.y*b.y; M[1][2] += a.y*b.z;
  2482. M[2][0] += a.z*b.x; M[2][1] += a.z*b.y; M[2][2] += a.z*b.z;
  2483. }
  2484. // M -= a*b.t()
  2485. inline void Rank1Sub(const Vector3<T> &a, const Vector3<T> &b)
  2486. {
  2487. M[0][0] -= a.x*b.x; M[0][1] -= a.x*b.y; M[0][2] -= a.x*b.z;
  2488. M[1][0] -= a.y*b.x; M[1][1] -= a.y*b.y; M[1][2] -= a.y*b.z;
  2489. M[2][0] -= a.z*b.x; M[2][1] -= a.z*b.y; M[2][2] -= a.z*b.z;
  2490. }
  2491. inline Vector3<T> Col(int c) const
  2492. {
  2493. return Vector3<T>(M[0][c], M[1][c], M[2][c]);
  2494. }
  2495. inline Vector3<T> Row(int r) const
  2496. {
  2497. return Vector3<T>(M[r][0], M[r][1], M[r][2]);
  2498. }
  2499. inline Vector3<T> GetColumn(int c) const
  2500. {
  2501. return Vector3<T>(M[0][c], M[1][c], M[2][c]);
  2502. }
  2503. inline Vector3<T> GetRow(int r) const
  2504. {
  2505. return Vector3<T>(M[r][0], M[r][1], M[r][2]);
  2506. }
  2507. inline void SetColumn(int c, const Vector3<T>& v)
  2508. {
  2509. M[0][c] = v.x;
  2510. M[1][c] = v.y;
  2511. M[2][c] = v.z;
  2512. }
  2513. inline void SetRow(int r, const Vector3<T>& v)
  2514. {
  2515. M[r][0] = v.x;
  2516. M[r][1] = v.y;
  2517. M[r][2] = v.z;
  2518. }
  2519. inline T Determinant() const
  2520. {
  2521. const Matrix3<T>& m = *this;
  2522. T d;
  2523. d = m.M[0][0] * (m.M[1][1]*m.M[2][2] - m.M[1][2] * m.M[2][1]);
  2524. d -= m.M[0][1] * (m.M[1][0]*m.M[2][2] - m.M[1][2] * m.M[2][0]);
  2525. d += m.M[0][2] * (m.M[1][0]*m.M[2][1] - m.M[1][1] * m.M[2][0]);
  2526. return d;
  2527. }
  2528. inline Matrix3<T> Inverse() const
  2529. {
  2530. Matrix3<T> a;
  2531. const Matrix3<T>& m = *this;
  2532. T d = Determinant();
  2533. OVR_MATH_ASSERT(d != 0);
  2534. T s = T(1)/d;
  2535. a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]);
  2536. a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]);
  2537. a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]);
  2538. a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]);
  2539. a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]);
  2540. a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]);
  2541. a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]);
  2542. a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]);
  2543. a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]);
  2544. return a;
  2545. }
  2546. // Outer Product of two column vectors: a * b.Transpose()
  2547. static Matrix3 OuterProduct(const Vector3<T>& a, const Vector3<T>& b)
  2548. {
  2549. return Matrix3(a.x*b.x, a.x*b.y, a.x*b.z,
  2550. a.y*b.x, a.y*b.y, a.y*b.z,
  2551. a.z*b.x, a.z*b.y, a.z*b.z);
  2552. }
  2553. // Vector cross product as a premultiply matrix:
  2554. // L.Cross(R) = LeftCrossAsMatrix(L) * R
  2555. static Matrix3 LeftCrossAsMatrix(const Vector3<T>& L)
  2556. {
  2557. return Matrix3(
  2558. T(0), -L.z, +L.y,
  2559. +L.z, T(0), -L.x,
  2560. -L.y, +L.x, T(0));
  2561. }
  2562. // Vector cross product as a premultiply matrix:
  2563. // L.Cross(R) = RightCrossAsMatrix(R) * L
  2564. static Matrix3 RightCrossAsMatrix(const Vector3<T>& R)
  2565. {
  2566. return Matrix3(
  2567. T(0), +R.z, -R.y,
  2568. -R.z, T(0), +R.x,
  2569. +R.y, -R.x, T(0));
  2570. }
  2571. // Angle in radians of a rotation matrix
  2572. // Uses identity trace(a) = 2*cos(theta) + 1
  2573. T Angle() const
  2574. {
  2575. return Acos((Trace() - T(1)) * T(0.5));
  2576. }
  2577. // Angle in radians between two rotation matrices
  2578. T Angle(const Matrix3& b) const
  2579. {
  2580. // Compute trace of (this->Transposed() * b)
  2581. // This works out to sum of products of elements.
  2582. T trace = T(0);
  2583. for (int i = 0; i < 3; i++)
  2584. {
  2585. for (int j = 0; j < 3; j++)
  2586. {
  2587. trace += M[i][j] * b.M[i][j];
  2588. }
  2589. }
  2590. return Acos((trace - T(1)) * T(0.5));
  2591. }
  2592. };
  2593. typedef Matrix3<float> Matrix3f;
  2594. typedef Matrix3<double> Matrix3d;
  2595. //-------------------------------------------------------------------------------------
  2596. // ***** Matrix2
  2597. template<class T>
  2598. class Matrix2
  2599. {
  2600. public:
  2601. typedef T ElementType;
  2602. static const size_t Dimension = 2;
  2603. T M[2][2];
  2604. enum NoInitType { NoInit };
  2605. // Construct with no memory initialization.
  2606. Matrix2(NoInitType) { }
  2607. // By default, we construct identity matrix.
  2608. Matrix2()
  2609. {
  2610. M[0][0] = M[1][1] = T(1);
  2611. M[0][1] = M[1][0] = T(0);
  2612. }
  2613. Matrix2(T m11, T m12,
  2614. T m21, T m22)
  2615. {
  2616. M[0][0] = m11; M[0][1] = m12;
  2617. M[1][0] = m21; M[1][1] = m22;
  2618. }
  2619. // Construction from X, Y basis vectors
  2620. Matrix2(const Vector2<T>& xBasis, const Vector2<T>& yBasis)
  2621. {
  2622. M[0][0] = xBasis.x; M[0][1] = yBasis.x;
  2623. M[1][0] = xBasis.y; M[1][1] = yBasis.y;
  2624. }
  2625. explicit Matrix2(T s)
  2626. {
  2627. M[0][0] = M[1][1] = s;
  2628. M[0][1] = M[1][0] = T(0);
  2629. }
  2630. Matrix2(T m11, T m22)
  2631. {
  2632. M[0][0] = m11; M[0][1] = T(0);
  2633. M[1][0] = T(0); M[1][1] = m22;
  2634. }
  2635. explicit Matrix2(const Matrix2<typename Math<T>::OtherFloatType> &src)
  2636. {
  2637. M[0][0] = T(src.M[0][0]); M[0][1] = T(src.M[0][1]);
  2638. M[1][0] = T(src.M[1][0]); M[1][1] = T(src.M[1][1]);
  2639. }
  2640. // C-interop support
  2641. Matrix2(const typename CompatibleTypes<Matrix2<T> >::Type& s)
  2642. {
  2643. OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix2), "sizeof(s) == sizeof(Matrix2)");
  2644. memcpy(M, s.M, sizeof(M));
  2645. }
  2646. operator const typename CompatibleTypes<Matrix2<T> >::Type() const
  2647. {
  2648. typename CompatibleTypes<Matrix2<T> >::Type result;
  2649. OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix2), "sizeof(result) == sizeof(Matrix2)");
  2650. memcpy(result.M, M, sizeof(M));
  2651. return result;
  2652. }
  2653. T operator()(int i, int j) const { return M[i][j]; }
  2654. T& operator()(int i, int j) { return M[i][j]; }
  2655. const T* operator[](int i) const { return M[i]; }
  2656. T* operator[](int i) { return M[i]; }
  2657. static Matrix2 Identity() { return Matrix2(); }
  2658. void SetIdentity()
  2659. {
  2660. M[0][0] = M[1][1] = T(1);
  2661. M[0][1] = M[1][0] = T(0);
  2662. }
  2663. static Matrix2 Diagonal(T m00, T m11)
  2664. {
  2665. return Matrix2(m00, m11);
  2666. }
  2667. static Matrix2 Diagonal(const Vector2<T>& v) { return Matrix2(v.x, v.y); }
  2668. T Trace() const { return M[0][0] + M[1][1]; }
  2669. bool operator== (const Matrix2& b) const
  2670. {
  2671. return M[0][0] == b.M[0][0] && M[0][1] == b.M[0][1] &&
  2672. M[1][0] == b.M[1][0] && M[1][1] == b.M[1][1];
  2673. }
  2674. Matrix2 operator+ (const Matrix2& b) const
  2675. {
  2676. return Matrix2(M[0][0] + b.M[0][0], M[0][1] + b.M[0][1],
  2677. M[1][0] + b.M[1][0], M[1][1] + b.M[1][1]);
  2678. }
  2679. Matrix2& operator+= (const Matrix2& b)
  2680. {
  2681. M[0][0] += b.M[0][0]; M[0][1] += b.M[0][1];
  2682. M[1][0] += b.M[1][0]; M[1][1] += b.M[1][1];
  2683. return *this;
  2684. }
  2685. void operator= (const Matrix2& b)
  2686. {
  2687. M[0][0] = b.M[0][0]; M[0][1] = b.M[0][1];
  2688. M[1][0] = b.M[1][0]; M[1][1] = b.M[1][1];
  2689. }
  2690. Matrix2 operator- (const Matrix2& b) const
  2691. {
  2692. return Matrix2(M[0][0] - b.M[0][0], M[0][1] - b.M[0][1],
  2693. M[1][0] - b.M[1][0], M[1][1] - b.M[1][1]);
  2694. }
  2695. Matrix2& operator-= (const Matrix2& b)
  2696. {
  2697. M[0][0] -= b.M[0][0]; M[0][1] -= b.M[0][1];
  2698. M[1][0] -= b.M[1][0]; M[1][1] -= b.M[1][1];
  2699. return *this;
  2700. }
  2701. Matrix2 operator* (const Matrix2& b) const
  2702. {
  2703. return Matrix2(M[0][0] * b.M[0][0] + M[0][1] * b.M[1][0], M[0][0] * b.M[0][1] + M[0][1] * b.M[1][1],
  2704. M[1][0] * b.M[0][0] + M[1][1] * b.M[1][0], M[1][0] * b.M[0][1] + M[1][1] * b.M[1][1]);
  2705. }
  2706. Matrix2& operator*= (const Matrix2& b)
  2707. {
  2708. *this = *this * b;
  2709. return *this;
  2710. }
  2711. Matrix2 operator* (T s) const
  2712. {
  2713. return Matrix2(M[0][0] * s, M[0][1] * s,
  2714. M[1][0] * s, M[1][1] * s);
  2715. }
  2716. Matrix2& operator*= (T s)
  2717. {
  2718. M[0][0] *= s; M[0][1] *= s;
  2719. M[1][0] *= s; M[1][1] *= s;
  2720. return *this;
  2721. }
  2722. Matrix2 operator/ (T s) const
  2723. {
  2724. return *this * (T(1) / s);
  2725. }
  2726. Matrix2& operator/= (T s)
  2727. {
  2728. return *this *= (T(1) / s);
  2729. }
  2730. Vector2<T> operator* (const Vector2<T> &b) const
  2731. {
  2732. return Vector2<T>(M[0][0] * b.x + M[0][1] * b.y,
  2733. M[1][0] * b.x + M[1][1] * b.y);
  2734. }
  2735. Vector2<T> Transform(const Vector2<T>& v) const
  2736. {
  2737. return Vector2<T>(M[0][0] * v.x + M[0][1] * v.y,
  2738. M[1][0] * v.x + M[1][1] * v.y);
  2739. }
  2740. Matrix2 Transposed() const
  2741. {
  2742. return Matrix2(M[0][0], M[1][0],
  2743. M[0][1], M[1][1]);
  2744. }
  2745. void Transpose()
  2746. {
  2747. OVRMath_Swap(M[1][0], M[0][1]);
  2748. }
  2749. Vector2<T> GetColumn(int c) const
  2750. {
  2751. return Vector2<T>(M[0][c], M[1][c]);
  2752. }
  2753. Vector2<T> GetRow(int r) const
  2754. {
  2755. return Vector2<T>(M[r][0], M[r][1]);
  2756. }
  2757. void SetColumn(int c, const Vector2<T>& v)
  2758. {
  2759. M[0][c] = v.x;
  2760. M[1][c] = v.y;
  2761. }
  2762. void SetRow(int r, const Vector2<T>& v)
  2763. {
  2764. M[r][0] = v.x;
  2765. M[r][1] = v.y;
  2766. }
  2767. T Determinant() const
  2768. {
  2769. return M[0][0] * M[1][1] - M[0][1] * M[1][0];
  2770. }
  2771. Matrix2 Inverse() const
  2772. {
  2773. T rcpDet = T(1) / Determinant();
  2774. return Matrix2( M[1][1] * rcpDet, -M[0][1] * rcpDet,
  2775. -M[1][0] * rcpDet, M[0][0] * rcpDet);
  2776. }
  2777. // Outer Product of two column vectors: a * b.Transpose()
  2778. static Matrix2 OuterProduct(const Vector2<T>& a, const Vector2<T>& b)
  2779. {
  2780. return Matrix2(a.x*b.x, a.x*b.y,
  2781. a.y*b.x, a.y*b.y);
  2782. }
  2783. // Angle in radians between two rotation matrices
  2784. T Angle(const Matrix2& b) const
  2785. {
  2786. const Matrix2& a = *this;
  2787. return Acos(a(0, 0)*b(0, 0) + a(1, 0)*b(1, 0));
  2788. }
  2789. };
  2790. typedef Matrix2<float> Matrix2f;
  2791. typedef Matrix2<double> Matrix2d;
  2792. //-------------------------------------------------------------------------------------
  2793. template<class T>
  2794. class SymMat3
  2795. {
  2796. private:
  2797. typedef SymMat3<T> this_type;
  2798. public:
  2799. typedef T Value_t;
  2800. // Upper symmetric
  2801. T v[6]; // _00 _01 _02 _11 _12 _22
  2802. inline SymMat3() {}
  2803. inline explicit SymMat3(T s)
  2804. {
  2805. v[0] = v[3] = v[5] = s;
  2806. v[1] = v[2] = v[4] = T(0);
  2807. }
  2808. inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22)
  2809. {
  2810. v[0] = a00; v[1] = a01; v[2] = a02;
  2811. v[3] = a11; v[4] = a12;
  2812. v[5] = a22;
  2813. }
  2814. // Cast to symmetric Matrix3
  2815. operator Matrix3<T>() const
  2816. {
  2817. return Matrix3<T>(v[0], v[1], v[2],
  2818. v[1], v[3], v[4],
  2819. v[2], v[4], v[5]);
  2820. }
  2821. static inline int Index(unsigned int i, unsigned int j)
  2822. {
  2823. return (i <= j) ? (3*i - i*(i+1)/2 + j) : (3*j - j*(j+1)/2 + i);
  2824. }
  2825. inline T operator()(int i, int j) const { return v[Index(i,j)]; }
  2826. inline T &operator()(int i, int j) { return v[Index(i,j)]; }
  2827. inline this_type& operator+=(const this_type& b)
  2828. {
  2829. v[0]+=b.v[0];
  2830. v[1]+=b.v[1];
  2831. v[2]+=b.v[2];
  2832. v[3]+=b.v[3];
  2833. v[4]+=b.v[4];
  2834. v[5]+=b.v[5];
  2835. return *this;
  2836. }
  2837. inline this_type& operator-=(const this_type& b)
  2838. {
  2839. v[0]-=b.v[0];
  2840. v[1]-=b.v[1];
  2841. v[2]-=b.v[2];
  2842. v[3]-=b.v[3];
  2843. v[4]-=b.v[4];
  2844. v[5]-=b.v[5];
  2845. return *this;
  2846. }
  2847. inline this_type& operator*=(T s)
  2848. {
  2849. v[0]*=s;
  2850. v[1]*=s;
  2851. v[2]*=s;
  2852. v[3]*=s;
  2853. v[4]*=s;
  2854. v[5]*=s;
  2855. return *this;
  2856. }
  2857. inline SymMat3 operator*(T s) const
  2858. {
  2859. SymMat3 d;
  2860. d.v[0] = v[0]*s;
  2861. d.v[1] = v[1]*s;
  2862. d.v[2] = v[2]*s;
  2863. d.v[3] = v[3]*s;
  2864. d.v[4] = v[4]*s;
  2865. d.v[5] = v[5]*s;
  2866. return d;
  2867. }
  2868. // Multiplies two matrices into destination with minimum copying.
  2869. static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b)
  2870. {
  2871. // _00 _01 _02 _11 _12 _22
  2872. d->v[0] = a.v[0] * b.v[0];
  2873. d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3];
  2874. d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4];
  2875. d->v[3] = a.v[3] * b.v[3];
  2876. d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5];
  2877. d->v[5] = a.v[5] * b.v[5];
  2878. return *d;
  2879. }
  2880. inline T Determinant() const
  2881. {
  2882. const this_type& m = *this;
  2883. T d;
  2884. d = m(0,0) * (m(1,1)*m(2,2) - m(1,2) * m(2,1));
  2885. d -= m(0,1) * (m(1,0)*m(2,2) - m(1,2) * m(2,0));
  2886. d += m(0,2) * (m(1,0)*m(2,1) - m(1,1) * m(2,0));
  2887. return d;
  2888. }
  2889. inline this_type Inverse() const
  2890. {
  2891. this_type a;
  2892. const this_type& m = *this;
  2893. T d = Determinant();
  2894. OVR_MATH_ASSERT(d != 0);
  2895. T s = T(1)/d;
  2896. a(0,0) = s * (m(1,1) * m(2,2) - m(1,2) * m(2,1));
  2897. a(0,1) = s * (m(0,2) * m(2,1) - m(0,1) * m(2,2));
  2898. a(1,1) = s * (m(0,0) * m(2,2) - m(0,2) * m(2,0));
  2899. a(0,2) = s * (m(0,1) * m(1,2) - m(0,2) * m(1,1));
  2900. a(1,2) = s * (m(0,2) * m(1,0) - m(0,0) * m(1,2));
  2901. a(2,2) = s * (m(0,0) * m(1,1) - m(0,1) * m(1,0));
  2902. return a;
  2903. }
  2904. inline T Trace() const { return v[0] + v[3] + v[5]; }
  2905. // M = a*a.t()
  2906. inline void Rank1(const Vector3<T> &a)
  2907. {
  2908. v[0] = a.x*a.x; v[1] = a.x*a.y; v[2] = a.x*a.z;
  2909. v[3] = a.y*a.y; v[4] = a.y*a.z;
  2910. v[5] = a.z*a.z;
  2911. }
  2912. // M += a*a.t()
  2913. inline void Rank1Add(const Vector3<T> &a)
  2914. {
  2915. v[0] += a.x*a.x; v[1] += a.x*a.y; v[2] += a.x*a.z;
  2916. v[3] += a.y*a.y; v[4] += a.y*a.z;
  2917. v[5] += a.z*a.z;
  2918. }
  2919. // M -= a*a.t()
  2920. inline void Rank1Sub(const Vector3<T> &a)
  2921. {
  2922. v[0] -= a.x*a.x; v[1] -= a.x*a.y; v[2] -= a.x*a.z;
  2923. v[3] -= a.y*a.y; v[4] -= a.y*a.z;
  2924. v[5] -= a.z*a.z;
  2925. }
  2926. };
  2927. typedef SymMat3<float> SymMat3f;
  2928. typedef SymMat3<double> SymMat3d;
  2929. template<class T>
  2930. inline Matrix3<T> operator*(const SymMat3<T>& a, const SymMat3<T>& b)
  2931. {
  2932. #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
  2933. return Matrix3<T>(
  2934. AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
  2935. AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
  2936. AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
  2937. #undef AJB_ARBC
  2938. }
  2939. template<class T>
  2940. inline Matrix3<T> operator*(const Matrix3<T>& a, const SymMat3<T>& b)
  2941. {
  2942. #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
  2943. return Matrix3<T>(
  2944. AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
  2945. AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
  2946. AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
  2947. #undef AJB_ARBC
  2948. }
  2949. //-------------------------------------------------------------------------------------
  2950. // ***** Angle
  2951. // Cleanly representing the algebra of 2D rotations.
  2952. // The operations maintain the angle between -Pi and Pi, the same range as atan2.
  2953. template<class T>
  2954. class Angle
  2955. {
  2956. public:
  2957. enum AngularUnits
  2958. {
  2959. Radians = 0,
  2960. Degrees = 1
  2961. };
  2962. Angle() : a(0) {}
  2963. // Fix the range to be between -Pi and Pi
  2964. Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); }
  2965. T Get(AngularUnits u = Radians) const { return (u == Radians) ? a : a*((T)MATH_DOUBLE_RADTODEGREEFACTOR); }
  2966. void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*((T)MATH_DOUBLE_DEGREETORADFACTOR); FixRange(); }
  2967. int Sign() const { if (a == 0) return 0; else return (a > 0) ? 1 : -1; }
  2968. T Abs() const { return (a >= 0) ? a : -a; }
  2969. bool operator== (const Angle& b) const { return a == b.a; }
  2970. bool operator!= (const Angle& b) const { return a != b.a; }
  2971. // bool operator< (const Angle& b) const { return a < a.b; }
  2972. // bool operator> (const Angle& b) const { return a > a.b; }
  2973. // bool operator<= (const Angle& b) const { return a <= a.b; }
  2974. // bool operator>= (const Angle& b) const { return a >= a.b; }
  2975. // bool operator= (const T& x) { a = x; FixRange(); }
  2976. // These operations assume a is already between -Pi and Pi.
  2977. Angle& operator+= (const Angle& b) { a = a + b.a; FastFixRange(); return *this; }
  2978. Angle& operator+= (const T& x) { a = a + x; FixRange(); return *this; }
  2979. Angle operator+ (const Angle& b) const { Angle res = *this; res += b; return res; }
  2980. Angle operator+ (const T& x) const { Angle res = *this; res += x; return res; }
  2981. Angle& operator-= (const Angle& b) { a = a - b.a; FastFixRange(); return *this; }
  2982. Angle& operator-= (const T& x) { a = a - x; FixRange(); return *this; }
  2983. Angle operator- (const Angle& b) const { Angle res = *this; res -= b; return res; }
  2984. Angle operator- (const T& x) const { Angle res = *this; res -= x; return res; }
  2985. T Distance(const Angle& b) { T c = fabs(a - b.a); return (c <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_TWOPI) - c; }
  2986. private:
  2987. // The stored angle, which should be maintained between -Pi and Pi
  2988. T a;
  2989. // Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side
  2990. inline void FastFixRange()
  2991. {
  2992. if (a < -((T)MATH_DOUBLE_PI))
  2993. a += ((T)MATH_DOUBLE_TWOPI);
  2994. else if (a > ((T)MATH_DOUBLE_PI))
  2995. a -= ((T)MATH_DOUBLE_TWOPI);
  2996. }
  2997. // Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method
  2998. inline void FixRange()
  2999. {
  3000. // do nothing if the value is already in the correct range, since fmod call is expensive
  3001. if (a >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI))
  3002. return;
  3003. a = fmod(a,((T)MATH_DOUBLE_TWOPI));
  3004. if (a < -((T)MATH_DOUBLE_PI))
  3005. a += ((T)MATH_DOUBLE_TWOPI);
  3006. else if (a > ((T)MATH_DOUBLE_PI))
  3007. a -= ((T)MATH_DOUBLE_TWOPI);
  3008. }
  3009. };
  3010. typedef Angle<float> Anglef;
  3011. typedef Angle<double> Angled;
  3012. //-------------------------------------------------------------------------------------
  3013. // ***** Plane
  3014. // Consists of a normal vector and distance from the origin where the plane is located.
  3015. template<class T>
  3016. class Plane
  3017. {
  3018. public:
  3019. Vector3<T> N;
  3020. T D;
  3021. Plane() : D(0) {}
  3022. // Normals must already be normalized
  3023. Plane(const Vector3<T>& n, T d) : N(n), D(d) {}
  3024. Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {}
  3025. // construct from a point on the plane and the normal
  3026. Plane(const Vector3<T>& p, const Vector3<T>& n) : N(n), D(-(p * n)) {}
  3027. // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane).
  3028. T TestSide(const Vector3<T>& p) const
  3029. {
  3030. return (N.Dot(p)) + D;
  3031. }
  3032. Plane<T> Flipped() const
  3033. {
  3034. return Plane(-N, -D);
  3035. }
  3036. void Flip()
  3037. {
  3038. N = -N;
  3039. D = -D;
  3040. }
  3041. bool operator==(const Plane<T>& rhs) const
  3042. {
  3043. return (this->D == rhs.D && this->N == rhs.N);
  3044. }
  3045. };
  3046. typedef Plane<float> Planef;
  3047. typedef Plane<double> Planed;
  3048. //-----------------------------------------------------------------------------------
  3049. // ***** ScaleAndOffset2D
  3050. struct ScaleAndOffset2D
  3051. {
  3052. Vector2f Scale;
  3053. Vector2f Offset;
  3054. ScaleAndOffset2D(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f)
  3055. : Scale(sx, sy), Offset(ox, oy)
  3056. { }
  3057. };
  3058. //-----------------------------------------------------------------------------------
  3059. // ***** FovPort
  3060. // FovPort describes Field Of View (FOV) of a viewport.
  3061. // This class has values for up, down, left and right, stored in
  3062. // tangent of the angle units to simplify calculations.
  3063. //
  3064. // As an example, for a standard 90 degree vertical FOV, we would
  3065. // have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
  3066. //
  3067. // CreateFromRadians/Degrees helper functions can be used to
  3068. // access FOV in different units.
  3069. // ***** FovPort
  3070. struct FovPort
  3071. {
  3072. float UpTan;
  3073. float DownTan;
  3074. float LeftTan;
  3075. float RightTan;
  3076. FovPort ( float sideTan = 0.0f ) :
  3077. UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) { }
  3078. FovPort ( float u, float d, float l, float r ) :
  3079. UpTan(u), DownTan(d), LeftTan(l), RightTan(r) { }
  3080. // C-interop support: FovPort <-> ovrFovPort (implementation in OVR_CAPI.cpp).
  3081. FovPort(const ovrFovPort &src)
  3082. : UpTan(src.UpTan), DownTan(src.DownTan), LeftTan(src.LeftTan), RightTan(src.RightTan)
  3083. { }
  3084. operator ovrFovPort () const
  3085. {
  3086. ovrFovPort result;
  3087. result.LeftTan = LeftTan;
  3088. result.RightTan = RightTan;
  3089. result.UpTan = UpTan;
  3090. result.DownTan = DownTan;
  3091. return result;
  3092. }
  3093. static FovPort CreateFromRadians(float horizontalFov, float verticalFov)
  3094. {
  3095. FovPort result;
  3096. result.UpTan = tanf ( verticalFov * 0.5f );
  3097. result.DownTan = tanf ( verticalFov * 0.5f );
  3098. result.LeftTan = tanf ( horizontalFov * 0.5f );
  3099. result.RightTan = tanf ( horizontalFov * 0.5f );
  3100. return result;
  3101. }
  3102. static FovPort CreateFromDegrees(float horizontalFovDegrees,
  3103. float verticalFovDegrees)
  3104. {
  3105. return CreateFromRadians(DegreeToRad(horizontalFovDegrees),
  3106. DegreeToRad(verticalFovDegrees));
  3107. }
  3108. // Get Horizontal/Vertical components of Fov in radians.
  3109. float GetVerticalFovRadians() const { return atanf(UpTan) + atanf(DownTan); }
  3110. float GetHorizontalFovRadians() const { return atanf(LeftTan) + atanf(RightTan); }
  3111. // Get Horizontal/Vertical components of Fov in degrees.
  3112. float GetVerticalFovDegrees() const { return RadToDegree(GetVerticalFovRadians()); }
  3113. float GetHorizontalFovDegrees() const { return RadToDegree(GetHorizontalFovRadians()); }
  3114. // Compute maximum tangent value among all four sides.
  3115. float GetMaxSideTan() const
  3116. {
  3117. return OVRMath_Max(OVRMath_Max(UpTan, DownTan), OVRMath_Max(LeftTan, RightTan));
  3118. }
  3119. static ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort tanHalfFov )
  3120. {
  3121. float projXScale = 2.0f / ( tanHalfFov.LeftTan + tanHalfFov.RightTan );
  3122. float projXOffset = ( tanHalfFov.LeftTan - tanHalfFov.RightTan ) * projXScale * 0.5f;
  3123. float projYScale = 2.0f / ( tanHalfFov.UpTan + tanHalfFov.DownTan );
  3124. float projYOffset = ( tanHalfFov.UpTan - tanHalfFov.DownTan ) * projYScale * 0.5f;
  3125. ScaleAndOffset2D result;
  3126. result.Scale = Vector2f(projXScale, projYScale);
  3127. result.Offset = Vector2f(projXOffset, projYOffset);
  3128. // Hey - why is that Y.Offset negated?
  3129. // It's because a projection matrix transforms from world coords with Y=up,
  3130. // whereas this is from NDC which is Y=down.
  3131. return result;
  3132. }
  3133. // Converts Fov Tan angle units to [-1,1] render target NDC space
  3134. Vector2f TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle)
  3135. {
  3136. ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(*this);
  3137. return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset;
  3138. }
  3139. // Compute per-channel minimum and maximum of Fov.
  3140. static FovPort Min(const FovPort& a, const FovPort& b)
  3141. {
  3142. FovPort fov( OVRMath_Min( a.UpTan , b.UpTan ),
  3143. OVRMath_Min( a.DownTan , b.DownTan ),
  3144. OVRMath_Min( a.LeftTan , b.LeftTan ),
  3145. OVRMath_Min( a.RightTan, b.RightTan ) );
  3146. return fov;
  3147. }
  3148. static FovPort Max(const FovPort& a, const FovPort& b)
  3149. {
  3150. FovPort fov( OVRMath_Max( a.UpTan , b.UpTan ),
  3151. OVRMath_Max( a.DownTan , b.DownTan ),
  3152. OVRMath_Max( a.LeftTan , b.LeftTan ),
  3153. OVRMath_Max( a.RightTan, b.RightTan ) );
  3154. return fov;
  3155. }
  3156. };
  3157. } // Namespace OVR
  3158. #if defined(_MSC_VER)
  3159. #pragma warning(pop)
  3160. #endif
  3161. #endif