mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 00:29:50 -04:00
Feat[utils]: Implement MatrixUtils, with methods to easily work with transform matrices
This commit is contained in:
parent
83fdf15379
commit
2cef7ccd49
@ -5,6 +5,8 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.utils.MatrixUtils;
|
||||||
|
|
||||||
public class BitmapCropBehaviour implements CropperBehaviour{
|
public class BitmapCropBehaviour implements CropperBehaviour{
|
||||||
private final Matrix mTranslateInverse = new Matrix();
|
private final Matrix mTranslateInverse = new Matrix();
|
||||||
protected final Matrix mTranslateMatrix = new Matrix();
|
protected final Matrix mTranslateMatrix = new Matrix();
|
||||||
@ -32,7 +34,7 @@ public class BitmapCropBehaviour implements CropperBehaviour{
|
|||||||
public void zoom(float zoomLevel, float midpointX, float midpointY) {
|
public void zoom(float zoomLevel, float midpointX, float midpointY) {
|
||||||
// Do this to avoid constantly inverting the same matrix on each touch event.
|
// Do this to avoid constantly inverting the same matrix on each touch event.
|
||||||
if(mTranslateInverseOutdated) {
|
if(mTranslateInverseOutdated) {
|
||||||
inverse(mTranslateMatrix, mTranslateInverse);
|
MatrixUtils.inverse(mTranslateMatrix, mTranslateInverse);
|
||||||
mTranslateInverseOutdated = false;
|
mTranslateInverseOutdated = false;
|
||||||
}
|
}
|
||||||
float[] zoomCenter = new float[] {
|
float[] zoomCenter = new float[] {
|
||||||
@ -81,42 +83,32 @@ public class BitmapCropBehaviour implements CropperBehaviour{
|
|||||||
|
|
||||||
public Bitmap crop(int targetMaxSide) {
|
public Bitmap crop(int targetMaxSide) {
|
||||||
Matrix imageInverse = new Matrix();
|
Matrix imageInverse = new Matrix();
|
||||||
inverse(mImageMatrix, imageInverse);
|
MatrixUtils.inverse(mImageMatrix, imageInverse);
|
||||||
// By inverting the matrix we will effectively "divide" our rectangle by it, thus getting
|
// By inverting the matrix we will effectively "divide" our rectangle by it, thus getting
|
||||||
// its two points on the surface of the bitmap. Math be cool indeed.
|
// its two points on the bitmap's surface. Math be cool indeed.
|
||||||
float[] src = new float[] {
|
Rect targetRect = new Rect();
|
||||||
mHostView.mSelectionRect.left,
|
MatrixUtils.transformRect(mHostView.mSelectionRect, targetRect, imageInverse);
|
||||||
mHostView.mSelectionRect.top,
|
|
||||||
mHostView.mSelectionRect.right,
|
|
||||||
mHostView.mSelectionRect.bottom
|
|
||||||
};
|
|
||||||
float[] dst = new float[4];
|
|
||||||
imageInverse.mapPoints(dst, 0, src, 0, 2);
|
|
||||||
Rect originalBitmapRect = new Rect(
|
|
||||||
(int)dst[0], (int)dst[1],
|
|
||||||
(int)dst[2], (int)dst[3]
|
|
||||||
);
|
|
||||||
// Pick the best dimensions for the crop result, shrinking the target if necessary.
|
// Pick the best dimensions for the crop result, shrinking the target if necessary.
|
||||||
int targetWidth, targetHeight;
|
int targetWidth, targetHeight;
|
||||||
int targetMinDimension = Math.min(originalBitmapRect.width(), originalBitmapRect.height());
|
int targetMinDimension = Math.min(targetRect.width(), targetRect.height());
|
||||||
if(targetMaxSide < targetMinDimension) {
|
if(targetMaxSide < targetMinDimension) {
|
||||||
float ratio = (float) targetMaxSide / targetMinDimension;
|
float ratio = (float) targetMaxSide / targetMinDimension;
|
||||||
targetWidth = (int) (originalBitmapRect.width() * ratio);
|
targetWidth = (int) (targetRect.width() * ratio);
|
||||||
targetHeight = (int) (originalBitmapRect.height() * ratio);
|
targetHeight = (int) (targetRect.height() * ratio);
|
||||||
}else {
|
}else {
|
||||||
targetWidth = originalBitmapRect.width();
|
targetWidth = targetRect.width();
|
||||||
targetHeight = originalBitmapRect.height();
|
targetHeight = targetRect.height();
|
||||||
}
|
}
|
||||||
Bitmap croppedBitmap = Bitmap.createBitmap(
|
Bitmap croppedBitmap = Bitmap.createBitmap(
|
||||||
targetWidth, targetHeight,
|
targetWidth, targetHeight,
|
||||||
mOriginalBitmap.getConfig()
|
mOriginalBitmap.getConfig()
|
||||||
);
|
);
|
||||||
// Draw the bitmap on the target. Doing this allows us to not bother with making sure
|
// Draw the bitmap on the target. Doing this allows us to not bother with making sure
|
||||||
// that originalBitmapRect is fully contained within image bounds.
|
// that targetRect is fully contained within image bounds.
|
||||||
Canvas drawCanvas = new Canvas(croppedBitmap);
|
Canvas drawCanvas = new Canvas(croppedBitmap);
|
||||||
drawCanvas.drawBitmap(
|
drawCanvas.drawBitmap(
|
||||||
mOriginalBitmap,
|
mOriginalBitmap,
|
||||||
originalBitmapRect,
|
targetRect,
|
||||||
new Rect(0, 0, targetWidth, targetHeight),
|
new Rect(0, 0, targetWidth, targetHeight),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
@ -166,50 +158,4 @@ public class BitmapCropBehaviour implements CropperBehaviour{
|
|||||||
mZoomMatrix.reset();
|
mZoomMatrix.reset();
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Android's conditions for matrix inversion are wacky, and sometimes it just stops working out
|
|
||||||
* of the blue. So, when Android's accelerated matrix inverse dies, just invert by hand.
|
|
||||||
* @param source Source matrix
|
|
||||||
* @param destination The inverse of the source matrix
|
|
||||||
*/
|
|
||||||
protected void inverse(Matrix source, Matrix destination) {
|
|
||||||
if(source.invert(destination)) return;
|
|
||||||
float[] matrix = new float[9];
|
|
||||||
source.getValues(matrix);
|
|
||||||
inverseMatrix(matrix);
|
|
||||||
destination.setValues(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This was made by ChatGPT and i have no clue what's happening here, but it works so eh
|
|
||||||
private static void inverseMatrix(float[] matrix) {
|
|
||||||
float determinant = matrix[0] * (matrix[4] * matrix[8] - matrix[5] * matrix[7])
|
|
||||||
- matrix[1] * (matrix[3] * matrix[8] - matrix[5] * matrix[6])
|
|
||||||
+ matrix[2] * (matrix[3] * matrix[7] - matrix[4] * matrix[6]);
|
|
||||||
|
|
||||||
if (determinant == 0) {
|
|
||||||
throw new IllegalArgumentException("Matrix is not invertible");
|
|
||||||
}
|
|
||||||
|
|
||||||
float invDet = 1 / determinant;
|
|
||||||
|
|
||||||
float temp0 = (matrix[4] * matrix[8] - matrix[5] * matrix[7]);
|
|
||||||
float temp1 = (matrix[2] * matrix[7] - matrix[1] * matrix[8]);
|
|
||||||
float temp2 = (matrix[1] * matrix[5] - matrix[2] * matrix[4]);
|
|
||||||
float temp3 = (matrix[5] * matrix[6] - matrix[3] * matrix[8]);
|
|
||||||
float temp4 = (matrix[0] * matrix[8] - matrix[2] * matrix[6]);
|
|
||||||
float temp5 = (matrix[2] * matrix[3] - matrix[0] * matrix[5]);
|
|
||||||
float temp6 = (matrix[3] * matrix[7] - matrix[4] * matrix[6]);
|
|
||||||
float temp7 = (matrix[1] * matrix[6] - matrix[0] * matrix[7]);
|
|
||||||
float temp8 = (matrix[0] * matrix[4] - matrix[1] * matrix[3]);
|
|
||||||
matrix[0] = temp0 * invDet;
|
|
||||||
matrix[1] = temp1 * invDet;
|
|
||||||
matrix[2] = temp2 * invDet;
|
|
||||||
matrix[3] = temp3 * invDet;
|
|
||||||
matrix[4] = temp4 * invDet;
|
|
||||||
matrix[5] = temp5 * invDet;
|
|
||||||
matrix[6] = temp6 * invDet;
|
|
||||||
matrix[7] = temp7 * invDet;
|
|
||||||
matrix[8] = temp8 * invDet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import android.os.Handler;
|
|||||||
|
|
||||||
import net.kdt.pojavlaunch.PojavApplication;
|
import net.kdt.pojavlaunch.PojavApplication;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.SelfReferencingFuture;
|
import net.kdt.pojavlaunch.modloaders.modpacks.SelfReferencingFuture;
|
||||||
|
import net.kdt.pojavlaunch.utils.MatrixUtils;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ public class RegionDecoderCropBehaviour extends BitmapCropBehaviour {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode a region from this Bitmap based on a subsection in the View coordinate space.
|
* Decoade a region from this Bitmap based on a subsection in the View coordinate space.
|
||||||
* @param targetDrawRect an output Rect. This Rect is the position at which the region must
|
* @param targetDrawRect an output Rect. This Rect is the position at which the region must
|
||||||
* be rendered within subsectionRect.
|
* be rendered within subsectionRect.
|
||||||
* @param subsectionRect the subsection in View coordinate space. Note that this Rect is modified
|
* @param subsectionRect the subsection in View coordinate space. Note that this Rect is modified
|
||||||
@ -46,15 +47,15 @@ public class RegionDecoderCropBehaviour extends BitmapCropBehaviour {
|
|||||||
* @return null if the resulting region is bigger than the original image
|
* @return null if the resulting region is bigger than the original image
|
||||||
* null if the resulting region is completely out of the original image bounds
|
* null if the resulting region is completely out of the original image bounds
|
||||||
* null if the resulting region is smaller than 16x16 pixels
|
* null if the resulting region is smaller than 16x16 pixels
|
||||||
* null if a region decoding error has occurred
|
* null if a region decoding error has occured
|
||||||
* the resulting Bitmap region otherwise.
|
* the resulting Bitmap region otherwise.
|
||||||
*/
|
*/
|
||||||
private Bitmap decodeRegionBitmap(RectF targetDrawRect, RectF subsectionRect) {
|
private Bitmap decodeRegionBitmap(RectF targetDrawRect, RectF subsectionRect) {
|
||||||
RectF decoderRect = new RectF(0, 0, mBitmapDecoder.getWidth(), mBitmapDecoder.getHeight());
|
RectF decoderRect = new RectF(0, 0, mBitmapDecoder.getWidth(), mBitmapDecoder.getHeight());
|
||||||
Matrix matrix = createDecoderImageMatrix();
|
Matrix matrix = createDecoderImageMatrix();
|
||||||
Matrix inverse = new Matrix();
|
Matrix inverse = new Matrix();
|
||||||
inverse(matrix, inverse);
|
MatrixUtils.inverse(matrix, inverse);
|
||||||
transformRect(subsectionRect, inverse);
|
MatrixUtils.transformRect(subsectionRect, inverse);
|
||||||
// If our current sub-section is bigger than the decoder rect, skip.
|
// If our current sub-section is bigger than the decoder rect, skip.
|
||||||
// We do this to avoid unnecessarily loading the image at full resolution.
|
// We do this to avoid unnecessarily loading the image at full resolution.
|
||||||
if(subsectionRect.width() > decoderRect.width()
|
if(subsectionRect.width() > decoderRect.width()
|
||||||
@ -187,25 +188,6 @@ public class RegionDecoderCropBehaviour extends BitmapCropBehaviour {
|
|||||||
return decoderImageMatrix;
|
return decoderImageMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform the coordinates of the Rect using the supplied Matrix.
|
|
||||||
* @param rect the input/output Rect for this operation
|
|
||||||
* @param regionImageInverse the Matrix for transforming the Rect.
|
|
||||||
*/
|
|
||||||
private void transformRect(RectF rect, Matrix regionImageInverse) {
|
|
||||||
if(regionImageInverse.isIdentity()) return;
|
|
||||||
float[] inOutDecodeRect = new float[8];
|
|
||||||
inOutDecodeRect[0] = rect.left;
|
|
||||||
inOutDecodeRect[1] = rect.top;
|
|
||||||
inOutDecodeRect[2] = rect.right;
|
|
||||||
inOutDecodeRect[3] = rect.bottom;
|
|
||||||
regionImageInverse.mapPoints(inOutDecodeRect, 4, inOutDecodeRect, 0, 2);
|
|
||||||
rect.left = inOutDecodeRect[4];
|
|
||||||
rect.top = inOutDecodeRect[5];
|
|
||||||
rect.right = inOutDecodeRect[6];
|
|
||||||
rect.bottom = inOutDecodeRect[7];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bitmap crop(int targetMaxSide) {
|
public Bitmap crop(int targetMaxSide) {
|
||||||
RectF drawRect = new RectF();
|
RectF drawRect = new RectF();
|
||||||
@ -227,7 +209,7 @@ public class RegionDecoderCropBehaviour extends BitmapCropBehaviour {
|
|||||||
float scaleRatio = (float)targetDimension / mHostView.mSelectionRect.width();
|
float scaleRatio = (float)targetDimension / mHostView.mSelectionRect.width();
|
||||||
Matrix drawRectScaleMatrix = new Matrix();
|
Matrix drawRectScaleMatrix = new Matrix();
|
||||||
drawRectScaleMatrix.setScale(scaleRatio, scaleRatio);
|
drawRectScaleMatrix.setScale(scaleRatio, scaleRatio);
|
||||||
transformRect(drawRect, drawRectScaleMatrix);
|
MatrixUtils.transformRect(drawRect, drawRectScaleMatrix);
|
||||||
|
|
||||||
Bitmap returnBitmap = Bitmap.createBitmap(targetDimension, targetDimension, regionBitmap.getConfig());
|
Bitmap returnBitmap = Bitmap.createBitmap(targetDimension, targetDimension, regionBitmap.getConfig());
|
||||||
Canvas canvas = new Canvas(returnBitmap);
|
Canvas canvas = new Canvas(returnBitmap);
|
||||||
|
@ -0,0 +1,178 @@
|
|||||||
|
package net.kdt.pojavlaunch.utils;
|
||||||
|
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class MatrixUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the coordinates of the RectF using the supplied Matrix, and write the result back into
|
||||||
|
* the RectF
|
||||||
|
* @param inOutRect the RectF for this operation
|
||||||
|
* @param transformMatrix the Matrix for transforming the Rect.
|
||||||
|
*/
|
||||||
|
public static void transformRect(Rect inOutRect, Matrix transformMatrix) {
|
||||||
|
transformRect(inOutRect, inOutRect, transformMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the coordinates of the RectF using the supplied Matrix, and write the result back into
|
||||||
|
* the RectF
|
||||||
|
* @param inOutRect the RectF for this operation
|
||||||
|
* @param transformMatrix the Matrix for transforming the Rect.
|
||||||
|
*/
|
||||||
|
public static void transformRect(RectF inOutRect, Matrix transformMatrix) {
|
||||||
|
transformRect(inOutRect, inOutRect, transformMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the coordinates of the input RectF using the supplied Matrix, and write the result
|
||||||
|
* into the output Rect
|
||||||
|
* @param inRect the input RectF for this operation
|
||||||
|
* @param outRect the output Rect for this operation
|
||||||
|
* @param transformMatrix the Matrix for transforming the Rect.
|
||||||
|
*/
|
||||||
|
public static void transformRect(RectF inRect, Rect outRect, Matrix transformMatrix) {
|
||||||
|
float[] inOutDecodeRect = createInOutDecodeRect(transformMatrix);
|
||||||
|
if(inOutDecodeRect == null) return;
|
||||||
|
writeInputRect(inOutDecodeRect, inRect);
|
||||||
|
transformPoints(inOutDecodeRect, transformMatrix);
|
||||||
|
readOutputRect(inOutDecodeRect, outRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the coordinates of the input Rect using the supplied Matrix, and write the result
|
||||||
|
* into the output RectF
|
||||||
|
* @param inRect the input Rect for this operation
|
||||||
|
* @param outRect the output RectF for this operation
|
||||||
|
* @param transformMatrix the Matrix for transforming the Rect.
|
||||||
|
*/
|
||||||
|
public static void transformRect(Rect inRect, RectF outRect, Matrix transformMatrix) {
|
||||||
|
float[] inOutDecodeRect = createInOutDecodeRect(transformMatrix);
|
||||||
|
if(inOutDecodeRect == null) return;
|
||||||
|
writeInputRect(inOutDecodeRect, inRect);
|
||||||
|
transformPoints(inOutDecodeRect, transformMatrix);
|
||||||
|
readOutputRect(inOutDecodeRect, outRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the coordinates of the input Rect using the supplied Matrix, and write the result
|
||||||
|
* into the output Rect
|
||||||
|
* @param inRect the input Rect for this operation
|
||||||
|
* @param outRect the output Rect for this operation
|
||||||
|
* @param transformMatrix the Matrix for transforming the Rect.
|
||||||
|
*/
|
||||||
|
public static void transformRect(Rect inRect, Rect outRect, Matrix transformMatrix) {
|
||||||
|
float[] inOutDecodeRect = createInOutDecodeRect(transformMatrix);
|
||||||
|
if(inOutDecodeRect == null) return;
|
||||||
|
writeInputRect(inOutDecodeRect, inRect);
|
||||||
|
transformPoints(inOutDecodeRect, transformMatrix);
|
||||||
|
readOutputRect(inOutDecodeRect, outRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the coordinates of the input RectF using the supplied Matrix, and write the result
|
||||||
|
* into the output RectF
|
||||||
|
* @param inRect the input RectF for this operation
|
||||||
|
* @param outRect the output RectF for this operation
|
||||||
|
* @param transformMatrix the Matrix for transforming the Rect.
|
||||||
|
*/
|
||||||
|
public static void transformRect(RectF inRect, RectF outRect, Matrix transformMatrix) {
|
||||||
|
float[] inOutDecodeRect = createInOutDecodeRect(transformMatrix);
|
||||||
|
if(inOutDecodeRect == null) return;
|
||||||
|
writeInputRect(inOutDecodeRect, inRect);
|
||||||
|
transformPoints(inOutDecodeRect, transformMatrix);
|
||||||
|
readOutputRect(inOutDecodeRect, outRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The group of functions below are used as building blocks of the transformRect() functions
|
||||||
|
// in order to not repeat the same exact code a lot of times.
|
||||||
|
private static void writeInputRect(float[] inOutDecodeRect, RectF inRect) {
|
||||||
|
inOutDecodeRect[0] = inRect.left;
|
||||||
|
inOutDecodeRect[1] = inRect.top;
|
||||||
|
inOutDecodeRect[2] = inRect.right;
|
||||||
|
inOutDecodeRect[3] = inRect.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeInputRect(float[] inOutDecodeRect, Rect inRect) {
|
||||||
|
inOutDecodeRect[0] = inRect.left;
|
||||||
|
inOutDecodeRect[1] = inRect.top;
|
||||||
|
inOutDecodeRect[2] = inRect.right;
|
||||||
|
inOutDecodeRect[3] = inRect.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readOutputRect(float[] inOutDecodeRect, RectF outRect) {
|
||||||
|
outRect.left = inOutDecodeRect[4];
|
||||||
|
outRect.top = inOutDecodeRect[5];
|
||||||
|
outRect.right = inOutDecodeRect[6];
|
||||||
|
outRect.bottom = inOutDecodeRect[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readOutputRect(float[] inOutDecodeRect, Rect outRect) {
|
||||||
|
outRect.left = (int)inOutDecodeRect[4];
|
||||||
|
outRect.top = (int)inOutDecodeRect[5];
|
||||||
|
outRect.right = (int)inOutDecodeRect[6];
|
||||||
|
outRect.bottom = (int)inOutDecodeRect[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float[] createInOutDecodeRect(Matrix transformMatrix) {
|
||||||
|
if(transformMatrix.isIdentity()) return null;
|
||||||
|
// We need an array of 8 floats because each point is two floats,
|
||||||
|
// we need to transform two points and we need to have a separated input and output
|
||||||
|
return new float[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void transformPoints(float[] inOutDecodeRect, Matrix transformMatrix) {
|
||||||
|
transformMatrix.mapPoints(inOutDecodeRect, 4, inOutDecodeRect, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invert the source matrix, and write the result into the destination matrix.
|
||||||
|
* Android's integrated Matrix.invert() has some unexpected conditions when the matrix
|
||||||
|
* can't be inverted, and in that case the method inverts the matrix by hand.
|
||||||
|
* @param source Source matrix
|
||||||
|
* @param destination The inverse of the source matrix
|
||||||
|
* @throws IllegalArgumentException when the matrix is not invertible
|
||||||
|
*/
|
||||||
|
public static void inverse(Matrix source, Matrix destination) throws IllegalArgumentException {
|
||||||
|
if(source.invert(destination)) return;
|
||||||
|
float[] matrix = new float[9];
|
||||||
|
source.getValues(matrix);
|
||||||
|
inverseMatrix(matrix);
|
||||||
|
destination.setValues(matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This was made by ChatGPT and i have no clue what's happening here, but it works so eh
|
||||||
|
private static void inverseMatrix(float[] matrix) {
|
||||||
|
float determinant = matrix[0] * (matrix[4] * matrix[8] - matrix[5] * matrix[7])
|
||||||
|
- matrix[1] * (matrix[3] * matrix[8] - matrix[5] * matrix[6])
|
||||||
|
+ matrix[2] * (matrix[3] * matrix[7] - matrix[4] * matrix[6]);
|
||||||
|
|
||||||
|
if (determinant == 0) {
|
||||||
|
throw new IllegalArgumentException("Matrix is not invertible");
|
||||||
|
}
|
||||||
|
|
||||||
|
float invDet = 1 / determinant;
|
||||||
|
|
||||||
|
float temp0 = (matrix[4] * matrix[8] - matrix[5] * matrix[7]);
|
||||||
|
float temp1 = (matrix[2] * matrix[7] - matrix[1] * matrix[8]);
|
||||||
|
float temp2 = (matrix[1] * matrix[5] - matrix[2] * matrix[4]);
|
||||||
|
float temp3 = (matrix[5] * matrix[6] - matrix[3] * matrix[8]);
|
||||||
|
float temp4 = (matrix[0] * matrix[8] - matrix[2] * matrix[6]);
|
||||||
|
float temp5 = (matrix[2] * matrix[3] - matrix[0] * matrix[5]);
|
||||||
|
float temp6 = (matrix[3] * matrix[7] - matrix[4] * matrix[6]);
|
||||||
|
float temp7 = (matrix[1] * matrix[6] - matrix[0] * matrix[7]);
|
||||||
|
float temp8 = (matrix[0] * matrix[4] - matrix[1] * matrix[3]);
|
||||||
|
matrix[0] = temp0 * invDet;
|
||||||
|
matrix[1] = temp1 * invDet;
|
||||||
|
matrix[2] = temp2 * invDet;
|
||||||
|
matrix[3] = temp3 * invDet;
|
||||||
|
matrix[4] = temp4 * invDet;
|
||||||
|
matrix[5] = temp5 * invDet;
|
||||||
|
matrix[6] = temp6 * invDet;
|
||||||
|
matrix[7] = temp7 * invDet;
|
||||||
|
matrix[8] = temp8 * invDet;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user