diff --git a/src/native/win32/MatrixOpCommon.cpp b/src/native/win32/MatrixOpCommon.cpp new file mode 100644 index 00000000..8ca7a229 --- /dev/null +++ b/src/native/win32/MatrixOpCommon.cpp @@ -0,0 +1,332 @@ + +//#include +#include +#include "MatrixOpCommon.h" + +bool Matrix::identicalDataSpaces(Matrix & other) +{ + if (address != other.address) + return JNI_FALSE; + if (stride != other.stride) + return JNI_FALSE; + if ((width * height) != (other.width * other.height)) + return JNI_FALSE; + return JNI_TRUE; +} + +bool Matrix::intersectingDataSpaces(Matrix & other) +{ + char * my_max_address = &address[ stride * elements ]; + char * other_max_address = &other.address[ other.stride * other.elements]; + + if (address >= other.address || address <= other_max_address) return JNI_TRUE; + if (other.address >= address || other.address <= my_max_address) return JNI_TRUE; + return JNI_FALSE; +} + +void Matrix::transposeMatrix(float * src, float * dst, int src_width, int src_height) +{ + // square matrix transpose + if (src_width == src_height) + { + for (int i = 0; i < src_width; i++) + for (int j = 0; j < src_width; j++) + dst[i + src_width * j] = src[j + i * src_width]; + } + // non square matrix transpose + else + { + for (int i = 0; i < src_width; i ++) + for (int j = 0; j < src_height; j++) + dst[i + src_height * j] = src[j + i * src_height]; + } +} + +void Matrix::transposeMatrix(float * mat, int src_width, int src_height) +{ + float temp; + + // square matrix transpose + if (src_width == src_height) + { + for (int col = 0; col < src_width; col++) + { + for (int row = col+1; row < src_height; row++) + { + // swap the two elements + temp = mat [col * src_height + row]; + mat[col * src_height + row] = mat[row * src_width + col]; + mat[row * src_width + col] = temp; + } + } + } + // non square matrix transpose + else + { + transposeMatrix(mat, transpose_record, src_width, src_height); + memcpy(mat, transpose_record, src_width * src_height * sizeof(float)); + } + +} + + +SrcMatrix::SrcMatrix ( jint addr, jint s, + jint w, jint h, + jint e, jboolean t): + Matrix(addr, s, e), + record_offset((char *) addr), + record_size (w*h) +{ + if (t) { + width = h; + height = w; + } + else { + width = w; + height = h; + } + + elements = e; + record = new float[width * height]; + + // vectors do not need to be transposed + transpose = (t == JNI_TRUE) + && (w != 1) + && (h != 1); + + if (transpose && (width != height)) + // only need temp storage for transpose if the matrix is not square + transpose_record = new float[width*height]; + else + transpose_record = 0; + + if (elements == 1) + { + // fool the nextRecord function into returning a value + elements = 2; + nextRecord(); + elements = 1; + } +} + +SrcMatrix::~SrcMatrix() +{ + //cout << "SrcMatrix destructor \n"; + + delete [] record; + + if (transpose_record != 0) + delete [] transpose_record; +} + +float * SrcMatrix::nextRecord() +{ + if (elements > 1) + { + //cout << "Elements: " << elements << "\n"; + //cout << "Address: " << (unsigned int) (record_offset) << "\n"; + + // the record is not properly aligned + if ((unsigned int) (record_offset) & FLOAT_ALIGNMENT) + { + // copy the floats into a buffer so that they are aligned + // on 4 byte margins (not necessary on intel, but a good thing) + + memcpy (record, record_offset, record_size * sizeof(float)); + + if (transpose) + transposeMatrix (record, height, width); + + record_offset = &record_offset[stride]; + current_record_ptr = record; + } + // the record is aligned but it has to be transposed + else if (transpose) + { + transposeMatrix ((float *) (record_offset), record, height, width); + record_offset = &record_offset[stride]; + current_record_ptr = record; + } + // nothing has to be done to the record + else + { + // the floats are aligned in memory + current_record_ptr = (float *) record_offset; + record_offset = &record_offset[stride]; + } + } + + return current_record_ptr; +} + +DstMatrix::DstMatrix (jint addr, jint s, jint w, jint h, jint e, jboolean t): + Matrix(addr, s, e) +{ + width = w; + height = h; + record_size = width * height; + record = new float[record_size]; + + // vectors do not need to be transposed + transpose = (t) && (w != 1) && (h != 1); + + if (transpose) + transpose_record = new float[width*height]; + else + transpose_record = 0; + + data_buffered = JNI_FALSE; + record_buffered = JNI_FALSE; + + record_offset = address - stride; +} + +DstMatrix::~DstMatrix() +{ + //cout << "DstMatrix destructor \n"; + + delete [] record; + if (transpose_record != 0) + delete [] transpose_record; + + // copy back any buffered data + if (data_buffered) + { + char * src = buffer; + char * dest = address; + + for (int i = 0; i < elements; i++) + { + memcpy(dest, src, record_size * sizeof(float)); + src += stride; + dest += stride; + } + + delete [] buffer; + } +} + +void DstMatrix::configureBuffer(SrcMatrix & a, SrcMatrix & b) +{ + + + if (!a.intersectingDataSpaces(b)) + { + // as long as the output only overlays 1 of the sources, and the other + // source only has 1 matrix in it, only a record_buffer is required + if (a.elements == 1 && identicalDataSpaces(b)) + record_buffered = JNI_TRUE; + else if (b.elements == 1 && identicalDataSpaces(a)) + record_buffered = JNI_TRUE; + else + // otherwise all of the output has to be buffered + createBuffer(); + } + else + createBuffer(); +} + +void DstMatrix::configureBuffer(SrcMatrix & a) +{ + if (identicalDataSpaces(a)) + record_buffered = JNI_TRUE; + else if (intersectingDataSpaces(a)) + createBuffer(); +} + +void DstMatrix::createBuffer() +{ + data_buffered = JNI_TRUE; + buffer = new char[ elements * stride ]; + record_offset = buffer - stride; +} + +float * DstMatrix::nextRecord() +{ + record_offset = &record_offset[stride]; + + if ((((unsigned int)(record_offset)) & FLOAT_ALIGNMENT) || transpose || record_buffered) + { + last_record_in_temp = JNI_TRUE; + return record; + } + else + { + last_record_in_temp = JNI_FALSE; + return (float *) record_offset; + } +} + + +void DstMatrix::writeRecord() +{ + if (last_record_in_temp) + { + // 3 reasons why the record would be in temp + // + // 1. The record is not aligned + // 2. The result will need to be transposed + // 3. Direct Mode where result would overlay an operand + + if (((unsigned int)(record_offset)) & FLOAT_ALIGNMENT) + { + if (transpose) + transposeMatrix(record, width, height); + memcpy (record, record_offset, record_size * sizeof(jfloat)); + } + else if (transpose) + { + transposeMatrix(record, (float *) record_offset, width, height); + } + else + memcpy (record_offset, record, record_size * sizeof(jfloat)); + } +} + +/////////////////////////////////////////////////////////////////////////// + +void subMatrix (const float * src, int side, float * dst , int col_omit, int row_omit) +{ + int index = 0; + + for (int c = 0; c < side; c++) + { + if (c == col_omit) continue; + for (int r = 0; r < side; r++) + { + if (r == row_omit) continue; + dst[index++] = src[r + c * side]; + } + } +} + +float determinant (const float * matrix , int side) +{ + // we are assuming for this case that the data is in column major format + + float det = 0; + + if (side == 2) + // your basic cross product + det = matrix[0] * matrix[3] - matrix[2] * matrix[1]; + else + { + int temp_side = side - 1; + float temp_matrix [temp_side * temp_side]; + float sign = 1; + + for (int i = 0; i < side; i++) + { + // get a sub matrix by eliminating the ith row and the 0th column + subMatrix(matrix, side, temp_matrix, 0, i); + + // add to the determinant sign * [a]i0 * [M]i0 + det += sign * matrix[i] * determinant (temp_matrix, temp_side); + + // alternate the sign + sign = (sign == 1) ? -1 : 1; + } + } + + return det; +} diff --git a/src/native/win32/MatrixOpCommon.h b/src/native/win32/MatrixOpCommon.h new file mode 100755 index 00000000..83557ef4 --- /dev/null +++ b/src/native/win32/MatrixOpCommon.h @@ -0,0 +1,91 @@ +/* + * Matrix.h + * + * + * Created by tristan on Sat Aug 24 2002. + * Copyright (c) 2001 __MyCompanyName__. All rights reserved. + * + */ + + + +#define FLOAT_ALIGNMENT 0x00000003 + +float determinant (const float * matrix , int side); +void subMatrix (const float * src, int side, float * dst , int col_omit, int row_omit); + +/////////////////////////////////////////////////////////////////////////////////////// +// Matrix +////////////////////////////////////////////////////////////////////////////////////// + +class Matrix +{ + protected: + float * transpose_record; // to use while transposing the record + + public: + char * address; // the start of the data + jint stride; // the distance between each record + jint width, // the width of the matrix + height, // the height of the matrix + elements; // the number of matricies + jboolean transpose; // whether this matrix is or will be transposed + + Matrix (jint a, jint s, jint e): + address((char *)a), stride(s), elements(e) {} + bool identicalDataSpaces (Matrix & other); + bool intersectingDataSpaces(Matrix & other); + void transposeMatrix(float * src, float * dst, int src_width, int src_height); + void transposeMatrix(float * mat, int src_width, int src_height); +}; + +/////////////////////////////////////////////////////////////////////////////////////// +// Src Matrix +////////////////////////////////////////////////////////////////////////////////////// + +class SrcMatrix: public Matrix +{ + private: + char * record_offset; // the offset of this record in memory + + float * record; // temporary storage to store a fully aligned and transposed + // copy of the record, if the one in memory is not so + float * current_record_ptr; // the address of the memory containing the record last + // returned by the nextRecord() function + jint record_size; // the total floats in each record + + public: + SrcMatrix ( jint address, jint stride, jint width, jint height, jint elements, jboolean transpose); + void rewind() { record_offset = address; } + float * nextRecord(); + ~SrcMatrix(); +}; + +/////////////////////////////////////////////////////////////////////////////////////// +// Dst Matrix +////////////////////////////////////////////////////////////////////////////////////// + +class DstMatrix: public Matrix +{ + char * record_offset; // the offset of the record in memory + + jboolean data_buffered; // if all of the data has to be buffered + char * buffer; // a buffer used when data_buffered + + jboolean last_record_in_temp; + jboolean record_buffered; // if only a single record is buffered + float * record; // to store data if source is unaligned + + jint record_size; + + public: + DstMatrix (jint address, jint stride, jint width, jint height, jint elements, jboolean transpose); + void configureBuffer(SrcMatrix & a, SrcMatrix & b); + void configureBuffer(SrcMatrix & a); + void createBuffer(); + float * nextRecord(); + void writeRecord(); + ~DstMatrix(); +}; + + diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect.cpp index 96036b50..8f241be4 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect.cpp @@ -1,75 +1,101 @@ -/* - * Copyright (c) 2002 Light Weight Java Game Library Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'Light Weight Java Game Library' nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * $Id$ - * - * Win32 math library. - * - * @author cix_foo - * @version $Revision$ - */ - -#include -#include "org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect.h" -/* - * Class: org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect - * Method: execute - * Signature: (IIIIIZIIIIIZIIZ)V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpAdd_00024MatrixOpDirect_execute - ( - JNIEnv * env, - jobject obj, - jint leftSourceAddress, - jint leftSourceStride, - jint leftElements, - jint leftSourceWidth, - jint leftSourceHeight, - jboolean transposeLeftSource, - jint rightSourceAddress, - jint rightSourceStride, - jint rightElements, - jint rightSourceWidth, - jint rightSourceHeight, - jboolean transposeRightSource, - jint destAddress, - jint destStride, - jboolean transposeDest - ) -{ - float * leftSource = (float *) leftSourceAddress; - float * rightSource = (float *) rightSourceAddress; - float * dest = (float *) destAddress; -} +/* + * Copyright (c) 2002 Light Weight Java Game Library Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * $Id$ + * + * Win32 math library. + * + * @author cix_foo + * @version $Revision$ + */ + +#include +#include "org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect.h" +#include "MatrixOpCommon.h" +/* + * Class: org_lwjgl_Math_MatrixOpAdd_MatrixOpDirect + * Method: execute + * Signature: (IIIIIZIIIIIZIIZ)V + */ +JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpAdd_00024MatrixOpDirect_execute + ( + JNIEnv * env, + jobject obj, + jint leftSourceAddress, + jint leftSourceStride, + jint leftElements, + jint leftSourceWidth, + jint leftSourceHeight, + jboolean transposeLeftSource, + jint rightSourceAddress, + jint rightSourceStride, + jint rightElements, + jint rightSourceWidth, + jint rightSourceHeight, + jboolean transposeRightSource, + jint destAddress, + jint destStride, + jboolean transposeDest + ) +{ + SrcMatrix left (leftSourceAddress, leftSourceStride, + leftSourceWidth, leftSourceHeight, leftElements, transposeLeftSource); + SrcMatrix right (rightSourceAddress, leftSourceStride, + rightSourceWidth, rightSourceHeight, rightElements, transposeRightSource); + DstMatrix dest (destAddress, destStride, + left.width, left.height, left.elements * right.elements, transposeDest); + + dest.configureBuffer(left, right); + + float * leftRecord, * rightRecord, * destRecord; + + left.rewind(); + for (int i = 0; i < left.elements; i++) + { + leftRecord = left.nextRecord(); + + right.rewind(); + for (int j = 0; j < right.elements; j++) + { + rightRecord = right.nextRecord(); + destRecord = dest.nextRecord(); + + for (int k = (dest.width * dest.height) - 1; k >= 0; k--) + destRecord[k] = leftRecord[k] + rightRecord[k]; + + dest.writeRecord(); + } + } + +} diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpSafe.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpSafe.cpp index 68175de8..1406ec50 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpSafe.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpAdd_MatrixOpSafe.cpp @@ -41,6 +41,7 @@ #include #include "org_lwjgl_Math_MatrixOpAdd_MatrixOpSafe.h" +#include "MatrixOpCommon.h" /* * Class: org_lwjgl_Math_MatrixOpAdd_MatrixOpSafe * Method: execute @@ -67,9 +68,33 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpAdd_00024MatrixOpSafe_ex jboolean transposeDest ) { - float * leftSource = (float *) leftSourceAddress; - float * rightSource = (float *) rightSourceAddress; - float * dest = (float *) destAddress; + SrcMatrix left (leftSourceAddress, leftSourceStride, + leftSourceWidth, leftSourceHeight, leftElements, transposeLeftSource); + SrcMatrix right (rightSourceAddress, leftSourceStride, + rightSourceWidth, rightSourceHeight, rightElements, transposeRightSource); + DstMatrix dest (destAddress, destStride, + left.width, left.height, left.elements * right.elements, transposeDest); + + float * leftRecord, * rightRecord, * destRecord; + + left.rewind(); + for (int i = 0; i < leftElements; i++) + { + leftRecord = left.nextRecord(); + right.rewind(); + + for (int j = 0; j < rightElements; j++) + { + rightRecord = right.nextRecord(); + destRecord = dest.nextRecord(); + + for (int k = (leftSourceWidth * rightSourceWidth) - 1; k >= 0; k--) + destRecord[k] = leftRecord[k] + rightRecord[k]; + + dest.writeRecord(); + } + } + } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpDirect.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpDirect.cpp index 23e68323..85c30bf5 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpDirect.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpDirect.cpp @@ -41,6 +41,7 @@ #include #include "org_lwjgl_Math_MatrixOpCopy_MatrixOpDirect.h" +#include "MatrixOpCommon.h" /* * Class: org_lwjgl_Math_MatrixOpCopy_MatrixOpDirect * Method: execute @@ -61,8 +62,29 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpCopy_00024MatrixOpDirect jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + if (transposeSource == transposeDest) + { + transposeSource = false; + transposeDest = false; + } + + SrcMatrix source (sourceAddress, sourceStride, sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, source.width, source.height, source.elements, transposeDest); + + dest.configureBuffer(source); + + float * sourceRecord, * destRecord; + + for (int i = 0; i < source.elements; i++) + { + sourceRecord = source.nextRecord(); + destRecord = dest.nextRecord(); + + // just do a straight memory copy + memcpy(destRecord, sourceRecord, source.width*source.height*sizeof(jfloat)); + dest.writeRecord(); + } } + diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpSafe.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpSafe.cpp index f3fec7c7..4534c5f3 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpSafe.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpCopy_MatrixOpSafe.cpp @@ -41,6 +41,7 @@ #include #include "org_lwjgl_Math_MatrixOpCopy_MatrixOpSafe.h" +#include "MatrixOpCommon.h" /* * Class: org_lwjgl_Math_MatrixOpCopy_MatrixOpSafe * Method: execute @@ -61,6 +62,25 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpCopy_00024MatrixOpSafe_e jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + // remove any unnecessary copying + if (transposeSource == transposeDest) + { + transposeSource = false; + transposeDest = false; + } + + SrcMatrix source (sourceAddress, sourceStride, sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, source.width, source.height, source.elements, transposeDest); + + float * sourceRecord, * destRecord; + + for (int i = 0; i < source.elements; i++) + { + sourceRecord = source.nextRecord(); + destRecord = dest.nextRecord(); + + // just do a straight memory copy + memcpy(destRecord, sourceRecord, source.width * source.height * sizeof(jfloat)); + dest.writeRecord(); + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect.cpp index 8275aee8..ebe9759e 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect.cpp @@ -41,6 +41,7 @@ #include #include "org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect.h" +#include "MatrixOpCommon.h" /* * Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpDirect * Method: execute @@ -61,6 +62,47 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpDire jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + // We are under the assumption that sourceWidth == sourceHeight and the matrix + // defined within is invertable + + SrcMatrix source (sourceAddress, sourceStride, + sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, + source.width, source.height, source.elements, transposeDest); + + dest.configureBuffer(source); + + float * sourceRecord, * destRecord; + + int temp_side = source.width-1; + float temp_matrix [temp_side*temp_side]; + + for (int i = 0; i < source.elements; i++) + { + sourceRecord = source.nextRecord(); + destRecord = dest.nextRecord(); + + float det = determinant(sourceRecord, sourceWidth); + float sign; + + for (int c = 0; c < source.width; c++) + { + sign = (c & 1) ? 1.0f : -1.0f; + + for (int r = 0; r < source.width; r++) + { + // get the sub matrix + subMatrix(sourceRecord, source.width, temp_matrix, c, r); + + // transpose the result + destRecord[r + c * source.width] + = (sign / det) * determinant(temp_matrix, temp_side); + + // swap signs + sign = (sign == 1) ? -1.0f : 1.0f; + } + } + + dest.writeRecord(); + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.cpp index 90288ef3..4602bf56 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.cpp @@ -41,6 +41,9 @@ #include #include "org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.h" +#include "MatrixOpCommon.h" + + /* * Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe * Method: execute @@ -61,6 +64,45 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpSafe jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + // We are under the assumption that sourceWidth == sourceHeight and the matrix + // defined within is invertable + + SrcMatrix source (sourceAddress, sourceStride, + sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, + source.width, source.height, source.elements, transposeDest); + + float * sourceRecord, * destRecord; + + int temp_side = source.width-1; + float temp_matrix [temp_side*temp_side]; + + for (int i = 0; i < source.elements; i++) + { + sourceRecord = source.nextRecord(); + destRecord = dest.nextRecord(); + + float det = determinant(sourceRecord, sourceWidth); + float sign; + + for (int c = 0; c < source.width; c++) + { + sign = (c & 1) ? 1.0f : -1.0f; + + for (int r = 0; r < source.width; r++) + { + // get the sub matrix + subMatrix(sourceRecord, source.width, temp_matrix, c, r); + + // transpose the result + destRecord[r + c * source.width] + = (sign / det) * determinant(temp_matrix, temp_side); + + // swap signs + sign = (sign == 1) ? -1.0f : 1.0f; + } + } + + dest.writeRecord(); + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpDirect.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpDirect.cpp index d74f39a6..2a8706ff 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpDirect.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpDirect.cpp @@ -41,6 +41,8 @@ #include #include "org_lwjgl_Math_MatrixOpMultiply_MatrixOpDirect.h" +#include "MatrixOpCommon.h" +#include /* * Class: org_lwjgl_Math_MatrixOpMultiply_MatrixOpDirect * Method: execute @@ -67,9 +69,55 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpMultiply_00024MatrixOpDi jboolean transposeDest ) { - float * leftSource = (float *) leftSourceAddress; - float * rightSource = (float *) rightSourceAddress; - float * dest = (float *) destAddress; + if (transposeLeftSource && transposeRightSource) + { + transposeLeftSource = false; + transposeRightSource = false; + transposeDest = !transposeDest; + } + + + SrcMatrix left (leftSourceAddress, leftSourceStride, + leftSourceWidth, leftSourceHeight, leftElements, transposeLeftSource); + SrcMatrix right (rightSourceAddress, leftSourceStride, + rightSourceWidth, rightSourceHeight, rightElements, transposeRightSource); + DstMatrix dest (destAddress, destStride, + right.width, left.height, left.elements * right.elements, transposeDest); + + dest.configureBuffer(left, right); + + float * leftRecord, * rightRecord, * destRecord; + + // check out discussions envolving ordering + + + left.rewind(); + for (int i = 0; i < leftElements; i++) + { + leftRecord = left.nextRecord(); + + right.rewind(); + for (int j = 0; j < rightElements; j++) + { + rightRecord = right.nextRecord(); + destRecord = dest.nextRecord(); + + memset(destRecord, 0, dest.width * dest.height * sizeof(jfloat)); + + for (int rightCol = 0; rightCol < right.width; rightCol++) + { + for (int leftIndex = 0; leftIndex < left.width*left.height; leftIndex++) + { + destRecord[i % dest.height] += leftRecord[i] * rightRecord[i / leftSourceHeight]; + } + + rightRecord = &rightRecord[right.height]; + destRecord = &destRecord[dest.height]; + + } + dest.writeRecord(); + } + } + } - diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.cpp index ab635bc6..e4b81196 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.cpp @@ -41,6 +41,9 @@ #include #include "org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.h" +#include "MatrixOpCommon.h" +#include + /* * Class: org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe * Method: execute @@ -67,9 +70,54 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpMultiply_00024MatrixOpSa jboolean transposeDest ) { - float * leftSource = (float *) leftSourceAddress; - float * rightSource = (float *) rightSourceAddress; - float * dest = (float *) destAddress; + if (transposeLeftSource && transposeRightSource) + { + transposeLeftSource = false; + transposeRightSource = false; + transposeDest = !transposeDest; + } + + + SrcMatrix left (leftSourceAddress, leftSourceStride, + leftSourceWidth, leftSourceHeight, leftElements, transposeLeftSource); + SrcMatrix right (rightSourceAddress, leftSourceStride, + rightSourceWidth, rightSourceHeight, rightElements, transposeRightSource); + DstMatrix dest (destAddress, destStride, + right.width, left.height, left.elements * right.elements, transposeDest); + + float * leftRecord, * rightRecord, * destRecord; + + // check out discussions envolving ordering + + + left.rewind(); + for (int i = 0; i < leftElements; i++) + { + leftRecord = left.nextRecord(); + + right.rewind(); + for (int j = 0; j < rightElements; j++) + { + rightRecord = right.nextRecord(); + destRecord = dest.nextRecord(); + + memset(destRecord, 0, dest.width * dest.height * sizeof(jfloat)); + + for (int rightCol = 0; rightCol < right.width; rightCol++) + { + for (int leftIndex = 0; leftIndex < left.width*left.height; leftIndex++) + { + destRecord[i % dest.height] += leftRecord[i] * rightRecord[i / leftSourceHeight]; + } + + rightRecord = &rightRecord[right.height]; + destRecord = &destRecord[dest.height]; + + } + dest.writeRecord(); + } + } + } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpDirect.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpDirect.cpp index df1d3e5a..c8dbbed2 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpDirect.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpDirect.cpp @@ -41,6 +41,7 @@ #include #include "org_lwjgl_Math_MatrixOpNegate_MatrixOpDirect.h" +#include "MatrixOpCommon.h" /* * Class: org_lwjgl_Math_MatrixOpNegate_MatrixOpDirect * Method: execute @@ -61,6 +62,25 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpNegate_00024MatrixOpDire jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + SrcMatrix source (sourceAddress, sourceStride, sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, source.width, source.height, numElements, transposeDest); + + dest.configureBuffer(source); + + int * sourceRecord, * destRecord; + + for (int i = 0; i < source.elements; i++) + { + sourceRecord = (int *) source.nextRecord(); + destRecord = (int *) dest.nextRecord(); + + // we can cheat and use the less expensive xor + // to switch the sign bit of the float + // single precision format 1 - sign 8 - exponent (excess 127) 23 - mantisa + + for (int j = 0; j < sourceWidth*sourceHeight; j++) + destRecord[j] = sourceRecord[j] ^ 0x80000000; + + dest.writeRecord(); + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpSafe.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpSafe.cpp index 60f6189e..37652614 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpSafe.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpNegate_MatrixOpSafe.cpp @@ -41,6 +41,7 @@ #include #include "org_lwjgl_Math_MatrixOpNegate_MatrixOpSafe.h" +#include "MatrixOpCommon.h" /* * Class: org_lwjgl_Math_MatrixOpNegate_MatrixOpSafe * Method: execute @@ -61,6 +62,23 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpNegate_00024MatrixOpSafe jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + SrcMatrix source (sourceAddress, sourceStride, sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, source.width, source.height, numElements, transposeDest); + + int * sourceRecord, * destRecord; + + for (int i = 0; i < source.elements; i++) + { + sourceRecord = (int *) source.nextRecord(); + destRecord = (int *) dest.nextRecord(); + + // we can cheat and use the less expensive xor + // to switch the sign bit of the float + // single precision format 1 - sign 8 - exponent (excess 127) 23 - mantisa + + for (int j = 0; j < sourceWidth*sourceHeight; j++) + destRecord[j] = sourceRecord[j] ^ 0x80000000; + + dest.writeRecord(); + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpDirect.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpDirect.cpp index 1db67ec6..08fe495c 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpDirect.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpDirect.cpp @@ -41,6 +41,11 @@ #include #include "org_lwjgl_Math_MatrixOpNormalise_MatrixOpDirect.h" +#include "MatrixOpCommon.h" +#include + +using namespace std; + /* * Class: org_lwjgl_Math_MatrixOpNormalise_MatrixOpDirect * Method: execute @@ -61,6 +66,32 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpNormalise_00024MatrixOpD jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + SrcMatrix source (sourceAddress, sourceStride, sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, source.width, source.height, source.elements, transposeDest); + + dest.configureBuffer(source); + + float * sourceRecord, * destRecord; + float magnitude, magnitude_squared; + + int i; + register int j; + + for (i = 0; i < source.elements; i++) + { + + magnitude_squared = 0; + sourceRecord = source.nextRecord(); + destRecord = dest.nextRecord(); + + for (j = 0 ; j < sourceWidth*sourceHeight; i++) + magnitude_squared += sourceRecord[j] * sourceRecord[j]; + + magnitude = (float) sqrt((double) magnitude_squared); + + for (j = 0; j < sourceWidth*sourceHeight; i++) + destRecord[j] = sourceRecord[j] / magnitude; + + dest.writeRecord(); + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpSafe.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpSafe.cpp index 249990a0..070c38e4 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpSafe.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpNormalise_MatrixOpSafe.cpp @@ -41,6 +41,11 @@ #include #include "org_lwjgl_Math_MatrixOpSubtract_MatrixOpSafe.h" +#include "MatrixOpCommon.h" +#include + +using namespace std; + /* * Class: org_lwjgl_Math_MatrixOpNormalise_MatrixOpSafe * Method: execute @@ -61,6 +66,30 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpNormalise_00024MatrixOpS jboolean transposeDest ) { - float * source = (float *) sourceAddress; - float * dest = (float *) destAddress; + SrcMatrix source (sourceAddress, sourceStride, sourceWidth, sourceHeight, numElements, transposeSource); + DstMatrix dest (destAddress, destStride, source.width, source.height, source.elements, transposeDest); + + float * sourceRecord, * destRecord; + float magnitude, magnitude_squared; + + int i; + register int j; + + for (i = 0; i < source.elements; i++) + { + + magnitude_squared = 0; + sourceRecord = source.nextRecord(); + destRecord = dest.nextRecord(); + + for (j = 0 ; j < sourceWidth*sourceHeight; i++) + magnitude_squared += sourceRecord[j] * sourceRecord[j]; + + magnitude = (float) sqrt((double) magnitude_squared); + + for (j = 0; j < sourceWidth*sourceHeight; i++) + destRecord[j] = sourceRecord[j] / magnitude; + + dest.writeRecord(); + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpDirect.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpDirect.cpp index 445119d1..a7947214 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpDirect.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpDirect.cpp @@ -41,6 +41,7 @@ #include #include "org_lwjgl_Math_MatrixOpSubtract_MatrixOpDirect.h" +#include "MatrixOpCommon.h" /* * Class: org_lwjgl_Math_MatrixOpSubtract_MatrixOpDirect * Method: execute @@ -67,9 +68,41 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpSubtract_00024MatrixOpDi jboolean transposeDest ) { - float * leftSource = (float *) leftSourceAddress; - float * rightSource = (float *) rightSourceAddress; - float * dest = (float *) destAddress; + if (transposeLeftSource && transposeRightSource) + { + transposeLeftSource = false; + transposeRightSource = false; + transposeDest = !transposeDest; + } + + SrcMatrix left (leftSourceAddress, leftSourceStride, + leftSourceWidth, leftSourceHeight, leftElements, transposeLeftSource); + SrcMatrix right (rightSourceAddress, leftSourceStride, + rightSourceWidth, rightSourceHeight, rightElements, transposeRightSource); + DstMatrix dest (destAddress, destStride, + left.width, left.height, left.elements * right.elements, transposeDest); + + dest.configureBuffer(left, right); + + float * leftRecord, * rightRecord, * destRecord; + + left.rewind(); + for (int i = 0; i < left.elements; i++) + { + leftRecord = left.nextRecord(); + + right.rewind(); + for (int j = 0; j < right.elements; j++) + { + rightRecord = right.nextRecord(); + destRecord = dest.nextRecord(); + + for (int k = (left.width * left.height) - 1; k >= 0; k--) + destRecord[k] = leftRecord[k] - rightRecord[k]; + + dest.writeRecord(); + } + } } diff --git a/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpSafe.cpp b/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpSafe.cpp index c5c7088f..85891c2e 100644 --- a/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpSafe.cpp +++ b/src/native/win32/org_lwjgl_Math_MatrixOpSubtract_MatrixOpSafe.cpp @@ -41,6 +41,8 @@ #include #include "org_lwjgl_Math_MatrixOpSubtract_MatrixOpSafe.h" +#include "MatrixOpCommon.h" + /* * Class: org_lwjgl_Math_MatrixOpSubtract_MatrixOpSafe * Method: execute @@ -67,9 +69,40 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpSubtract_00024MatrixOpSa jboolean transposeDest ) { - float * leftSource = (float *) leftSourceAddress; - float * rightSource = (float *) rightSourceAddress; - float * dest = (float *) destAddress; + if (transposeLeftSource && transposeRightSource) + { + transposeLeftSource = false; + transposeRightSource = false; + transposeDest = !transposeDest; + } + + SrcMatrix left (leftSourceAddress, leftSourceStride, + leftSourceWidth, leftSourceHeight, leftElements, transposeLeftSource); + SrcMatrix right (rightSourceAddress, leftSourceStride, + rightSourceWidth, rightSourceHeight, rightElements, transposeRightSource); + DstMatrix dest (destAddress, destStride, + left.width, left.height, left.elements * right.elements, transposeDest); + + float * leftRecord, * rightRecord, * destRecord; + + left.rewind(); + for (int i = 0; i < left.elements; i++) + { + leftRecord = left.nextRecord(); + + right.rewind(); + for (int j = 0; j < right.elements; j++) + { + rightRecord = right.nextRecord(); + destRecord = dest.nextRecord(); + + for (int k = (left.width * left.height) - 1; k >= 0; k--) + destRecord[k] = leftRecord[k] - rightRecord[k]; + + dest.writeRecord(); + } + } } +