Core/Misc: update g3dlite lib (#2904)

* Core/Misc: update g3dlite lib

* update

Co-authored-by: Francesco Borzì <borzifrancesco@gmail.com>
This commit is contained in:
Viste
2020-07-30 13:35:45 +03:00
committed by GitHub
parent 91bbbf08eb
commit fcaf91b8b2
183 changed files with 13258 additions and 8022 deletions

View File

@@ -1,16 +1,16 @@
/**
@file Matrix4.cpp
\file G3D/source/Matrix4.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
\maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-10-02
@edited 2010-01-29
\created 2003-10-02
\edited 2012-02-19
*/
#include "G3D/platform.h"
#include "G3D/Matrix4.h"
#include "G3D/Matrix3.h"
#include "G3D/Matrix2.h"
#include "G3D/Vector4.h"
#include "G3D/Vector3.h"
#include "G3D/BinaryInput.h"
@@ -24,11 +24,11 @@ namespace G3D {
Matrix4::Matrix4(const Any& any) {
any.verifyName("Matrix4");
any.verifyNameBeginsWith("Matrix4", "CFrame", "CoordinateFrame");
any.verifyType(Any::ARRAY);
const std::string& name = toLower(any.name());
if (name == "matrix4") {
const std::string& name = any.name();
if (name == "Matrix4") {
any.verifySize(16);
for (int r = 0; r < 4; ++r) {
@@ -36,26 +36,43 @@ Matrix4::Matrix4(const Any& any) {
elt[r][c] = any[r * 4 + c];
}
}
} else if (name == "matrix4::scale") {
} else if (name == "Matrix4::scale") {
if (any.size() == 1) {
*this = scale(any[0].number());
*this = scale(any[0].floatValue());
} else if (any.size() == 3) {
*this = scale(any[0], any[1], any[2]);
} else {
any.verify(false, "Matrix4::scale() takes either 1 or 3 arguments");
}
} else if (name == "matrix4::translation") {
} else if (name == "Matrix4::rollDegrees") {
any.verifySize(1);
*this = rollDegrees(any[0].floatValue());
} else if (name == "Matrix4::yawDegrees") {
any.verifySize(1);
*this = yawDegrees(any[0].floatValue());
} else if (name == "Matrix4::pitchDegrees") {
any.verifySize(1);
*this = pitchDegrees(any[0].floatValue());
} else if (name == "Matrix4::translation") {
if (any.size() == 3) {
*this = translation(any[0], any[1], any[2]);
} else {
any.verify(false, "Matrix4::translation() takes either 1 or 3 arguments");
} } else {
any.verify(false, "Matrix4::translation() requires 3 arguments");
}
} else if (name == "Matrix4::diagonal") {
any.verifySize(4);
*this = diagonal(any[0], any[1], any[2], any[3]);
} else if (name == "Matrix4::identity") {
*this = identity();
} else if (beginsWith(name, "CFrame") || beginsWith(name, "CoordinateFrame")) {
*this = CFrame(any);
} else {
any.verify(false, "Expected Matrix4 constructor");
}
}
Matrix4::operator Any() const {
Any Matrix4::toAny() const {
Any any(Any::ARRAY, "Matrix4");
any.resize(16);
for (int r = 0; r < 4; ++r) {
@@ -121,6 +138,12 @@ Matrix3 Matrix4::upper3x3() const {
}
Matrix2 Matrix4::upper2x2() const {
return Matrix2(elt[0][0], elt[0][1],
elt[1][0], elt[1][1]);
}
Matrix4 Matrix4::orthogonalProjection(
const class Rect2D& rect,
float nearval,
@@ -164,59 +187,59 @@ Matrix4 Matrix4::orthogonalProjection(
Matrix4 Matrix4::perspectiveProjection(
float left,
float right,
float bottom,
float top,
float nearval,
float farval,
float upDirection) {
double left,
double right,
double bottom,
double top,
double nearval,
double farval,
float upDirection) {
float x, y, a, b, c, d;
double x, y, a, b, c, d;
x = (2.0f*nearval) / (right-left);
y = (2.0f*nearval) / (top-bottom);
x = (2.0*nearval) / (right-left);
y = (2.0*nearval) / (top-bottom);
a = (right+left) / (right-left);
b = (top+bottom) / (top-bottom);
if (farval >= finf()) {
if (farval >= inf()) {
// Infinite view frustum
c = -1.0f;
d = -2.0f * nearval;
c = -1.0;
d = -2.0 * nearval;
} else {
c = -(farval+nearval) / (farval-nearval);
d = -(2.0f*farval*nearval) / (farval-nearval);
d = -(2.0*farval*nearval) / (farval-nearval);
}
debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");
debugAssertM(abs(upDirection) == 1.0, "upDirection must be -1 or +1");
y *= upDirection;
b *= upDirection;
return Matrix4(
x, 0, a, 0,
0, y, b, 0,
0, 0, c, d,
(float)x, 0, (float)a, 0,
0, (float)y, (float)b, 0,
0, 0, (float)c, (float)d,
0, 0, -1, 0);
}
void Matrix4::getPerspectiveProjectionParameters(
float& left,
float& right,
float& bottom,
float& top,
float& nearval,
float& farval,
double& left,
double& right,
double& bottom,
double& top,
double& nearval,
double& farval,
float upDirection) const {
debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");
float x = elt[0][0];
float y = elt[1][1] * upDirection;
float a = elt[0][2];
float b = elt[1][2] * upDirection;
float c = elt[2][2];
float d = elt[2][3];
double x = elt[0][0];
double y = elt[1][1] * upDirection;
double a = elt[0][2];
double b = elt[1][2] * upDirection;
double c = elt[2][2];
double d = elt[2][3];
// Verify that this really is a projection matrix
debugAssertM(elt[3][2] == -1, "Not a projection matrix");
@@ -232,18 +255,18 @@ void Matrix4::getPerspectiveProjectionParameters(
if (c == -1) {
farval = finf();
nearval = -d / 2.0f;
nearval = -d / 2.0;
} else {
nearval = d * ((c - 1.0f) / (c + 1.0f) - 1.0f) / (-2.0f * (c - 1.0f) / (c + 1.0f));
farval = nearval * ((c - 1.0f) / (c + 1.0f));
nearval = d * ((c - 1.0) / (c + 1.0) - 1.0) / (-2.0 * (c - 1.0) / (c + 1.0));
farval = nearval * ((c - 1.0) / (c + 1.0));
}
left = (a - 1.0f) * nearval / x;
right = 2.0f * nearval / x + left;
left = (a - 1.0) * nearval / x;
right = 2.0 * nearval / x + left;
bottom = (b - 1.0f) * nearval / y;
top = 2.0f * nearval / y + bottom;
bottom = (b - 1.0) * nearval / y;
top = 2.0 * nearval / y + bottom;
}
@@ -401,7 +424,7 @@ bool Matrix4::operator==(const Matrix4& other) const {
float Matrix4::determinant() const {
// Determinant is the dot product of the first row and the first row
// of cofactors (i.e. the first col of the adjoint matrix)
return cofactor().row(0).dot(row(0));
return cofactor().row(0).dot(row(0));
}
@@ -417,14 +440,14 @@ Matrix4 Matrix4::inverse() const {
// Determinant is the dot product of the first row and the first row
// of cofactors (i.e. the first col of the adjoint matrix)
float det = A.column(0).dot(row(0));
float det = A.column(0).dot(row(0));
return A * (1.0f / det);
return A * (1.0f / det);
}
Matrix4 Matrix4::cofactor() const {
Matrix4 out;
Matrix4 out;
// We'll use i to incrementally compute -1 ^ (r+c)
int i = 1;
@@ -482,19 +505,19 @@ float Matrix4::subDeterminant(int excludeRow, int excludeCol) const {
CoordinateFrame Matrix4::approxCoordinateFrame() const {
CoordinateFrame cframe;
CoordinateFrame cframe;
for (int r = 0; r < 3; ++r) {
for (int c = 0; c < 3; ++c) {
cframe.rotation[r][c] = elt[r][c];
}
cframe.translation[r] = elt[r][3];
}
for (int r = 0; r < 3; ++r) {
for (int c = 0; c < 3; ++c) {
cframe.rotation[r][c] = elt[r][c];
}
cframe.translation[r] = elt[r][3];
}
// Ensure that the rotation matrix is orthonormal
cframe.rotation.orthonormalize();
// Ensure that the rotation matrix is orthonormal
cframe.rotation.orthonormalize();
return cframe;
return cframe;
}
@@ -517,12 +540,138 @@ void Matrix4::deserialize(class BinaryInput& b) {
std::string Matrix4::toString() const {
return G3D::format("[%g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g]",
elt[0][0], elt[0][1], elt[0][2], elt[0][3],
elt[1][0], elt[1][1], elt[1][2], elt[1][3],
elt[2][0], elt[2][1], elt[2][2], elt[2][3],
elt[3][0], elt[3][1], elt[3][2], elt[3][3]);
elt[0][0], elt[0][1], elt[0][2], elt[0][3],
elt[1][0], elt[1][1], elt[1][2], elt[1][3],
elt[2][0], elt[2][1], elt[2][2], elt[2][3],
elt[3][0], elt[3][1], elt[3][2], elt[3][3]);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
Matrix4float64::Matrix4float64(const Matrix4& m) {
for (int r = 0; r < 4; ++r) {
for (int c = 0; c < 4; ++c) {
elt[r][c] = m[r][c];
}
}
}
Matrix4float64::Matrix4float64() {
for (int r = 0; r < 4; ++r) {
for (int c = 0; c < 4; ++c) {
elt[r][c] = 0.0;
}
}
}
Matrix4float64::Matrix4float64
(double r1c1, double r1c2, double r1c3, double r1c4,
double r2c1, double r2c2, double r2c3, double r2c4,
double r3c1, double r3c2, double r3c3, double r3c4,
double r4c1, double r4c2, double r4c3, double r4c4) {
elt[0][0] = r1c1; elt[0][1] = r1c2; elt[0][2] = r1c3; elt[0][3] = r1c4;
elt[1][0] = r2c1; elt[1][1] = r2c2; elt[1][2] = r2c3; elt[1][3] = r2c4;
elt[2][0] = r3c1; elt[2][1] = r3c2; elt[2][2] = r3c3; elt[2][3] = r3c4;
elt[3][0] = r4c1; elt[3][1] = r4c2; elt[3][2] = r4c3; elt[3][3] = r4c4;
}
const Matrix4float64& Matrix4float64::identity() {
static Matrix4float64 m(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
return m;
}
const Matrix4float64& Matrix4float64::zero() {
static Matrix4float64 m;
return m;
}
bool Matrix4float64::operator!=(const Matrix4float64& other) const {
return ! (*this == other);
}
bool Matrix4float64::operator==(const Matrix4float64& other) const {
// If the bit patterns are identical, they must be
// the same matrix. If not, they *might* still have
// equal elements due to floating point weirdness.
if (memcmp(this, &other, sizeof(Matrix4float64)) == 0) {
return true;
}
for (int r = 0; r < 4; ++r) {
for (int c = 0; c < 4; ++c) {
if (elt[r][c] != other.elt[r][c]) {
return false;
}
}
}
return true;
}
Vector4 Matrix4float64::operator*(const Vector4& vector) const {
Vector4 result;
for (int r = 0; r < 4; ++r) {
double sum = 0;
for (int c = 0; c < 4; ++c) {
sum += elt[r][c] * vector[c];
}
result[r] = (float)sum;
}
return result;
}
Matrix4float64 Matrix4float64::perspectiveProjection(
double left,
double right,
double bottom,
double top,
double nearval,
double farval,
float upDirection) {
double x, y, a, b, c, d;
x = (2.0*nearval) / (right-left);
y = (2.0*nearval) / (top-bottom);
a = (right+left) / (right-left);
b = (top+bottom) / (top-bottom);
if (farval >= inf()) {
// Infinite view frustum
c = -1.0;
d = -2.0 * nearval;
} else {
c = -(farval+nearval) / (farval-nearval);
d = -(2.0*farval*nearval) / (farval-nearval);
}
debugAssertM(abs(upDirection) == 1.0, "upDirection must be -1 or +1");
y *= upDirection;
b *= upDirection;
return Matrix4float64(
(float)x, 0, (float)a, 0,
0, (float)y, (float)b, 0,
0, 0, (float)c, (float)d,
0, 0, -1, 0);
}
} // namespace