MATH: added few GLU helpers

This commit is contained in:
Pawel Kolodziejski
2014-07-10 07:27:18 +02:00
parent 6625530d88
commit 46a91377d8
4 changed files with 338 additions and 6 deletions
+74
View File
@@ -0,0 +1,74 @@
/* ResidualVM - A 3D game interpreter
*
* ResidualVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "math/glmath.h"
namespace Math {
// function based on gluPerspective from Mesa 5.0 glu GPLv2+ licensed sources
Matrix4 makePerspectiveMatrix(double fovy, double aspect, double zNear, double zFar) {
double xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * M_PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
return makeFrustumMatrix(xmin, xmax, ymin, ymax, zNear, zFar);
}
Matrix4 makeFrustumMatrix(double left, double right, double bottom, double top, double zNear, double zFar) {
Matrix4 proj;
proj(0, 0) = (2.0f * zNear) / (right - left);
proj(1, 1) = (2.0f * zNear) / (top - bottom);
proj(2, 0) = (right + left) / (right - left);
proj(2, 1) = (top + bottom) / (top - bottom);
proj(2, 2) = -(zFar + zNear) / (zFar - zNear);
proj(2, 3) = -1.0f;
proj(3, 2) = -(2.0f * zFar * zNear) / (zFar - zNear);
proj(3, 3) = 0.0f;
return proj;
}
Matrix4 makeLookAtMatrix(const Vector3d &eye, const Vector3d &center, const Vector3d &up) {
Vector3d f = (center - eye).getNormalized();
Vector3d u = up.getNormalized();
Vector3d s = Vector3d::crossProduct(f, u).getNormalized();
u = Vector3d::crossProduct(s, f);
Math::Matrix4 look;
look(0, 0) = s.x();
look(1, 0) = s.y();
look(2, 0) = s.z();
look(0, 1) = u.x();
look(1, 1) = u.y();
look(2, 1) = u.z();
look(0, 2) = -f.x();
look(1, 2) = -f.y();
look(2, 2) = -f.z();
look(3, 3) = 1.0;
return look;
}
}
+109
View File
@@ -0,0 +1,109 @@
/* ResidualVM - A 3D game interpreter
*
* ResidualVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef MATH_GLMATH_H
#define MATH_GLMATH_H
#include "math/vector4d.h"
#include "math/matrix4.h"
namespace Math {
// function based on gluProject from Mesa 5.0 glu GPLv2+ licensed sources
template<typename T>
bool gluMathProject(Vector3d obj, const T model[16], const T proj[16], const int viewport[4], Vector3d &win) {
Vector4d in, out;
Matrix4 modelMatrix, projMatrix;
in.set(obj.x(), obj.y(), obj.z(), 1.0);
for (int i = 0; i < 4; i++) {
modelMatrix(0, i) = model[0 * 4 + i];
modelMatrix(1, i) = model[1 * 4 + i];
modelMatrix(2, i) = model[2 * 4 + i];
modelMatrix(3, i) = model[3 * 4 + i];
projMatrix(0, i) = proj[0 * 4 + i];
projMatrix(1, i) = proj[1 * 4 + i];
projMatrix(2, i) = proj[2 * 4 + i];
projMatrix(3, i) = proj[3 * 4 + i];
}
out = modelMatrix.transform(in);
in = projMatrix.transform(out);
if (in.w() == 0.0)
return false;
in.x() /= in.w();
in.y() /= in.w();
in.z() /= in.w();
win.x() = viewport[0] + (1 + in.x()) * viewport[2] / 2;
win.y() = viewport[1] + (1 + in.y()) * viewport[3] / 2;
win.z() = (1 + in.z()) / 2;
return true;
}
// function based on gluUnProject from Mesa 5.0 glu GPLv2+ licensed sources
template<typename T>
bool gluMathUnProject(Vector3d win, const T model[16], const T proj[16], const int viewport[4], Vector3d &obj) {
Matrix4 A;
Matrix4 modelMatrix, projMatrix;
Vector4d in, out;
in.x() = (win.x() - viewport[0]) * 2 / viewport[2] - 1.0;
in.y() = (win.y() - viewport[1]) * 2 / viewport[3] - 1.0;
in.z() = 2 * win.z() - 1.0;
in.w() = 1.0;
for (int i = 0; i < 4; i++) {
modelMatrix(0, i) = model[0 * 4 + i];
modelMatrix(1, i) = model[1 * 4 + i];
modelMatrix(2, i) = model[2 * 4 + i];
modelMatrix(3, i) = model[3 * 4 + i];
projMatrix(0, i) = proj[0 * 4 + i];
projMatrix(1, i) = proj[1 * 4 + i];
projMatrix(2, i) = proj[2 * 4 + i];
projMatrix(3, i) = proj[3 * 4 + i];
}
A = modelMatrix * projMatrix;
A.inverse();
out = A.transform(in);
if (out.w() == 0.0)
return false;
obj.x() = out.x() / out.w();
obj.y() = out.y() / out.w();
obj.z() = out.x() / out.w();
return true;
}
Matrix4 makePerspectiveMatrix(double fovy, double aspect, double zNear, double zFar);
Matrix4 makeFrustumMatrix(double left, double right, double bottom, double top, double zNear, double zFar);
Matrix4 makeLookAtMatrix(const Vector3d &eye, const Vector3d &center, const Vector3d &up);
}
#endif
+148
View File
@@ -26,6 +26,7 @@
#include "math/rotation3d.h"
#include "math/squarematrix.h"
#include "math/vector3d.h"
#include "math/vector4d.h"
#include "math/matrix3.h"
namespace Math {
@@ -93,6 +94,153 @@ public:
return result;
}
inline Vector4d transform(const Vector4d &v) const {
Vector4d result;
const float *d1 = getData();
const float *d2 = v.getData();
float *r = result.getData();
for (int i = 0; i < 4; i++) {
r[i] = d2[0] * d1[0 * 4 + i] +
d2[1] * d1[1 * 4 + i] +
d2[2] * d1[2 * 4 + i] +
d2[3] * d1[3 * 4 + i];
}
return result;
}
inline bool inverse() const {
Matrix<4, 4> invMatrix;
float *inv = invMatrix.getData();
float *m = (float *)getData();
inv[0] = m[5] * m[10] * m[15] -
m[5] * m[11] * m[14] -
m[9] * m[6] * m[15] +
m[9] * m[7] * m[14] +
m[13] * m[6] * m[11] -
m[13] * m[7] * m[10];
inv[4] = -m[4] * m[10] * m[15] +
m[4] * m[11] * m[14] +
m[8] * m[6] * m[15] -
m[8] * m[7] * m[14] -
m[12] * m[6] * m[11] +
m[12] * m[7] * m[10];
inv[8] = m[4] * m[9] * m[15] -
m[4] * m[11] * m[13] -
m[8] * m[5] * m[15] +
m[8] * m[7] * m[13] +
m[12] * m[5] * m[11] -
m[12] * m[7] * m[9];
inv[12] = -m[4] * m[9] * m[14] +
m[4] * m[10] * m[13] +
m[8] * m[5] * m[14] -
m[8] * m[6] * m[13] -
m[12] * m[5] * m[10] +
m[12] * m[6] * m[9];
inv[1] = -m[1] * m[10] * m[15] +
m[1] * m[11] * m[14] +
m[9] * m[2] * m[15] -
m[9] * m[3] * m[14] -
m[13] * m[2] * m[11] +
m[13] * m[3] * m[10];
inv[5] = m[0] * m[10] * m[15] -
m[0] * m[11] * m[14] -
m[8] * m[2] * m[15] +
m[8] * m[3] * m[14] +
m[12] * m[2] * m[11] -
m[12] * m[3] * m[10];
inv[9] = -m[0] * m[9] * m[15] +
m[0] * m[11] * m[13] +
m[8] * m[1] * m[15] -
m[8] * m[3] * m[13] -
m[12] * m[1] * m[11] +
m[12] * m[3] * m[9];
inv[13] = m[0] * m[9] * m[14] -
m[0] * m[10] * m[13] -
m[8] * m[1] * m[14] +
m[8] * m[2] * m[13] +
m[12] * m[1] * m[10] -
m[12] * m[2] * m[9];
inv[2] = m[1] * m[6] * m[15] -
m[1] * m[7] * m[14] -
m[5] * m[2] * m[15] +
m[5] * m[3] * m[14] +
m[13] * m[2] * m[7] -
m[13] * m[3] * m[6];
inv[6] = -m[0] * m[6] * m[15] +
m[0] * m[7] * m[14] +
m[4] * m[2] * m[15] -
m[4] * m[3] * m[14] -
m[12] * m[2] * m[7] +
m[12] * m[3] * m[6];
inv[10] = m[0] * m[5] * m[15] -
m[0] * m[7] * m[13] -
m[4] * m[1] * m[15] +
m[4] * m[3] * m[13] +
m[12] * m[1] * m[7] -
m[12] * m[3] * m[5];
inv[14] = -m[0] * m[5] * m[14] +
m[0] * m[6] * m[13] +
m[4] * m[1] * m[14] -
m[4] * m[2] * m[13] -
m[12] * m[1] * m[6] +
m[12] * m[2] * m[5];
inv[3] = -m[1] * m[6] * m[11] +
m[1] * m[7] * m[10] +
m[5] * m[2] * m[11] -
m[5] * m[3] * m[10] -
m[9] * m[2] * m[7] +
m[9] * m[3] * m[6];
inv[7] = m[0] * m[6] * m[11] -
m[0] * m[7] * m[10] -
m[4] * m[2] * m[11] +
m[4] * m[3] * m[10] +
m[8] * m[2] * m[7] -
m[8] * m[3] * m[6];
inv[11] = -m[0] * m[5] * m[11] +
m[0] * m[7] * m[9] +
m[4] * m[1] * m[11] -
m[4] * m[3] * m[9] -
m[8] * m[1] * m[7] +
m[8] * m[3] * m[5];
inv[15] = m[0] * m[5] * m[10] -
m[0] * m[6] * m[9] -
m[4] * m[1] * m[10] +
m[4] * m[2] * m[9] +
m[8] * m[1] * m[6] -
m[8] * m[2] * m[5];
float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (int i = 0; i < 16; i++) {
m[i] = inv[i] * det;
}
return true;
}
};
typedef Matrix<4, 4> Matrix4;
+7 -6
View File
@@ -1,19 +1,20 @@
MODULE := math
MODULE_OBJS := \
aabb.o \
angle.o \
frustum.o \
glmath.o \
line2d.o \
line3d.o \
matrix3.o \
matrix4.o \
line3d.o \
line2d.o \
plane.o \
quat.o \
rect2d.o \
vector2d.o \
vector3d.o \
vector4d.o \
aabb.o \
frustum.o \
plane.o
vector4d.o
# Include common rules
include $(srcdir)/rules.mk