common: add 4x4 (from mesa) and 2x2 matrix inverse
This commit is contained in:
parent
6344e0723c
commit
8a4d1ff218
|
|
@ -7,6 +7,7 @@ set(BSPUTIL_SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/common/bspfile.cc
|
${CMAKE_SOURCE_DIR}/common/bspfile.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/bsputils.cc
|
${CMAKE_SOURCE_DIR}/common/bsputils.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/mathlib.cc
|
${CMAKE_SOURCE_DIR}/common/mathlib.cc
|
||||||
|
${CMAKE_SOURCE_DIR}/common/qvec.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/polylib.cc
|
${CMAKE_SOURCE_DIR}/common/polylib.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/log.cc
|
${CMAKE_SOURCE_DIR}/common/log.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/threads.cc
|
${CMAKE_SOURCE_DIR}/common/threads.cc
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* Copyright (C) 2017 Eric Wasylishen
|
||||||
|
|
||||||
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
See file, 'COPYING', for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common/qvec.hh>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
|
||||||
|
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice including the dates of first publication and
|
||||||
|
* either this permission notice or a reference to
|
||||||
|
* http://oss.sgi.com/projects/FreeB/
|
||||||
|
* shall be included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* Except as contained in this notice, the name of Silicon Graphics, Inc.
|
||||||
|
* shall not be used in advertising or otherwise to promote the sale, use or
|
||||||
|
* other dealings in this Software without prior written authorization from
|
||||||
|
* Silicon Graphics, Inc.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
** Invert 4x4 matrix.
|
||||||
|
** Contributed by David Moore (See Mesa bug #6748)
|
||||||
|
*/
|
||||||
|
static bool gluInvertMatrixd(const double m[16], double invOut[16])
|
||||||
|
{
|
||||||
|
double inv[16], det;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
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 (i = 0; i < 16; i++)
|
||||||
|
invOut[i] = inv[i] * det;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmat4x4d qv::invert(const qmat4x4d &input, bool *ok)
|
||||||
|
{
|
||||||
|
double flat_in[16];
|
||||||
|
double flat_out[16];
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
for (int j=0; j<4; j++)
|
||||||
|
flat_in[4*i+j] = input[i][j];
|
||||||
|
|
||||||
|
*ok = gluInvertMatrixd(flat_in, flat_out);
|
||||||
|
if (!*ok)
|
||||||
|
return qmat4x4d();
|
||||||
|
|
||||||
|
qmat4x4d result;
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
for (int j=0; j<4; j++)
|
||||||
|
result[i][j] = flat_out[4*i+j];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmat4x4f qv::invert(const qmat4x4f &input, bool *ok)
|
||||||
|
{
|
||||||
|
return qmat4x4f(qv::invert(qmat4x4d(input), ok));
|
||||||
|
}
|
||||||
|
|
||||||
|
qmat2x2f qv::invert(const qmat2x2f &m, bool *ok)
|
||||||
|
{
|
||||||
|
float a = m[0][0];
|
||||||
|
float b = m[1][0];
|
||||||
|
float c = m[0][1];
|
||||||
|
float d = m[1][1];
|
||||||
|
|
||||||
|
float det = a*d - b*c;
|
||||||
|
if (det == 0) {
|
||||||
|
*ok = false;
|
||||||
|
return qmat2x2f();
|
||||||
|
}
|
||||||
|
|
||||||
|
*ok = true;
|
||||||
|
qmat2x2f result {
|
||||||
|
d, -c, // col 0
|
||||||
|
-b, a // col 1
|
||||||
|
};
|
||||||
|
|
||||||
|
return result * (1.0f/det);
|
||||||
|
}
|
||||||
|
|
@ -267,6 +267,15 @@ public:
|
||||||
this->m_cols[i] = other.m_cols[i];
|
this->m_cols[i] = other.m_cols[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casting from another matrix type of the same size
|
||||||
|
*/
|
||||||
|
template <class T2>
|
||||||
|
qmat(const qmat<M, N, T2> &other) {
|
||||||
|
for (int i=0; i<N; i++)
|
||||||
|
m_cols[i] = qvec<M, T>(other[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// initializer list
|
// initializer list
|
||||||
qmat(std::initializer_list<T> list) {
|
qmat(std::initializer_list<T> list) {
|
||||||
assert(list.size() == M*N);
|
assert(list.size() == M*N);
|
||||||
|
|
@ -324,6 +333,16 @@ public:
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multiplication by a scalar
|
||||||
|
|
||||||
|
qmat<M,N,T> operator*(const T scalar) const {
|
||||||
|
qmat<M,N,T> res;
|
||||||
|
for (int j=0; j<N; j++) {
|
||||||
|
res[j] = this->m_cols[j] * scalar;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using qmat2x2f = qmat<2, 2, float>;
|
using qmat2x2f = qmat<2, 2, float>;
|
||||||
|
|
@ -351,4 +370,11 @@ using qmat4x2d = qmat<4, 2, double>;
|
||||||
using qmat4x3d = qmat<4, 3, double>;
|
using qmat4x3d = qmat<4, 3, double>;
|
||||||
using qmat4x4d = qmat<4, 4, double>;
|
using qmat4x4d = qmat<4, 4, double>;
|
||||||
|
|
||||||
|
namespace qv {
|
||||||
|
qmat4x4f invert(const qmat4x4f &input, bool *ok);
|
||||||
|
qmat4x4d invert(const qmat4x4d &input, bool *ok);
|
||||||
|
|
||||||
|
qmat2x2f invert(const qmat2x2f &input, bool *ok);
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __COMMON_QVEC_HH__ */
|
#endif /* __COMMON_QVEC_HH__ */
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ set(LIGHT_SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/common/bspfile.cc
|
${CMAKE_SOURCE_DIR}/common/bspfile.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/cmdlib.cc
|
${CMAKE_SOURCE_DIR}/common/cmdlib.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/mathlib.cc
|
${CMAKE_SOURCE_DIR}/common/mathlib.cc
|
||||||
|
${CMAKE_SOURCE_DIR}/common/qvec.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/mesh.cc
|
${CMAKE_SOURCE_DIR}/common/mesh.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/log.cc
|
${CMAKE_SOURCE_DIR}/common/log.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/threads.cc
|
${CMAKE_SOURCE_DIR}/common/threads.cc
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ set(VIS_SOURCES
|
||||||
state.cc
|
state.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/cmdlib.cc
|
${CMAKE_SOURCE_DIR}/common/cmdlib.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/mathlib.cc
|
${CMAKE_SOURCE_DIR}/common/mathlib.cc
|
||||||
|
${CMAKE_SOURCE_DIR}/common/qvec.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/polylib.cc
|
${CMAKE_SOURCE_DIR}/common/polylib.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/bsputils.cc
|
${CMAKE_SOURCE_DIR}/common/bsputils.cc
|
||||||
${CMAKE_SOURCE_DIR}/common/bspfile.cc
|
${CMAKE_SOURCE_DIR}/common/bspfile.cc
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue