Revert "Revert "Move Matrix operations multiplyMM and MultiplMV ..."
Revert submission 2382753-revert-2208281-opengl-matrix-VRTQUTHPDK Reason for revert: Revert-Revert-with-fix Reverted changes: /q/submissionid:2382753-revert-2208281-opengl-matrix-VRTQUTHPDK Change-Id: I8bde74db4e9fde278a6d53c1784d3a65530c5173
This commit is contained in:
committed by
Trevor David Black
parent
08afbf5cf1
commit
449f4269e2
@@ -541,87 +541,6 @@ jint util_visibilityTest(JNIEnv *env, jclass clazz,
|
|||||||
indices.mData, indexCount);
|
indices.mData, indexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define I(_i, _j) ((_j)+ 4*(_i))
|
|
||||||
|
|
||||||
static
|
|
||||||
void multiplyMM(float* r, const float* lhs, const float* rhs)
|
|
||||||
{
|
|
||||||
for (int i=0 ; i<4 ; i++) {
|
|
||||||
const float rhs_i0 = rhs[ I(i,0) ];
|
|
||||||
float ri0 = lhs[ I(0,0) ] * rhs_i0;
|
|
||||||
float ri1 = lhs[ I(0,1) ] * rhs_i0;
|
|
||||||
float ri2 = lhs[ I(0,2) ] * rhs_i0;
|
|
||||||
float ri3 = lhs[ I(0,3) ] * rhs_i0;
|
|
||||||
for (int j=1 ; j<4 ; j++) {
|
|
||||||
const float rhs_ij = rhs[ I(i,j) ];
|
|
||||||
ri0 += lhs[ I(j,0) ] * rhs_ij;
|
|
||||||
ri1 += lhs[ I(j,1) ] * rhs_ij;
|
|
||||||
ri2 += lhs[ I(j,2) ] * rhs_ij;
|
|
||||||
ri3 += lhs[ I(j,3) ] * rhs_ij;
|
|
||||||
}
|
|
||||||
r[ I(i,0) ] = ri0;
|
|
||||||
r[ I(i,1) ] = ri1;
|
|
||||||
r[ I(i,2) ] = ri2;
|
|
||||||
r[ I(i,3) ] = ri3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void util_multiplyMM(JNIEnv *env, jclass clazz,
|
|
||||||
jfloatArray result_ref, jint resultOffset,
|
|
||||||
jfloatArray lhs_ref, jint lhsOffset,
|
|
||||||
jfloatArray rhs_ref, jint rhsOffset) {
|
|
||||||
|
|
||||||
FloatArrayHelper resultMat(env, result_ref, resultOffset, 16);
|
|
||||||
FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
|
|
||||||
FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16);
|
|
||||||
|
|
||||||
bool checkOK = resultMat.check() && lhs.check() && rhs.check();
|
|
||||||
|
|
||||||
if ( !checkOK ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resultMat.bind();
|
|
||||||
lhs.bind();
|
|
||||||
rhs.bind();
|
|
||||||
|
|
||||||
multiplyMM(resultMat.mData, lhs.mData, rhs.mData);
|
|
||||||
|
|
||||||
resultMat.commitChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void multiplyMV(float* r, const float* lhs, const float* rhs)
|
|
||||||
{
|
|
||||||
mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void util_multiplyMV(JNIEnv *env, jclass clazz,
|
|
||||||
jfloatArray result_ref, jint resultOffset,
|
|
||||||
jfloatArray lhs_ref, jint lhsOffset,
|
|
||||||
jfloatArray rhs_ref, jint rhsOffset) {
|
|
||||||
|
|
||||||
FloatArrayHelper resultV(env, result_ref, resultOffset, 4);
|
|
||||||
FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
|
|
||||||
FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4);
|
|
||||||
|
|
||||||
bool checkOK = resultV.check() && lhs.check() && rhs.check();
|
|
||||||
|
|
||||||
if ( !checkOK ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resultV.bind();
|
|
||||||
lhs.bind();
|
|
||||||
rhs.bind();
|
|
||||||
|
|
||||||
multiplyMV(resultV.mData, lhs.mData, rhs.mData);
|
|
||||||
|
|
||||||
resultV.commitChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// The internal format is no longer the same as pixel format, per Table 2 in
|
// The internal format is no longer the same as pixel format, per Table 2 in
|
||||||
@@ -1009,11 +928,6 @@ static jint etc1_getHeight(JNIEnv *env, jclass clazz,
|
|||||||
* JNI registration
|
* JNI registration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const JNINativeMethod gMatrixMethods[] = {
|
|
||||||
{ "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
|
|
||||||
{ "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const JNINativeMethod gVisibilityMethods[] = {
|
static const JNINativeMethod gVisibilityMethods[] = {
|
||||||
{ "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
|
{ "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
|
||||||
{ "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
|
{ "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
|
||||||
@@ -1046,7 +960,6 @@ typedef struct _ClassRegistrationInfo {
|
|||||||
} ClassRegistrationInfo;
|
} ClassRegistrationInfo;
|
||||||
|
|
||||||
static const ClassRegistrationInfo gClasses[] = {
|
static const ClassRegistrationInfo gClasses[] = {
|
||||||
{"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
|
|
||||||
{"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
|
{"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
|
||||||
{"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
|
{"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
|
||||||
{"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
|
{"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ package android.opengl;
|
|||||||
public class Matrix {
|
public class Matrix {
|
||||||
|
|
||||||
/** Temporary memory for operations that need temporary matrix data. */
|
/** Temporary memory for operations that need temporary matrix data. */
|
||||||
private final static float[] sTemp = new float[32];
|
private static final ThreadLocal<float[]> ThreadTmp = new ThreadLocal() {
|
||||||
|
@Override protected float[] initialValue() {
|
||||||
|
return new float[32];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated All methods are static, do not instantiate this class.
|
* @deprecated All methods are static, do not instantiate this class.
|
||||||
@@ -46,6 +50,40 @@ public class Matrix {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public Matrix() {}
|
public Matrix() {}
|
||||||
|
|
||||||
|
private static boolean overlap(
|
||||||
|
float[] a, int aStart, int aLength, float[] b, int bStart, int bLength) {
|
||||||
|
if (a != b) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aStart == bStart) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aEnd = aStart + aLength;
|
||||||
|
int bEnd = bStart + bLength;
|
||||||
|
|
||||||
|
if (aEnd == bEnd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aStart < bStart && bStart < aEnd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (aStart < bEnd && bEnd < aEnd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bStart < aStart && aStart < bEnd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (bStart < aEnd && aEnd < bEnd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multiplies two 4x4 matrices together and stores the result in a third 4x4
|
* Multiplies two 4x4 matrices together and stores the result in a third 4x4
|
||||||
* matrix. In matrix notation: result = lhs x rhs. Due to the way
|
* matrix. In matrix notation: result = lhs x rhs. Due to the way
|
||||||
@@ -53,9 +91,9 @@ public class Matrix {
|
|||||||
* effect as first multiplying by the rhs matrix, then multiplying by
|
* effect as first multiplying by the rhs matrix, then multiplying by
|
||||||
* the lhs matrix. This is the opposite of what you might expect.
|
* the lhs matrix. This is the opposite of what you might expect.
|
||||||
* <p>
|
* <p>
|
||||||
* The same float array may be passed for result, lhs, and/or rhs. However,
|
* The same float array may be passed for result, lhs, and/or rhs. This
|
||||||
* the result element values are undefined if the result elements overlap
|
* operation is expected to do the correct thing if the result elements
|
||||||
* either the lhs or rhs elements.
|
* overlap with either of the lhs or rhs elements.
|
||||||
*
|
*
|
||||||
* @param result The float array that holds the result.
|
* @param result The float array that holds the result.
|
||||||
* @param resultOffset The offset into the result array where the result is
|
* @param resultOffset The offset into the result array where the result is
|
||||||
@@ -65,20 +103,101 @@ public class Matrix {
|
|||||||
* @param rhs The float array that holds the right-hand-side matrix.
|
* @param rhs The float array that holds the right-hand-side matrix.
|
||||||
* @param rhsOffset The offset into the rhs array where the rhs is stored.
|
* @param rhsOffset The offset into the rhs array where the rhs is stored.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if result, lhs, or rhs are null, or if
|
* @throws IllegalArgumentException under any of the following conditions:
|
||||||
* resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or
|
* result, lhs, or rhs are null;
|
||||||
* rhsOffset + 16 > rhs.length.
|
* resultOffset + 16 > result.length
|
||||||
|
* or lhsOffset + 16 > lhs.length
|
||||||
|
* or rhsOffset + 16 > rhs.length;
|
||||||
|
* resultOffset < 0 or lhsOffset < 0 or rhsOffset < 0
|
||||||
*/
|
*/
|
||||||
public static native void multiplyMM(float[] result, int resultOffset,
|
public static void multiplyMM(float[] result, int resultOffset,
|
||||||
float[] lhs, int lhsOffset, float[] rhs, int rhsOffset);
|
float[] lhs, int lhsOffset, float[] rhs, int rhsOffset) {
|
||||||
|
// error checking
|
||||||
|
if (result == null) {
|
||||||
|
throw new IllegalArgumentException("result == null");
|
||||||
|
}
|
||||||
|
if (lhs == null) {
|
||||||
|
throw new IllegalArgumentException("lhs == null");
|
||||||
|
}
|
||||||
|
if (rhs == null) {
|
||||||
|
throw new IllegalArgumentException("rhs == null");
|
||||||
|
}
|
||||||
|
if (resultOffset < 0) {
|
||||||
|
throw new IllegalArgumentException("resultOffset < 0");
|
||||||
|
}
|
||||||
|
if (lhsOffset < 0) {
|
||||||
|
throw new IllegalArgumentException("lhsOffset < 0");
|
||||||
|
}
|
||||||
|
if (rhsOffset < 0) {
|
||||||
|
throw new IllegalArgumentException("rhsOffset < 0");
|
||||||
|
}
|
||||||
|
if (result.length < resultOffset + 16) {
|
||||||
|
throw new IllegalArgumentException("result.length < resultOffset + 16");
|
||||||
|
}
|
||||||
|
if (lhs.length < lhsOffset + 16) {
|
||||||
|
throw new IllegalArgumentException("lhs.length < lhsOffset + 16");
|
||||||
|
}
|
||||||
|
if (rhs.length < rhsOffset + 16) {
|
||||||
|
throw new IllegalArgumentException("rhs.length < rhsOffset + 16");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for overlap between rhs and result or lhs and result
|
||||||
|
if ( overlap(result, resultOffset, 16, lhs, lhsOffset, 16)
|
||||||
|
|| overlap(result, resultOffset, 16, rhs, rhsOffset, 16) ) {
|
||||||
|
float[] tmp = ThreadTmp.get();
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
final float rhs_i0 = rhs[ 4*i + 0 + rhsOffset ];
|
||||||
|
float ri0 = lhs[ 0 + lhsOffset ] * rhs_i0;
|
||||||
|
float ri1 = lhs[ 1 + lhsOffset ] * rhs_i0;
|
||||||
|
float ri2 = lhs[ 2 + lhsOffset ] * rhs_i0;
|
||||||
|
float ri3 = lhs[ 3 + lhsOffset ] * rhs_i0;
|
||||||
|
for (int j=1; j<4; j++) {
|
||||||
|
final float rhs_ij = rhs[ 4*i + j + rhsOffset];
|
||||||
|
ri0 += lhs[ 4*j + 0 + lhsOffset ] * rhs_ij;
|
||||||
|
ri1 += lhs[ 4*j + 1 + lhsOffset ] * rhs_ij;
|
||||||
|
ri2 += lhs[ 4*j + 2 + lhsOffset ] * rhs_ij;
|
||||||
|
ri3 += lhs[ 4*j + 3 + lhsOffset ] * rhs_ij;
|
||||||
|
}
|
||||||
|
tmp[ 4*i + 0 ] = ri0;
|
||||||
|
tmp[ 4*i + 1 ] = ri1;
|
||||||
|
tmp[ 4*i + 2 ] = ri2;
|
||||||
|
tmp[ 4*i + 3 ] = ri3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy from tmp to result
|
||||||
|
for (int i=0; i < 16; i++) {
|
||||||
|
result[ i + resultOffset ] = tmp[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
final float rhs_i0 = rhs[ 4*i + 0 + rhsOffset ];
|
||||||
|
float ri0 = lhs[ 0 + lhsOffset ] * rhs_i0;
|
||||||
|
float ri1 = lhs[ 1 + lhsOffset ] * rhs_i0;
|
||||||
|
float ri2 = lhs[ 2 + lhsOffset ] * rhs_i0;
|
||||||
|
float ri3 = lhs[ 3 + lhsOffset ] * rhs_i0;
|
||||||
|
for (int j=1; j<4; j++) {
|
||||||
|
final float rhs_ij = rhs[ 4*i + j + rhsOffset];
|
||||||
|
ri0 += lhs[ 4*j + 0 + lhsOffset ] * rhs_ij;
|
||||||
|
ri1 += lhs[ 4*j + 1 + lhsOffset ] * rhs_ij;
|
||||||
|
ri2 += lhs[ 4*j + 2 + lhsOffset ] * rhs_ij;
|
||||||
|
ri3 += lhs[ 4*j + 3 + lhsOffset ] * rhs_ij;
|
||||||
|
}
|
||||||
|
result[ 4*i + 0 + resultOffset ] = ri0;
|
||||||
|
result[ 4*i + 1 + resultOffset ] = ri1;
|
||||||
|
result[ 4*i + 2 + resultOffset ] = ri2;
|
||||||
|
result[ 4*i + 3 + resultOffset ] = ri3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multiplies a 4 element vector by a 4x4 matrix and stores the result in a
|
* Multiplies a 4 element vector by a 4x4 matrix and stores the result in a
|
||||||
* 4-element column vector. In matrix notation: result = lhs x rhs
|
* 4-element column vector. In matrix notation: result = lhs x rhs
|
||||||
* <p>
|
* <p>
|
||||||
* The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
|
* The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
|
||||||
* However, the resultVec element values are undefined if the resultVec
|
* This operation is expected to do the correct thing if the result elements
|
||||||
* elements overlap either the lhsMat or rhsVec elements.
|
* overlap with either of the lhs or rhs elements.
|
||||||
*
|
*
|
||||||
* @param resultVec The float array that holds the result vector.
|
* @param resultVec The float array that holds the result vector.
|
||||||
* @param resultVecOffset The offset into the result array where the result
|
* @param resultVecOffset The offset into the result array where the result
|
||||||
@@ -89,14 +208,67 @@ public class Matrix {
|
|||||||
* @param rhsVecOffset The offset into the rhs vector where the rhs vector
|
* @param rhsVecOffset The offset into the rhs vector where the rhs vector
|
||||||
* is stored.
|
* is stored.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if resultVec, lhsMat,
|
* @throws IllegalArgumentException under any of the following conditions:
|
||||||
* or rhsVec are null, or if resultVecOffset + 4 > resultVec.length
|
* resultVec, lhsMat, or rhsVec are null;
|
||||||
* or lhsMatOffset + 16 > lhsMat.length or
|
* resultVecOffset + 4 > resultVec.length
|
||||||
* rhsVecOffset + 4 > rhsVec.length.
|
* or lhsMatOffset + 16 > lhsMat.length
|
||||||
|
* or rhsVecOffset + 4 > rhsVec.length;
|
||||||
|
* resultVecOffset < 0 or lhsMatOffset < 0 or rhsVecOffset < 0
|
||||||
*/
|
*/
|
||||||
public static native void multiplyMV(float[] resultVec,
|
public static void multiplyMV(float[] resultVec,
|
||||||
int resultVecOffset, float[] lhsMat, int lhsMatOffset,
|
int resultVecOffset, float[] lhsMat, int lhsMatOffset,
|
||||||
float[] rhsVec, int rhsVecOffset);
|
float[] rhsVec, int rhsVecOffset) {
|
||||||
|
// error checking
|
||||||
|
if (resultVec == null) {
|
||||||
|
throw new IllegalArgumentException("resultVec == null");
|
||||||
|
}
|
||||||
|
if (lhsMat == null) {
|
||||||
|
throw new IllegalArgumentException("lhsMat == null");
|
||||||
|
}
|
||||||
|
if (rhsVec == null) {
|
||||||
|
throw new IllegalArgumentException("rhsVec == null");
|
||||||
|
}
|
||||||
|
if (resultVecOffset < 0) {
|
||||||
|
throw new IllegalArgumentException("resultVecOffset < 0");
|
||||||
|
}
|
||||||
|
if (lhsMatOffset < 0) {
|
||||||
|
throw new IllegalArgumentException("lhsMatOffset < 0");
|
||||||
|
}
|
||||||
|
if (rhsVecOffset < 0) {
|
||||||
|
throw new IllegalArgumentException("rhsVecOffset < 0");
|
||||||
|
}
|
||||||
|
if (resultVec.length < resultVecOffset + 4) {
|
||||||
|
throw new IllegalArgumentException("resultVec.length < resultVecOffset + 4");
|
||||||
|
}
|
||||||
|
if (lhsMat.length < lhsMatOffset + 16) {
|
||||||
|
throw new IllegalArgumentException("lhsMat.length < lhsMatOffset + 16");
|
||||||
|
}
|
||||||
|
if (rhsVec.length < rhsVecOffset + 4) {
|
||||||
|
throw new IllegalArgumentException("rhsVec.length < rhsVecOffset + 4");
|
||||||
|
}
|
||||||
|
|
||||||
|
float tmp0 = lhsMat[0 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
|
||||||
|
lhsMat[0 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
|
||||||
|
lhsMat[0 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
|
||||||
|
lhsMat[0 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
|
||||||
|
float tmp1 = lhsMat[1 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
|
||||||
|
lhsMat[1 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
|
||||||
|
lhsMat[1 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
|
||||||
|
lhsMat[1 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
|
||||||
|
float tmp2 = lhsMat[2 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
|
||||||
|
lhsMat[2 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
|
||||||
|
lhsMat[2 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
|
||||||
|
lhsMat[2 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
|
||||||
|
float tmp3 = lhsMat[3 + 4 * 0 + lhsMatOffset] * rhsVec[0 + rhsVecOffset] +
|
||||||
|
lhsMat[3 + 4 * 1 + lhsMatOffset] * rhsVec[1 + rhsVecOffset] +
|
||||||
|
lhsMat[3 + 4 * 2 + lhsMatOffset] * rhsVec[2 + rhsVecOffset] +
|
||||||
|
lhsMat[3 + 4 * 3 + lhsMatOffset] * rhsVec[3 + rhsVecOffset];
|
||||||
|
|
||||||
|
resultVec[ 0 + resultVecOffset ] = tmp0;
|
||||||
|
resultVec[ 1 + resultVecOffset ] = tmp1;
|
||||||
|
resultVec[ 2 + resultVecOffset ] = tmp2;
|
||||||
|
resultVec[ 3 + resultVecOffset ] = tmp3;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transposes a 4 x 4 matrix.
|
* Transposes a 4 x 4 matrix.
|
||||||
@@ -537,10 +709,9 @@ public class Matrix {
|
|||||||
public static void rotateM(float[] rm, int rmOffset,
|
public static void rotateM(float[] rm, int rmOffset,
|
||||||
float[] m, int mOffset,
|
float[] m, int mOffset,
|
||||||
float a, float x, float y, float z) {
|
float a, float x, float y, float z) {
|
||||||
synchronized(sTemp) {
|
float[] tmp = ThreadTmp.get();
|
||||||
setRotateM(sTemp, 0, a, x, y, z);
|
setRotateM(tmp, 16, a, x, y, z);
|
||||||
multiplyMM(rm, rmOffset, m, mOffset, sTemp, 0);
|
multiplyMM(rm, rmOffset, m, mOffset, tmp, 16);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -556,11 +727,7 @@ public class Matrix {
|
|||||||
*/
|
*/
|
||||||
public static void rotateM(float[] m, int mOffset,
|
public static void rotateM(float[] m, int mOffset,
|
||||||
float a, float x, float y, float z) {
|
float a, float x, float y, float z) {
|
||||||
synchronized(sTemp) {
|
rotateM(m, mOffset, m, mOffset, a, x, y, z);
|
||||||
setRotateM(sTemp, 0, a, x, y, z);
|
|
||||||
multiplyMM(sTemp, 16, m, mOffset, sTemp, 0);
|
|
||||||
System.arraycopy(sTemp, 16, m, mOffset, 16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user