mirror of
https://github.com/scummvm/scummvm.git
synced 2026-05-21 05:40:43 +00:00
MATH: added few GLU helpers
This commit is contained in:
@@ -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 ¢er, 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
@@ -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 ¢er, const Vector3d &up);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+148
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user