2025-11-24 22:52:51 +03:00

122 lines
5.0 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* it.unimi.dsi.fastutil.ints.IntConsumer
* org.apache.commons.lang3.mutable.MutableLong
* org.jspecify.annotations.Nullable
* org.lwjgl.system.MemoryUtil
*/
package com.mojang.blaze3d.vertex;
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import com.mojang.blaze3d.vertex.CompactVectorArray;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement;
import com.mojang.blaze3d.vertex.VertexSorting;
import it.unimi.dsi.fastutil.ints.IntConsumer;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import org.apache.commons.lang3.mutable.MutableLong;
import org.jspecify.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;
public class MeshData
implements AutoCloseable {
private final ByteBufferBuilder.Result vertexBuffer;
private @Nullable ByteBufferBuilder.Result indexBuffer;
private final DrawState drawState;
public MeshData(ByteBufferBuilder.Result vertexBuffer, DrawState drawState) {
this.vertexBuffer = vertexBuffer;
this.drawState = drawState;
}
private static CompactVectorArray unpackQuadCentroids(ByteBuffer vertexBuffer, int vertices, VertexFormat format) {
int positionOffset = format.getOffset(VertexFormatElement.POSITION);
if (positionOffset == -1) {
throw new IllegalArgumentException("Cannot identify quad centers with no position element");
}
FloatBuffer floatBuffer = vertexBuffer.asFloatBuffer();
int vertexStride = format.getVertexSize() / 4;
int quadStride = vertexStride * 4;
int quads = vertices / 4;
CompactVectorArray sortingPoints = new CompactVectorArray(quads);
for (int i = 0; i < quads; ++i) {
int firstPosOffset = i * quadStride + positionOffset;
int secondPosOffset = firstPosOffset + vertexStride * 2;
float x0 = floatBuffer.get(firstPosOffset + 0);
float y0 = floatBuffer.get(firstPosOffset + 1);
float z0 = floatBuffer.get(firstPosOffset + 2);
float x1 = floatBuffer.get(secondPosOffset + 0);
float y1 = floatBuffer.get(secondPosOffset + 1);
float z1 = floatBuffer.get(secondPosOffset + 2);
float xMid = (x0 + x1) / 2.0f;
float yMid = (y0 + y1) / 2.0f;
float zMid = (z0 + z1) / 2.0f;
sortingPoints.set(i, xMid, yMid, zMid);
}
return sortingPoints;
}
public ByteBuffer vertexBuffer() {
return this.vertexBuffer.byteBuffer();
}
public @Nullable ByteBuffer indexBuffer() {
return this.indexBuffer != null ? this.indexBuffer.byteBuffer() : null;
}
public DrawState drawState() {
return this.drawState;
}
public @Nullable SortState sortQuads(ByteBufferBuilder indexBufferTarget, VertexSorting sorting) {
if (this.drawState.mode() != VertexFormat.Mode.QUADS) {
return null;
}
CompactVectorArray centroids = MeshData.unpackQuadCentroids(this.vertexBuffer.byteBuffer(), this.drawState.vertexCount(), this.drawState.format());
SortState sortState = new SortState(centroids, this.drawState.indexType());
this.indexBuffer = sortState.buildSortedIndexBuffer(indexBufferTarget, sorting);
return sortState;
}
@Override
public void close() {
this.vertexBuffer.close();
if (this.indexBuffer != null) {
this.indexBuffer.close();
}
}
public record DrawState(VertexFormat format, int vertexCount, int indexCount, VertexFormat.Mode mode, VertexFormat.IndexType indexType) {
}
public record SortState(CompactVectorArray centroids, VertexFormat.IndexType indexType) {
public @Nullable ByteBufferBuilder.Result buildSortedIndexBuffer(ByteBufferBuilder target, VertexSorting sorting) {
int[] startIndices = sorting.sort(this.centroids);
long pointer = target.reserve(startIndices.length * 6 * this.indexType.bytes);
IntConsumer indexWriter = this.indexWriter(pointer, this.indexType);
for (int startIndex : startIndices) {
indexWriter.accept(startIndex * 4 + 0);
indexWriter.accept(startIndex * 4 + 1);
indexWriter.accept(startIndex * 4 + 2);
indexWriter.accept(startIndex * 4 + 2);
indexWriter.accept(startIndex * 4 + 3);
indexWriter.accept(startIndex * 4 + 0);
}
return target.build();
}
private IntConsumer indexWriter(long pointer, VertexFormat.IndexType indexType) {
MutableLong nextIndex = new MutableLong(pointer);
return switch (indexType) {
default -> throw new MatchException(null, null);
case VertexFormat.IndexType.SHORT -> value -> MemoryUtil.memPutShort((long)nextIndex.getAndAdd(2L), (short)((short)value));
case VertexFormat.IndexType.INT -> value -> MemoryUtil.memPutInt((long)nextIndex.getAndAdd(4L), (int)value);
};
}
}
}