From 64f57e86a34902fd38f55809185551f97a46ae1b Mon Sep 17 00:00:00 2001 From: PenguinEncounter <49845522+penguinencounter@users.noreply.github.com> Date: Thu, 12 Sep 2024 22:12:12 -0700 Subject: [PATCH] Reduce scope - remove applyFilter because of performance issues and general 'who would ever use this' - remove FlexibleMatrix and FlexibleVector because they are now unused and maybe another PR should implement them instead --- .../figura/math/matrix/FlexibleMatrix.java | 403 ------------------ .../figura/math/vector/FlexibleVector.java | 227 ---------- .../rendering/texture/FiguraTexture.java | 80 ---- 3 files changed, 710 deletions(-) delete mode 100644 common/src/main/java/org/figuramc/figura/math/matrix/FlexibleMatrix.java delete mode 100644 common/src/main/java/org/figuramc/figura/math/vector/FlexibleVector.java diff --git a/common/src/main/java/org/figuramc/figura/math/matrix/FlexibleMatrix.java b/common/src/main/java/org/figuramc/figura/math/matrix/FlexibleMatrix.java deleted file mode 100644 index 015d377c1..000000000 --- a/common/src/main/java/org/figuramc/figura/math/matrix/FlexibleMatrix.java +++ /dev/null @@ -1,403 +0,0 @@ -package org.figuramc.figura.math.matrix; - -import org.figuramc.figura.math.vector.FiguraVector; -import org.figuramc.figura.math.vector.FlexibleVector; -import org.jetbrains.annotations.Contract; - -/** - * Not a Lua API, but used internally for things like image filtering. - * (read: I needed a 5*5 matrix and decided to generalize) - */ -public class FlexibleMatrix extends FiguraMatrix { - /** - * index internal[ROW][COL] or internal[Y][X] - */ - private final double[][] internal; - /** - * index internalTranspose[COL][ROW] or internal[X][Y] - */ - private final double[][] internalTranspose; - public final int width, height; - - public double[][] copyInternal() { - double[][] clone = new double[height][width]; - for (int y = 0; y < height; y++) clone[y] = internal[y].clone(); - return clone; - } - - public FlexibleMatrix(int width, int height) { - internal = new double[height][width]; - internalTranspose = new double[width][height]; - this.width = width; - this.height = height; - } - - public static , MatrixT extends FiguraMatrix> FlexibleMatrix from( - MatrixT mat) { - if (mat instanceof FlexibleMatrix) return (FlexibleMatrix) mat; - int width = mat.cols(); - int height = mat.rows(); - FlexibleMatrix newMat = new FlexibleMatrix(width, height); - newMat.lenientCopyFrom(mat); - return newMat; - } - - private void regenerateTranspose() { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - internalTranspose[x][y] = internal[y][x]; - } - } - } - - private void regenerateTransposeReverse() { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - internal[y][x] = internalTranspose[x][y]; - } - } - } - - private static , T2 extends FiguraMatrix> void assertSameSize(T1 left, - T2 right) { - if (left.rows() != right.rows() || left.cols() != right.cols()) - throw new IllegalArgumentException(String.format( - "both matrices need to be the same size, but one is %dx%d and the other is %dx%d", - left.cols(), left.rows(), right.cols(), right.rows() - )); - } - - private static void assertSameSize(FlexibleMatrix left, FlexibleMatrix right) { - if (left.width != right.width || left.height != right.height) throw new IllegalArgumentException(String.format( - "both matrices need to be the same size, but one is %dx%d and the other is %dx%d", - left.width, left.height, right.width, right.height - )); - } - - @Override - @Contract("-> fail") - public double det() { - throw new IllegalStateException("det() not supported on FlexibleMatrix"); - } - - @Override - @Contract("-> fail") - protected double calculateDeterminant() { - throw new IllegalStateException("det() not supported on FlexibleMatrix"); - } - - @Override - protected void resetIdentity() { - if (width == height) { - for (int xy = 0; xy < height; xy++) { - internal[xy] = new double[width]; - internal[xy][xy] = 1; - internalTranspose[xy] = new double[height]; - internalTranspose[xy][xy] = 1; - } - } else throw new IllegalStateException("cannot reset to identity non-square matrix"); - } - - public void strictCopyFrom(FlexibleMatrix source) { - assertSameSize(this, source); - lenientCopyFrom(source); - } - - public , MatrixT extends FiguraMatrix> - void strictCopyFrom(MatrixT source) { - assertSameSize(this, source); - lenientCopyFrom(source); - } - - public void lenientCopyFrom(FlexibleMatrix source) { - // fastest (no recalculation of the transpose) - if (source.width == this.width && source.height == this.height) { - for (int y = 0; y < height; y++) { - internal[y] = source.internal[y].clone(); - } - for (int x = 0; x < width; x++) { - internalTranspose[x] = source.internalTranspose[x].clone(); - } - return; - } - // faster? - if (source.height == this.height) { - for (int x = 0; x < Math.min(width, source.width); x++) { - internalTranspose[x] = source.internalTranspose[x].clone(); - } - regenerateTransposeReverse(); - return; - } - if (source.width == this.width) { - for (int y = 0; y < Math.min(height, source.height); y++) { - internal[y] = source.internal[y].clone(); - } - regenerateTranspose(); - return; - } - - for (int y = 0; y < Math.min(height, source.height); y++) { - for (int x = 0; x < Math.min(width, source.width); y++) { - internal[y][x] = source.internal[y][x]; - internalTranspose[x][y] = source.internalTranspose[x][y]; - } - } - } - - public , MatrixT extends FiguraMatrix> - void lenientCopyFrom(MatrixT source) { - if (source.rows() == height && source.cols() == width) { - for (int y = 0; y < height; y++) { - // this had BETTER clone it - double[] row = source.getRow(y + 1).unpack(); - if (row.length != width) throw new IllegalArgumentException(String.format( - "inconsistent info: cols() says the width is %d, but unpack() says it's %d", - width, row.length - )); - internal[y] = row; - } - for (int x = 0; x < width; x++) { - double[] col = source.getColumn(x + 1).unpack(); - if (col.length != height) throw new IllegalArgumentException(String.format( - "inconsistent info: rows() says the height is %d, but unpack() says it's %d", - height, col.length - )); - internalTranspose[x] = col; - } - return; - } - if (source.rows() == height) { - // copy columns into transpose table and then flip it - for (int x = 0; x < Math.min(width, source.cols()); x++) { - double[] col = source.getColumn(x + 1).unpack(); - if (col.length != height) throw new IllegalArgumentException(String.format( - "inconsistent info: rows() says the height is %d, but unpack() says it's %d", - height, col.length - )); - internalTranspose[x] = col; - } - regenerateTransposeReverse(); - return; - } - if (source.cols() == width) { - // same but with rows - for (int y = 0; y < Math.min(height, source.rows()); y++) { - double[] row = source.getRow(y + 1).unpack(); - if (row.length != width) throw new IllegalArgumentException(String.format( - "inconsistent info: cols() says the width is %d, but unpack() says it's %d", - width, row.length - )); - internal[y] = row; - } - regenerateTranspose(); - return; - } - // just iterate - for (int y = 0; y < Math.min(height, source.rows()); y++) { - double[] row = source.getRow(y + 1).unpack(); - // don't risk an out-of-bounds index - for (int x = 0; x < Math.min(width, row.length); x++) { - internal[y][x] = row[x]; - internalTranspose[x][y] = row[x]; - } - } - } - - @Override - @Contract(value = "-> new") - public FlexibleMatrix copy() { - FlexibleMatrix newMat = new FlexibleMatrix(width, height); - for (int y = 0; y < height; y++) newMat.internal[y] = internal[y].clone(); - for (int x = 0; x < width; x++) newMat.internalTranspose[x] = internalTranspose[x].clone(); - return newMat; - } - - @Override - public boolean equals(FlexibleMatrix other) { - if (other == null) return false; - if (other.width != width || other.height != height) return false; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - if (internal[y][x] != other.internal[y][x]) return false; - } - } - return true; - } - - @Override - public FlexibleVector getColumn(int col) { - return FlexibleVector.of(internalTranspose[col - 1]); - } - - @Override - public FlexibleVector getRow(int row) { - return FlexibleVector.of(internal[row - 1]); - } - - @Override - public int rows() { - return height; - } - - @Override - public int cols() { - return width; - } - - @Override - @Contract(value = "_ -> this") - public FlexibleMatrix set(FlexibleMatrix o) { - strictCopyFrom(o); - return this; - } - - public FlexibleMatrix set(double[][] items) { - return set(FlexibleMatrix.of(items)); - } - - /** - * Expects items[Y][X]; height is {@code items.length} and width is {@code items[0].length} (or 0 if empty) - * - * @param items values to create with - * @return new matrix - */ - @Contract("_ -> new") - public static FlexibleMatrix of(double[][] items) { - int height = items.length; - if (height == 0) return new FlexibleMatrix(0, 0); - int width = items[0].length; - FlexibleMatrix target = new FlexibleMatrix(width, height); - for (int y = 0; y < height; y++) { - target.internal[y] = items[y].clone(); - } - target.regenerateTranspose(); - return target; - } - - public void put(int y, int x, double value) { - if (y > height || y < 0) throw new IllegalArgumentException(String.format( - "y (%d) out of range [0, %d)", - y, height - )); - if (x > width || x < 0) throw new IllegalArgumentException(String.format( - "x (%d) out of range [0, %d)", - x, width - )); - internal[y][x] = value; - internalTranspose[x][y] = value; - } - - public double get(int y, int x) { - if (y > height || y < 0) throw new IllegalArgumentException(String.format( - "y (%d) out of range [0, %d)", - y, height - )); - if (x > width || x < 0) throw new IllegalArgumentException(String.format( - "x (%d) out of range [0, %d)", - x, width - )); - return internal[y][x]; - } - - /** - * Flips the matrix vertically. - */ - public void flipVertical() { - double[][] backup = internal.clone(); // retains refs - for (int ySrc = height - 1, yDst = 0; ySrc >= 0; ySrc--, yDst++) { - internal[yDst] = backup[ySrc]; - } - regenerateTranspose(); - } - /** - * Flips the matrix horizontally. - */ - public void flipHorizontal() { - double[][] backup = internalTranspose.clone(); - for (int xSrc = width - 1, xDst = 0; xSrc >= 0; xSrc--, xDst++) { - internalTranspose[xDst] = backup[xSrc]; - } - regenerateTransposeReverse(); - } - - /** - * Watch out - makes a copy! - * - * @param right right side of multiplication - * @return result - */ - @Override - @Contract("_ -> new") - public FlexibleMatrix multiply(FlexibleMatrix right) { - if (width != right.height) throw new IllegalArgumentException(String.format( - "cannot multiply matrices: [%d]x%d times %dx[%d]: [bracketed numbers] need to match", - width, height, right.width, right.height - )); - FlexibleMatrix output = new FlexibleMatrix(right.width, height); - for (int rowY = 0; rowY < height; rowY++) { - for (int colX = 0; colX < right.width; colX++) { - output.put(rowY, colX, getRow(rowY).dot(right.getColumn(colX))); - } - } - return output; - } - - /** - * Watch out - makes a copy! - * - * @param left left side of multiplication - * @return result - */ - @Override - @Contract("_ -> new") - public FlexibleMatrix rightMultiply(FlexibleMatrix left) { - return left.multiply(this); - } - - /** - * WATCH OUT! this makes a copy! and doesn't mutate! - * - * @return the new, transposed matrix - */ - @Override - @Contract("-> new") - public FlexibleMatrix transpose() { - @SuppressWarnings("SuspiciousNameCombination") // yes they're switched - FlexibleMatrix target = new FlexibleMatrix(height, width); - for (int y = 0; y < height; y++) target.internalTranspose[y] = internal[y].clone(); - for (int x = 0; x < width; x++) target.internal[x] = internalTranspose[x].clone(); - return target; - } - - @Override - @Contract("-> fail") - public FlexibleMatrix invert() { - throw new IllegalStateException("invert() not supported on FlexibleMatrix"); - } - - @Override - @Contract(value = "_ -> this") - public FlexibleMatrix add(FlexibleMatrix o) { - assertSameSize(this, o); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - internal[y][x] += o.internal[y][x]; - internalTranspose[y][x] += o.internalTranspose[y][x]; - } - } - return this; - } - - @Override - @Contract(value = "_ -> this") - public FlexibleMatrix sub(FlexibleMatrix o) { - assertSameSize(this, o); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - internal[y][x] -= o.internal[y][x]; - internalTranspose[y][x] -= o.internalTranspose[y][x]; - } - } - return this; - } -} diff --git a/common/src/main/java/org/figuramc/figura/math/vector/FlexibleVector.java b/common/src/main/java/org/figuramc/figura/math/vector/FlexibleVector.java deleted file mode 100644 index 72717d330..000000000 --- a/common/src/main/java/org/figuramc/figura/math/vector/FlexibleVector.java +++ /dev/null @@ -1,227 +0,0 @@ -package org.figuramc.figura.math.vector; - -import org.figuramc.figura.math.matrix.FlexibleMatrix; - -public class FlexibleVector extends FiguraVector { - private final double[] internal; - public final int size; - - public FlexibleVector(int size) { - internal = new double[size]; - this.size = size; - } - - public static > FlexibleVector from(VectorT vector) { - if (vector instanceof FlexibleVector) return (FlexibleVector) vector; - int size = vector.size(); - FlexibleVector v = new FlexibleVector(size); - v.lenientCopyFrom(vector); - return v; - } - - @Override - public double lengthSquared() { - return 0; - } - - private static , T2 extends FiguraVector> void assertSizeEqual(T1 left, - T2 right) { - if (left.size() != right.size()) throw new IllegalArgumentException(String.format( - "both vectors need to be the same size, but one is %d and the other is %d", - left.size(), right.size() - )); - } - - private static void assertSizeEqual(FlexibleVector left, FlexibleVector right) { - if (left.size != right.size) throw new IllegalArgumentException(String.format( - "both vectors need to be the same size, but one is %d and the other is %d", - left.size, right.size - )); - } - - public void strictCopyFrom(FlexibleVector source) { - assertSizeEqual(this, source); - System.arraycopy(source.internal, 0, internal, 0, size); - } - - public > void strictCopyFrom(T source) { - assertSizeEqual(this, source); - lenientCopyFrom(source); - } - - /** - * Copies values from the FlexibleVector in 'source'. - *
    - *
  • If the source and target vectors are the same size, behaves as in {@code strictCopyFrom}.
  • - *
  • If the source vector is smaller than the target vector, all values are copied starting at index 0, and - * values not copied from the source are left unchanged.
  • - *
  • If the source vector is larger than the target vector, extra values in the source vector are discarded.
  • - *
- * - * @param source Source vector. - */ - public void lenientCopyFrom(FlexibleVector source) { - System.arraycopy(source.internal, 0, internal, 0, Math.min(size, source.size)); - } - - public > void lenientCopyFrom(T source) { - double[] array = source.unpack(); - System.arraycopy(array, 0, internal, 0, Math.min(size, source.size())); - } - - @Override - public FlexibleVector copy() { - FlexibleVector newVec = new FlexibleVector(size); - newVec.lenientCopyFrom(this); - return newVec; - } - - @Override - public double dot(FlexibleVector other) { - assertSizeEqual(this, other); - double total = 0.0; - for (int i = 0; i < size; i++) { - total += internal[i] * other.internal[i]; - } - return total; - } - - @Override - public FlexibleVector set(FlexibleVector other) { - strictCopyFrom(other); - return this; - } - - @Override - public FlexibleVector add(FlexibleVector other) { - assertSizeEqual(this, other); - for (int i = 0; i < size; i++) { - internal[i] += other.internal[i]; - } - return this; - } - - @Override - public FlexibleVector subtract(FlexibleVector other) { - assertSizeEqual(this, other); - for (int i = 0; i < size; i++) { - internal[i] -= other.internal[i]; - } - return this; - } - - @Override - public FlexibleVector offset(double factor) { - for (int i = 0; i < size; i++) { - internal[i] += factor; - } - return this; - } - - @Override - public FlexibleVector multiply(FlexibleVector other) { - assertSizeEqual(this, other); - for (int i = 0; i < size; i++) { - internal[i] *= other.internal[i]; - } - return this; - } - - @Override - public FlexibleVector transform(FlexibleMatrix mat) { - return mat.multiply(asColumnMatrix()).getColumn(1); - } - - public FlexibleMatrix asColumnMatrix() { - double[][] rows = new double[size][1]; - for (int i = 0; i < size; i++) { - rows[i][1] = internal[i]; - } - return FlexibleMatrix.of(rows); - } - - @Override - public FlexibleVector divide(FlexibleVector other) { - assertSizeEqual(this, other); - for (int i = 0; i < size; i++) { - internal[i] /= other.internal[i]; - } - return this; - } - - @Override - public FlexibleVector reduce(FlexibleVector other) { - assertSizeEqual(this, other); - for (int i = 0; i < size; i++) { - double m = other.internal[i]; - // mod (positive remainder) - internal[i] = (((internal[i] % m) + m) % m); - } - return this; - } - - @Override - public FlexibleVector scale(double factor) { - for (int i = 0; i < size; i++) { - internal[i] *= factor; - } - return this; - } - - @Override - public double[] unpack() { - return internal.clone(); - } - - @Override - public int size() { - return size; - } - - @Override - public double index(int i) { - return internal[i]; - } - - @Override - public boolean equals(Object other) { - if (other == null) return false; - if (other instanceof FiguraVector) { - FiguraVector v = (FiguraVector) other; - double[] otherArr = v.unpack(); - if (otherArr.length != size) return false; - for (int i = 0; i < size; i++) { - // strict double equality? in MY math types? - if (otherArr[i] != internal[i]) return false; - } - return true; - } - return false; - } - - @Override - public String toString() { - StringBuilder preview = new StringBuilder(); - boolean commaFlag = false; - final int LIMIT = 5; - for (int i = 0; i < Math.min(size, LIMIT); i++) { - if (commaFlag) { - preview.append(", "); - } else { - commaFlag = true; - } - preview.append(String.format("%.4f", internal[i])); - } - if (size > LIMIT) preview.append(", ..."); - return String.format( - "FlexibleVector<%d>{%s}", - size, preview - ); - } - - public static FlexibleVector of(double... values) { - FlexibleVector o = new FlexibleVector(values.length); - System.arraycopy(o.internal, 0, values, 0, values.length); - return o; - } -} diff --git a/common/src/main/java/org/figuramc/figura/model/rendering/texture/FiguraTexture.java b/common/src/main/java/org/figuramc/figura/model/rendering/texture/FiguraTexture.java index 340016725..77ccefd5f 100644 --- a/common/src/main/java/org/figuramc/figura/model/rendering/texture/FiguraTexture.java +++ b/common/src/main/java/org/figuramc/figura/model/rendering/texture/FiguraTexture.java @@ -17,12 +17,9 @@ import org.figuramc.figura.lua.docs.LuaMethodOverload; import org.figuramc.figura.lua.docs.LuaTypeDoc; import org.figuramc.figura.math.matrix.FiguraMat4; -import org.figuramc.figura.math.matrix.FiguraMatrix; -import org.figuramc.figura.math.matrix.FlexibleMatrix; import org.figuramc.figura.math.vector.FiguraVec2; import org.figuramc.figura.math.vector.FiguraVec3; import org.figuramc.figura.math.vector.FiguraVec4; -import org.figuramc.figura.math.vector.FiguraVector; import org.figuramc.figura.mixin.render.TextureManagerAccessor; import org.figuramc.figura.utils.ColorUtils; import org.figuramc.figura.utils.FiguraIdentifier; @@ -173,83 +170,6 @@ public ResourceLocation getLocation() { return this.location; } - public , V extends FiguraVector> void applyFilter( - AnyMatrix kernel) { - applyFilter(kernel, false, null); - } - - public , V extends FiguraVector> void applyFilter( - AnyMatrix kernel, - boolean withAlpha) { - applyFilter(kernel, withAlpha, null); - } - - public , V extends FiguraVector> void applyFilter( - AnyMatrix kernel, - boolean withAlpha, - @Nullable Pair origin) { - FlexibleMatrix flex = FlexibleMatrix.from(kernel); - flex.flipVertical(); - flex.flipHorizontal(); - double[][] direct = flex.copyInternal(); - int kWidth = flex.width; - int kHeight = flex.height; - if (origin == null) { - if (kWidth % 2 == 1 && kHeight % 2 == 1) { - // integer division rounding down - origin = Pair.of(kWidth / 2, kHeight / 2); - } else { - throw new IllegalArgumentException( - "cannot infer kernel origin because it doesn't have a definite center; provide a second argument to specify manually"); - } - } - int originX = origin.getFirst(), originY = origin.getSecond(); - WriteOverflowStrategy original = writeOverflowStrategy; - // We're necessarily going to be doing some out-of-bounds reads here - writeOverflowStrategy = WriteOverflowStrategy.CLAMP; - try { - int imgWidth = getWidth(), imgHeight = getHeight(); - // this is the target image - int[][] outputBuffer = new int[imgHeight][imgWidth]; - for (int x = 0; x < imgWidth; x++) { - for (int y = 0; y < imgHeight; y++) { - double rAcc = 0.0, gAcc = 0.0, bAcc = 0.0, aAcc = 0.0; - for (int kx = 0; kx < kWidth; kx++) { - for (int ky = 0; ky < kHeight; ky++) { - int relKX = kx - originX, relKY = ky - originY; - Pair actual = mapCoordinates(x + relKX, y + relKY); - if (actual == null) throw new IllegalStateException("???"); - int actualX = actual.getFirst(), actualY = actual.getSecond(); - FiguraVec4 unpacked = getActualPixel(actualX, actualY); - unpacked.scale(direct[ky][kx]); - rAcc += unpacked.x; - gAcc += unpacked.y; - bAcc += unpacked.z; - aAcc += unpacked.w; - } - } - rAcc = clamp01(rAcc); - gAcc = clamp01(gAcc); - bAcc = clamp01(bAcc); - if (!withAlpha) { - aAcc = (texture.getPixelRGBA(x, y) >> 24 & 0xff) / (double) 0xff; - } else { - aAcc = clamp01(rAcc); - } - outputBuffer[y][x] = (int) (aAcc * 0xff) << 24 | (int) (bAcc * 0xff) << 16 | (int) (gAcc * 0xff) << 8 | (int) (rAcc * 0xff); - } - } - backupImage(); - for (int y = 0; y < imgHeight; y++) { - for (int x = 0; x < imgWidth; x++) { - setActualPixel(x, y, outputBuffer[y][x], false); - } - } - } finally { - writeOverflowStrategy = original; - } - } - // -- lua stuff -- //