Recent Testing: Mul and Inv work for 3x3 matrix, more testing coming
check www.happypedestrian.com/lwjgl/matrixop.html for current status
This commit is contained in:
parent
9e58e87ce9
commit
0078885178
|
@ -288,14 +288,21 @@ void DstMatrix::writeRecord()
|
||||||
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)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
int src_index = 0;
|
||||||
|
|
||||||
for (int c = 0; c < side; c++)
|
for (int c = 0; c < side; c++)
|
||||||
{
|
{
|
||||||
if (c == col_omit) continue;
|
if (c == col_omit)
|
||||||
|
{ src_index += side;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int r = 0; r < side; r++)
|
for (int r = 0; r < side; r++)
|
||||||
{
|
{
|
||||||
if (r == row_omit) continue;
|
if (r == row_omit)
|
||||||
dst[index++] = src[r + c * side];
|
{ src_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dst[index++] = src[src_index++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,20 +318,21 @@ float determinant (const float * matrix , int side)
|
||||||
det = matrix[0] * matrix[3] - matrix[2] * matrix[1];
|
det = matrix[0] * matrix[3] - matrix[2] * matrix[1];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int temp_side = side - 1;
|
int temp_side = side - 1; // the dimensions of the sub matrix
|
||||||
float temp_matrix [temp_side * temp_side];
|
float temp_matrix [temp_side * temp_side]; // hold a sub matrix of this matrix
|
||||||
float sign = 1;
|
bool sign_pos = 1; // the sign is positive
|
||||||
|
|
||||||
for (int i = 0; i < side; i++)
|
for (int row = 0; row < side; row++)
|
||||||
{
|
{
|
||||||
// get a sub matrix by eliminating the ith row and the 0th column
|
// get a sub matrix by eliminating the 0th col and the specified row
|
||||||
subMatrix(matrix, side, temp_matrix, 0, i);
|
subMatrix(matrix, side, temp_matrix, 0, row);
|
||||||
|
|
||||||
// add to the determinant sign * [a]i0 * [M]i0
|
// add to the determinant sign * [a]i0 * [M]i0
|
||||||
det += sign * matrix[i] * determinant (temp_matrix, temp_side);
|
det += ((sign_pos) ? matrix[row] :
|
||||||
|
-matrix[row]) * determinant (temp_matrix, temp_side);
|
||||||
|
|
||||||
// alternate the sign
|
// alternate the sign
|
||||||
sign = (sign == 1) ? -1 : 1;
|
sign_pos ^= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,25 +77,41 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpDire
|
||||||
int temp_side = source.width-1;
|
int temp_side = source.width-1;
|
||||||
float temp_matrix [temp_side*temp_side];
|
float temp_matrix [temp_side*temp_side];
|
||||||
|
|
||||||
for (int i = 0; i < source.elements; i++)
|
for (int i = 0; i < source.elements; i++)
|
||||||
{
|
{
|
||||||
sourceRecord = source.nextRecord();
|
sourceRecord = source.nextRecord();
|
||||||
destRecord = dest.nextRecord();
|
destRecord = dest.nextRecord();
|
||||||
|
|
||||||
float det = determinant(sourceRecord, sourceWidth);
|
// calculate the determinant
|
||||||
|
float det = determinant(sourceRecord, source.width);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf("Determinant: %f\n", det);
|
||||||
|
#endif
|
||||||
|
|
||||||
float sign;
|
float sign;
|
||||||
|
|
||||||
for (int c = 0; c < source.width; c++)
|
for (int col = 0; col < source.width; col++)
|
||||||
{
|
{
|
||||||
sign = (c & 1) ? 1.0f : -1.0f;
|
/*
|
||||||
|
Maintain sign:
|
||||||
|
|
||||||
|
+ - + - ...
|
||||||
|
- + - + ..
|
||||||
|
+ - + - ..
|
||||||
|
- + - + ..
|
||||||
|
: : : : \
|
||||||
|
*/
|
||||||
|
|
||||||
|
sign = (col & 1) ? -1.0f : 1.0f;
|
||||||
|
|
||||||
for (int r = 0; r < source.width; r++)
|
for (int row = 0; row < source.height; row++)
|
||||||
{
|
{
|
||||||
// get the sub matrix
|
// get the sub matrix
|
||||||
subMatrix(sourceRecord, source.width, temp_matrix, c, r);
|
subMatrix(sourceRecord, source.width, temp_matrix, col, row);
|
||||||
|
|
||||||
// transpose the result
|
// transpose the result
|
||||||
destRecord[r + c * source.width]
|
destRecord[col + row * source.height]
|
||||||
= (sign / det) * determinant(temp_matrix, temp_side);
|
= (sign / det) * determinant(temp_matrix, temp_side);
|
||||||
|
|
||||||
// swap signs
|
// swap signs
|
||||||
|
|
|
@ -38,12 +38,16 @@
|
||||||
* @author cix_foo <cix_foo@users.sourceforge.net>
|
* @author cix_foo <cix_foo@users.sourceforge.net>
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.h"
|
#include "org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.h"
|
||||||
#include "MatrixOpCommon.h"
|
#include "MatrixOpCommon.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe
|
* Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe
|
||||||
* Method: execute
|
* Method: execute
|
||||||
|
@ -82,20 +86,36 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpSafe
|
||||||
sourceRecord = source.nextRecord();
|
sourceRecord = source.nextRecord();
|
||||||
destRecord = dest.nextRecord();
|
destRecord = dest.nextRecord();
|
||||||
|
|
||||||
float det = determinant(sourceRecord, sourceWidth);
|
// calculate the determinant
|
||||||
|
float det = determinant(sourceRecord, source.width);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf("Determinant: %f\n", det);
|
||||||
|
#endif
|
||||||
|
|
||||||
float sign;
|
float sign;
|
||||||
|
|
||||||
for (int c = 0; c < source.width; c++)
|
for (int col = 0; col < source.width; col++)
|
||||||
{
|
{
|
||||||
sign = (c & 1) ? 1.0f : -1.0f;
|
/*
|
||||||
|
Maintain sign:
|
||||||
|
|
||||||
|
+ - + - ...
|
||||||
|
- + - + ..
|
||||||
|
+ - + - ..
|
||||||
|
- + - + ..
|
||||||
|
: : : : \
|
||||||
|
*/
|
||||||
|
|
||||||
|
sign = (col & 1) ? -1.0f : 1.0f;
|
||||||
|
|
||||||
for (int r = 0; r < source.width; r++)
|
for (int row = 0; row < source.height; row++)
|
||||||
{
|
{
|
||||||
// get the sub matrix
|
// get the sub matrix
|
||||||
subMatrix(sourceRecord, source.width, temp_matrix, c, r);
|
subMatrix(sourceRecord, source.width, temp_matrix, col, row);
|
||||||
|
|
||||||
// transpose the result
|
// transpose the result
|
||||||
destRecord[r + c * source.width]
|
destRecord[col + row * source.height]
|
||||||
= (sign / det) * determinant(temp_matrix, temp_side);
|
= (sign / det) * determinant(temp_matrix, temp_side);
|
||||||
|
|
||||||
// swap signs
|
// swap signs
|
||||||
|
|
|
@ -91,33 +91,45 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpMultiply_00024MatrixOpDi
|
||||||
// check out discussions envolving ordering
|
// check out discussions envolving ordering
|
||||||
|
|
||||||
|
|
||||||
left.rewind();
|
left.rewind();
|
||||||
for (int i = 0; i < leftElements; i++)
|
for (int i = 0; i < left.elements; i++)
|
||||||
{
|
{
|
||||||
leftRecord = left.nextRecord();
|
leftRecord = left.nextRecord();
|
||||||
|
|
||||||
right.rewind();
|
right.rewind();
|
||||||
for (int j = 0; j < rightElements; j++)
|
for (int j = 0; j < right.elements; j++)
|
||||||
{
|
{
|
||||||
rightRecord = right.nextRecord();
|
rightRecord = right.nextRecord();
|
||||||
destRecord = dest.nextRecord();
|
destRecord = dest.nextRecord();
|
||||||
|
|
||||||
memset(destRecord, 0, dest.width * dest.height * sizeof(jfloat));
|
// zero the elements of the destination matrix
|
||||||
|
for (int d = 0; d < dest.width * dest.height; d++)
|
||||||
|
destRecord[d] = 0;
|
||||||
|
|
||||||
|
// loop through each column of the right matrix
|
||||||
|
int rightCell = 0;
|
||||||
for (int rightCol = 0; rightCol < right.width; rightCol++)
|
for (int rightCol = 0; rightCol < right.width; rightCol++)
|
||||||
{
|
{
|
||||||
for (int leftIndex = 0; leftIndex < left.width*left.height; leftIndex++)
|
// [RxC] * [RxC]
|
||||||
|
// dest has same height as left
|
||||||
|
// dest has same width as right
|
||||||
|
|
||||||
|
int leftCell = 0;
|
||||||
|
for (int leftCol = 0; leftCol < left.width; leftCol++)
|
||||||
{
|
{
|
||||||
destRecord[i % dest.height] += leftRecord[i] * rightRecord[i / leftSourceHeight];
|
for (int leftRow = 0; leftRow < left.height; leftRow++)
|
||||||
|
{
|
||||||
|
destRecord[leftRow] += rightRecord[rightCell] * leftRecord[leftCell++];
|
||||||
|
}
|
||||||
|
rightCell ++ ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rightRecord = &rightRecord[right.height];
|
//rightRecord = &rightRecord[right.height];
|
||||||
destRecord = &destRecord[dest.height];
|
destRecord = &destRecord[dest.height];
|
||||||
|
|
||||||
}
|
}
|
||||||
dest.writeRecord();
|
dest.writeRecord();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.h"
|
#include "org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.h"
|
||||||
#include "MatrixOpCommon.h"
|
#include "MatrixOpCommon.h"
|
||||||
|
@ -91,26 +92,39 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpMultiply_00024MatrixOpSa
|
||||||
|
|
||||||
|
|
||||||
left.rewind();
|
left.rewind();
|
||||||
for (int i = 0; i < leftElements; i++)
|
for (int i = 0; i < left.elements; i++)
|
||||||
{
|
{
|
||||||
leftRecord = left.nextRecord();
|
leftRecord = left.nextRecord();
|
||||||
|
|
||||||
right.rewind();
|
right.rewind();
|
||||||
for (int j = 0; j < rightElements; j++)
|
for (int j = 0; j < right.elements; j++)
|
||||||
{
|
{
|
||||||
rightRecord = right.nextRecord();
|
rightRecord = right.nextRecord();
|
||||||
destRecord = dest.nextRecord();
|
destRecord = dest.nextRecord();
|
||||||
|
|
||||||
memset(destRecord, 0, dest.width * dest.height * sizeof(jfloat));
|
// zero the elements of the destination matrix
|
||||||
|
for (int d = 0; d < dest.width * dest.height; d++)
|
||||||
|
destRecord[d] = 0;
|
||||||
|
|
||||||
|
// loop through each column of the right matrix
|
||||||
|
int rightCell = 0;
|
||||||
for (int rightCol = 0; rightCol < right.width; rightCol++)
|
for (int rightCol = 0; rightCol < right.width; rightCol++)
|
||||||
{
|
{
|
||||||
for (int leftIndex = 0; leftIndex < left.width*left.height; leftIndex++)
|
// [RxC] * [RxC]
|
||||||
|
// dest has same height as left
|
||||||
|
// dest has same width as right
|
||||||
|
|
||||||
|
int leftCell = 0;
|
||||||
|
for (int leftCol = 0; leftCol < left.width; leftCol++)
|
||||||
{
|
{
|
||||||
destRecord[i % dest.height] += leftRecord[i] * rightRecord[i / leftSourceHeight];
|
for (int leftRow = 0; leftRow < left.height; leftRow++)
|
||||||
|
{
|
||||||
|
destRecord[leftRow] += rightRecord[rightCell] * leftRecord[leftCell++];
|
||||||
|
}
|
||||||
|
rightCell ++ ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rightRecord = &rightRecord[right.height];
|
//rightRecord = &rightRecord[right.height];
|
||||||
destRecord = &destRecord[dest.height];
|
destRecord = &destRecord[dest.height];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue