122 lines
5.0 KiB
Java
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);
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|