rev |
line source |
nuclear@1
|
1 /************************************************************************************
|
nuclear@1
|
2
|
nuclear@1
|
3 Filename : OVR_Math.h
|
nuclear@1
|
4 Content : Implementation of 3D primitives such as vectors, matrices.
|
nuclear@1
|
5 Created : September 4, 2012
|
nuclear@1
|
6 Authors : Andrew Reisse, Michael Antonov
|
nuclear@1
|
7
|
nuclear@1
|
8 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
|
nuclear@1
|
9
|
nuclear@1
|
10 Use of this software is subject to the terms of the Oculus license
|
nuclear@1
|
11 agreement provided at the time of installation or download, or which
|
nuclear@1
|
12 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@1
|
13
|
nuclear@1
|
14 *************************************************************************************/
|
nuclear@1
|
15
|
nuclear@1
|
16 #include "OVR_Math.h"
|
nuclear@1
|
17
|
nuclear@1
|
18 #include <float.h>
|
nuclear@1
|
19
|
nuclear@1
|
20 namespace OVR {
|
nuclear@1
|
21
|
nuclear@1
|
22
|
nuclear@1
|
23 //-------------------------------------------------------------------------------------
|
nuclear@1
|
24 // ***** Math
|
nuclear@1
|
25
|
nuclear@1
|
26
|
nuclear@1
|
27 // Single-precision Math constants class.
|
nuclear@1
|
28 const float Math<float>::Pi = 3.1415926f;
|
nuclear@1
|
29 const float Math<float>::TwoPi = 3.1415926f * 2;
|
nuclear@1
|
30 const float Math<float>::PiOver2 = 3.1415926f / 2.0f;
|
nuclear@1
|
31 const float Math<float>::PiOver4 = 3.1415926f / 4.0f;
|
nuclear@1
|
32 const float Math<float>::E = 2.7182818f;
|
nuclear@1
|
33
|
nuclear@1
|
34 const float Math<float>::MaxValue = FLT_MAX;
|
nuclear@1
|
35 const float Math<float>::MinPositiveValue = FLT_MIN;
|
nuclear@1
|
36
|
nuclear@1
|
37 const float Math<float>::RadToDegreeFactor = 360.0f / Math<float>::TwoPi;
|
nuclear@1
|
38 const float Math<float>::DegreeToRadFactor = Math<float>::TwoPi / 360.0f;
|
nuclear@1
|
39
|
nuclear@1
|
40 const float Math<float>::Tolerance = 0.00001f;
|
nuclear@1
|
41 const float Math<float>::SingularityRadius = 0.0000001f; // Use for Gimbal lock numerical problems
|
nuclear@1
|
42
|
nuclear@1
|
43
|
nuclear@1
|
44 // Double-precision Math constants class.
|
nuclear@1
|
45 const double Math<double>::Pi = 3.14159265358979;
|
nuclear@1
|
46 const double Math<double>::TwoPi = 3.14159265358979 * 2;
|
nuclear@1
|
47 const double Math<double>::PiOver2 = 3.14159265358979 / 2.0;
|
nuclear@1
|
48 const double Math<double>::PiOver4 = 3.14159265358979 / 4.0;
|
nuclear@1
|
49 const double Math<double>::E = 2.71828182845905;
|
nuclear@1
|
50
|
nuclear@1
|
51 const double Math<double>::MaxValue = DBL_MAX;
|
nuclear@1
|
52 const double Math<double>::MinPositiveValue = DBL_MIN;
|
nuclear@1
|
53
|
nuclear@1
|
54 const double Math<double>::RadToDegreeFactor = 360.0 / Math<double>::TwoPi;
|
nuclear@1
|
55 const double Math<double>::DegreeToRadFactor = Math<double>::TwoPi / 360.0;
|
nuclear@1
|
56
|
nuclear@1
|
57 const double Math<double>::Tolerance = 0.00001;
|
nuclear@1
|
58 const double Math<double>::SingularityRadius = 0.000000000001; // Use for Gimbal lock numerical problems
|
nuclear@1
|
59
|
nuclear@1
|
60
|
nuclear@1
|
61
|
nuclear@1
|
62 //-------------------------------------------------------------------------------------
|
nuclear@1
|
63 // ***** Matrix4f
|
nuclear@1
|
64
|
nuclear@1
|
65
|
nuclear@1
|
66 Matrix4f Matrix4f::LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
|
nuclear@1
|
67 {
|
nuclear@1
|
68 Vector3f z = (eye - at).Normalized(); // Forward
|
nuclear@1
|
69 Vector3f x = up.Cross(z).Normalized(); // Right
|
nuclear@1
|
70 Vector3f y = z.Cross(x);
|
nuclear@1
|
71
|
nuclear@1
|
72 Matrix4f m(x.x, x.y, x.z, -(x * eye),
|
nuclear@1
|
73 y.x, y.y, y.z, -(y * eye),
|
nuclear@1
|
74 z.x, z.y, z.z, -(z * eye),
|
nuclear@1
|
75 0, 0, 0, 1 );
|
nuclear@1
|
76 return m;
|
nuclear@1
|
77 }
|
nuclear@1
|
78
|
nuclear@1
|
79 Matrix4f Matrix4f::LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
|
nuclear@1
|
80 {
|
nuclear@1
|
81 Vector3f z = (at - eye).Normalized(); // Forward
|
nuclear@1
|
82 Vector3f x = up.Cross(z).Normalized(); // Right
|
nuclear@1
|
83 Vector3f y = z.Cross(x);
|
nuclear@1
|
84
|
nuclear@1
|
85 Matrix4f m(x.x, x.y, x.z, -(x * eye),
|
nuclear@1
|
86 y.x, y.y, y.z, -(y * eye),
|
nuclear@1
|
87 z.x, z.y, z.z, -(z * eye),
|
nuclear@1
|
88 0, 0, 0, 1 );
|
nuclear@1
|
89 return m;
|
nuclear@1
|
90 }
|
nuclear@1
|
91
|
nuclear@1
|
92
|
nuclear@1
|
93 Matrix4f Matrix4f::PerspectiveLH(float yfov, float aspect, float znear, float zfar)
|
nuclear@1
|
94 {
|
nuclear@1
|
95 Matrix4f m;
|
nuclear@1
|
96 float tanHalfFov = tan(yfov * 0.5f);
|
nuclear@1
|
97
|
nuclear@1
|
98 m.M[0][0] = 1.0f / (aspect * tanHalfFov);
|
nuclear@1
|
99 m.M[1][1] = 1.0f / tanHalfFov;
|
nuclear@1
|
100 m.M[2][2] = zfar / (zfar - znear);
|
nuclear@1
|
101 m.M[3][2] = 1.0f;
|
nuclear@1
|
102 m.M[2][3] = (zfar * znear) / (znear - zfar);
|
nuclear@1
|
103 m.M[3][3] = 0.0f;
|
nuclear@1
|
104
|
nuclear@1
|
105 // Note: Post-projection matrix result assumes Left-Handed coordinate system,
|
nuclear@1
|
106 // with Y up, X right and Z forward. This supports positive z-buffer values.
|
nuclear@1
|
107 return m;
|
nuclear@1
|
108 }
|
nuclear@1
|
109
|
nuclear@1
|
110
|
nuclear@1
|
111 Matrix4f Matrix4f::PerspectiveRH(float yfov, float aspect, float znear, float zfar)
|
nuclear@1
|
112 {
|
nuclear@1
|
113 Matrix4f m;
|
nuclear@1
|
114 float tanHalfFov = tan(yfov * 0.5f);
|
nuclear@1
|
115
|
nuclear@1
|
116 m.M[0][0] = 1.0f / (aspect * tanHalfFov);
|
nuclear@1
|
117 m.M[1][1] = 1.0f / tanHalfFov;
|
nuclear@1
|
118 m.M[2][2] = zfar / (znear - zfar);
|
nuclear@1
|
119 // m.M[2][2] = zfar / (zfar - znear);
|
nuclear@1
|
120 m.M[3][2] = -1.0f;
|
nuclear@1
|
121 m.M[2][3] = (zfar * znear) / (znear - zfar);
|
nuclear@1
|
122 m.M[3][3] = 0.0f;
|
nuclear@1
|
123
|
nuclear@1
|
124 // Note: Post-projection matrix result assumes Left-Handed coordinate system,
|
nuclear@1
|
125 // with Y up, X right and Z forward. This supports positive z-buffer values.
|
nuclear@1
|
126 // This is the case even for RHS cooridnate input.
|
nuclear@1
|
127 return m;
|
nuclear@1
|
128 }
|
nuclear@1
|
129
|
nuclear@1
|
130
|
nuclear@1
|
131 /*
|
nuclear@1
|
132 OffCenterLH
|
nuclear@1
|
133
|
nuclear@1
|
134 2*zn/(r-l) 0 0 0
|
nuclear@1
|
135 0 2*zn/(t-b) 0 0
|
nuclear@1
|
136 (l+r)/(l-r) (t+b)/(b-t) zf/(zf-zn) 1
|
nuclear@1
|
137 0 0 zn*zf/(zn-zf) 0
|
nuclear@1
|
138
|
nuclear@1
|
139 */
|
nuclear@1
|
140
|
nuclear@1
|
141
|
nuclear@1
|
142 Matrix4f Matrix4f::Ortho2D(float w, float h)
|
nuclear@1
|
143 {
|
nuclear@1
|
144 Matrix4f m;
|
nuclear@1
|
145 m.M[0][0] = 2.0f/w;
|
nuclear@1
|
146 m.M[1][1] = -2.0f/h;
|
nuclear@1
|
147 m.M[0][3] = -1.0;
|
nuclear@1
|
148 m.M[1][3] = 1.0;
|
nuclear@1
|
149 m.M[2][2] = 0;
|
nuclear@1
|
150 return m;
|
nuclear@1
|
151 }
|
nuclear@1
|
152
|
nuclear@1
|
153 }
|