Optimised INVERT cases for Orthogonal Matricies (Rotations)
This commit is contained in:
parent
77e0186cb7
commit
fa665cce33
|
@ -90,9 +90,7 @@ MatrixSrc::MatrixSrc ( jint addr, jint s,
|
||||||
record = new float[width * height];
|
record = new float[width * height];
|
||||||
|
|
||||||
// vectors do not need to be transposed
|
// vectors do not need to be transposed
|
||||||
transpose = (t == JNI_TRUE)
|
transpose = (t == JNI_TRUE) && (w != 1) && (h != 1);
|
||||||
&& (w != 1)
|
|
||||||
&& (h != 1);
|
|
||||||
|
|
||||||
if (transpose && (width != height))
|
if (transpose && (width != height))
|
||||||
// only need temp storage for transpose if the matrix is not square
|
// only need temp storage for transpose if the matrix is not square
|
||||||
|
@ -244,8 +242,9 @@ void MatrixDst::createBuffer()
|
||||||
float * MatrixDst::nextMatrix()
|
float * MatrixDst::nextMatrix()
|
||||||
{
|
{
|
||||||
record_offset = &record_offset[stride];
|
record_offset = &record_offset[stride];
|
||||||
|
int alignment = ((unsigned int)(record_offset)) & FLOAT_ALIGNMENT;
|
||||||
|
|
||||||
if ((((unsigned int)(record_offset)) & FLOAT_ALIGNMENT) || transpose || record_buffered)
|
if (transpose || record_buffered || alignment)
|
||||||
{
|
{
|
||||||
last_record_in_temp = JNI_TRUE;
|
last_record_in_temp = JNI_TRUE;
|
||||||
return record;
|
return record;
|
||||||
|
@ -276,7 +275,7 @@ void MatrixDst::writeComplete()
|
||||||
}
|
}
|
||||||
else if (transpose)
|
else if (transpose)
|
||||||
{
|
{
|
||||||
transposeMatrix(record, (float *) record_offset, width, height);
|
transposeMatrix(record, (float *) &record_offset[0], width, height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
memcpy (record_offset, record, record_size * sizeof(jfloat));
|
memcpy (record_offset, record, record_size * sizeof(jfloat));
|
||||||
|
|
|
@ -9,11 +9,31 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Utility Functions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define FLOAT_ALIGNMENT 0x00000003
|
#define FLOAT_ALIGNMENT 0x00000003
|
||||||
|
|
||||||
|
// 23 bit mantisa on a float (we need error for checking if two nums are equal)
|
||||||
|
// for now use error of 1/2^18, this could be refined up to 1/2^22 if needed
|
||||||
|
#define FLOATING_POINT_ERROR (1.0f/262144.0f)
|
||||||
|
|
||||||
|
// check if two numbers are approximately equal, used when floating point errors
|
||||||
|
// occur. Should NEVER check to see if two floats are identical
|
||||||
|
|
||||||
|
inline bool approxEqual(float a, float b)
|
||||||
|
{
|
||||||
|
a -= b;
|
||||||
|
a = (a < 0) ? -a: a;
|
||||||
|
return (a < FLOATING_POINT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
float determinant (const float * matrix , int side);
|
float determinant (const float * matrix , int side);
|
||||||
void subMatrix (const float * src, int side, float * dst , int col_omit, int row_omit);
|
void subMatrix (const float * src, int side, float * dst , int col_omit, int row_omit);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Matrix
|
// Matrix
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect.h"
|
#include "org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect.h"
|
||||||
#include "MatrixOpCommon.h"
|
#include "MatrixOpCommon.h"
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect
|
* Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect
|
||||||
* Method: execute
|
* Method: execute
|
||||||
|
@ -62,6 +65,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpDire
|
||||||
jboolean transposeDest
|
jboolean transposeDest
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if (transposeSource == transposeDest)
|
||||||
|
{
|
||||||
|
transposeSource = JNI_FALSE;
|
||||||
|
transposeDest = JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// We are under the assumption that sourceWidth == sourceHeight and the matrix
|
// We are under the assumption that sourceWidth == sourceHeight and the matrix
|
||||||
// defined within is invertable
|
// defined within is invertable
|
||||||
|
|
||||||
|
@ -86,9 +96,51 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpDire
|
||||||
float det = determinant(srcMatrix, source.width);
|
float det = determinant(srcMatrix, source.width);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("Determinant: %f\n", det);
|
printf("Matrix Determinant: %f\n", det);
|
||||||
|
printf("Matrix Determinant - 1 = %f\n", det -1);
|
||||||
|
printf("FLOATING POINT ERROR: %f\n", FLOATING_POINT_ERROR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// use approxEqual to avoid direct comparisons
|
||||||
|
if (approxEqual(det, 1.0f) ||
|
||||||
|
approxEqual(det, -1.0f))
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf("Matrix is Orthogonal\n");
|
||||||
|
#endif
|
||||||
|
/* this matrix is orthogonal
|
||||||
|
|
||||||
|
since inv(M) * M = I
|
||||||
|
when orthogonal
|
||||||
|
trans(M) * M = I
|
||||||
|
|
||||||
|
proper orthogonal
|
||||||
|
inv(M) = trans(M)
|
||||||
|
improper orthogonal
|
||||||
|
inv(M) = -trans(M)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (approxEqual(det, 1))
|
||||||
|
{
|
||||||
|
// proper orthogonal
|
||||||
|
int srcIndex = 0;
|
||||||
|
for (int col = 0; col < source.width; col++)
|
||||||
|
for (int row = 0; row < source.height; row++)
|
||||||
|
destMatrix[col + row * source.width] = srcMatrix[srcIndex++];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// improper orthogonal
|
||||||
|
int srcIndex = 0;
|
||||||
|
for (int col = 0; col < source.width; col++)
|
||||||
|
for (int row = 0; row < source.height; row++)
|
||||||
|
destMatrix[col + row * source.width] = -srcMatrix[srcIndex++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
float sign;
|
float sign;
|
||||||
|
|
||||||
for (int col = 0; col < source.width; col++)
|
for (int col = 0; col < source.width; col++)
|
||||||
|
@ -119,6 +171,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpDire
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
dest.writeComplete();
|
dest.writeComplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,14 @@
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.h"
|
||||||
|
#include "MatrixOpCommon.h"
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include "org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.h"
|
|
||||||
#include "MatrixOpCommon.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe
|
* Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe
|
||||||
* Method: execute
|
* Method: execute
|
||||||
|
@ -68,6 +67,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpSafe
|
||||||
jboolean transposeDest
|
jboolean transposeDest
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (transposeSource == transposeDest)
|
||||||
|
{
|
||||||
|
transposeSource = JNI_FALSE;
|
||||||
|
transposeDest = JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// We are under the assumption that sourceWidth == sourceHeight and the matrix
|
// We are under the assumption that sourceWidth == sourceHeight and the matrix
|
||||||
// defined within is invertable
|
// defined within is invertable
|
||||||
|
|
||||||
|
@ -90,9 +96,50 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpSafe
|
||||||
float det = determinant(srcMatrix, source.width);
|
float det = determinant(srcMatrix, source.width);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("Determinant: %f\n", det);
|
printf("Matrix Determinant: %f\n", det);
|
||||||
|
printf("Matrix Determinant - 1: %f\n", det-1);
|
||||||
|
printf("FLOATING POINT ERROR: %f\n", FLOATING_POINT_ERROR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// use approxEqual to avoid direct comparisons
|
||||||
|
if (approxEqual(det,1) || approxEqual(det, -1))
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf("Matrix is Orthogonal\n");
|
||||||
|
#endif
|
||||||
|
/* this matrix is orthogonal
|
||||||
|
|
||||||
|
since inv(M) * M = I
|
||||||
|
when orthogonal
|
||||||
|
trans(M) * M = I
|
||||||
|
|
||||||
|
proper orthogonal
|
||||||
|
inv(M) = trans(M)
|
||||||
|
improper orthogonal
|
||||||
|
inv(M) = -trans(M)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (approxEqual(det, 1))
|
||||||
|
{
|
||||||
|
// proper orthogonal
|
||||||
|
int srcIndex = 0;
|
||||||
|
for (int col = 0; col < source.width; col++)
|
||||||
|
for (int row = 0; row < source.height; row++)
|
||||||
|
destMatrix[col + row * source.width] = srcMatrix[srcIndex++];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// improper orthogonal
|
||||||
|
int srcIndex = 0;
|
||||||
|
for (int col = 0; col < source.width; col++)
|
||||||
|
for (int row = 0; row < source.height; row++)
|
||||||
|
destMatrix[col + row * source.width] = -srcMatrix[srcIndex++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
float sign;
|
float sign;
|
||||||
|
|
||||||
for (int col = 0; col < source.width; col++)
|
for (int col = 0; col < source.width; col++)
|
||||||
|
@ -123,6 +170,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpSafe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
dest.writeComplete();
|
dest.writeComplete();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue