summaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/Kernel/OVR_Math.cpp
blob: d971d65ad8d3eb8e2fe8044991884b634a3fe517 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/************************************************************************************

Filename    :   OVR_Math.h
Content     :   Implementation of 3D primitives such as vectors, matrices.
Created     :   September 4, 2012
Authors     :   Andrew Reisse, Michael Antonov, Anna Yershova

Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.

Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.

*************************************************************************************/

#include "OVR_Math.h"
#include "OVR_Log.h"

#include <float.h>


namespace OVR {


//-------------------------------------------------------------------------------------
// ***** Math


// Single-precision Math constants class.
const float Math<float>::Pi      = 3.1415926f;
const float Math<float>::TwoPi   = 3.1415926f * 2;
const float Math<float>::PiOver2 = 3.1415926f / 2.0f;
const float Math<float>::PiOver4 = 3.1415926f / 4.0f;
const float Math<float>::E       = 2.7182818f;

const float Math<float>::MaxValue			= FLT_MAX;
const float Math<float>::MinPositiveValue	= FLT_MIN;

const float Math<float>::RadToDegreeFactor	= 360.0f / Math<float>::TwoPi;
const float Math<float>::DegreeToRadFactor	= Math<float>::TwoPi / 360.0f;

const float Math<float>::Tolerance			= 0.00001f;
const float Math<float>::SingularityRadius	= 0.0000001f; // Use for Gimbal lock numerical problems

// Double-precision Math constants class.
const double Math<double>::Pi      = 3.14159265358979;
const double Math<double>::TwoPi   = 3.14159265358979 * 2;
const double Math<double>::PiOver2 = 3.14159265358979 / 2.0;
const double Math<double>::PiOver4 = 3.14159265358979 / 4.0;
const double Math<double>::E       = 2.71828182845905;

const double Math<double>::MaxValue				= DBL_MAX;
const double Math<double>::MinPositiveValue		= DBL_MIN;

const double Math<double>::RadToDegreeFactor	= 360.0 / Math<double>::TwoPi;
const double Math<double>::DegreeToRadFactor	= Math<double>::TwoPi / 360.0;

const double Math<double>::Tolerance			= 0.00001;
const double Math<double>::SingularityRadius	= 0.000000000001; // Use for Gimbal lock numerical problems



//-------------------------------------------------------------------------------------
// ***** Matrix4f


Matrix4f Matrix4f::LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
{
    Vector3f z = (eye - at).Normalized();  // Forward
    Vector3f x = up.Cross(z).Normalized(); // Right
    Vector3f y = z.Cross(x);

    Matrix4f m(x.x,  x.y,  x.z,  -(x.Dot(eye)),
               y.x,  y.y,  y.z,  -(y.Dot(eye)),
               z.x,  z.y,  z.z,  -(z.Dot(eye)),
               0,    0,    0,    1 );
    return m;
}

Matrix4f Matrix4f::LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
{
    Vector3f z = (at - eye).Normalized();  // Forward
    Vector3f x = up.Cross(z).Normalized(); // Right
    Vector3f y = z.Cross(x);

    Matrix4f m(x.x,  x.y,  x.z,  -(x.Dot(eye)),
               y.x,  y.y,  y.z,  -(y.Dot(eye)),
               z.x,  z.y,  z.z,  -(z.Dot(eye)),
               0,    0,    0,    1 ); 
    return m;
}


Matrix4f Matrix4f::PerspectiveLH(float yfov, float aspect, float znear, float zfar)
{
    Matrix4f m;
    float    tanHalfFov = tan(yfov * 0.5f);

    m.M[0][0] = 1.0f / (aspect * tanHalfFov);
    m.M[1][1] = 1.0f / tanHalfFov;
    m.M[2][2] = zfar / (zfar - znear);
    m.M[3][2] = 1.0f;
    m.M[2][3] = (zfar * znear) / (znear - zfar);
    m.M[3][3] = 0.0f;

    // Note: Post-projection matrix result assumes Left-Handed coordinate system,
    //       with Y up, X right and Z forward. This supports positive z-buffer values.
    return m;
}


Matrix4f Matrix4f::PerspectiveRH(float yfov, float aspect, float znear, float zfar)
{
    Matrix4f m;
    float    tanHalfFov = tan(yfov * 0.5f);
  
    m.M[0][0] = 1.0f / (aspect * tanHalfFov);
    m.M[1][1] = 1.0f / tanHalfFov;
    m.M[2][2] = zfar / (znear - zfar);
   // m.M[2][2] = zfar / (zfar - znear);
    m.M[3][2] = -1.0f;
    m.M[2][3] = (zfar * znear) / (znear - zfar);
    m.M[3][3] = 0.0f;

    // Note: Post-projection matrix result assumes Left-Handed coordinate system,    
    //       with Y up, X right and Z forward. This supports positive z-buffer values.
    // This is the case even for RHS cooridnate input.       
    return m;
}

Matrix4f Matrix4f::Ortho2D(float w, float h)
{
    Matrix4f m;
    m.M[0][0] = 2.0f/w;
    m.M[1][1] = -2.0f/h;
    m.M[0][3] = -1.0;
    m.M[1][3] = 1.0;
    m.M[2][2] = 0;
    return m;
}


} // Namespace OVR