bluehorizons

Untitled

May 4th, 2026
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.34 KB | None | 0 0
  1. package william.starsight.graphics.mesh;
  2.  
  3. import org.jetbrains.annotations.NotNull;
  4. import org.joml.Vector3f;
  5.  
  6. import java.util.Arrays;
  7.  
  8. import static org.lwjgl.opengl.GL43.*;
  9.  
  10. /**
  11.  * This specifically assumes a vertex format of POS, UV, NORMALS, and is not meant to be used for entity models. A different Tesselator class should cover that
  12.  */
  13. public class Tesselator {
  14.     private static final int[] premadeIndices = new int[4194304]; // Filling up the premade indices. I need to document my choice of numbers
  15.  
  16.     static {
  17.         int one = 0;
  18.         int two = 1;
  19.         int three = 2;
  20.         int four = 2;
  21.         int five = 3;
  22.         int six = 0;
  23.         for (int i = 0; i < premadeIndices.length - 6;) { // The incrementation logic is better inside the loop code. I love side effects when they can be used properly!
  24.             premadeIndices[i++] = one; // Readability :D
  25.             premadeIndices[i++] = two;
  26.             premadeIndices[i++] = three;
  27.             premadeIndices[i++] = four;
  28.             premadeIndices[i++] = five;
  29.             premadeIndices[i++] /* I learned this secret technique from poorly written C code :D */ = six;
  30.             one += 4;
  31.             two += 4;
  32.             three += 4;
  33.             four += 4;
  34.             five += 4;
  35.             six += 4;
  36.         }
  37.     }
  38.  
  39.     private final float[] buffer;
  40.     private int bufferPosition;
  41.     private int quadCount;
  42.  
  43.     public Tesselator() {
  44.         this((int) (32 * 32 * 32 * 24 * 1.25)); // Default capacity
  45.     }
  46.  
  47.     public Tesselator(int startingCapacity) {
  48.         buffer = new float[startingCapacity];
  49.         bufferPosition = 0;
  50.         quadCount = 0;
  51.     }
  52.  
  53.     public void setOrientation(Orientation o) { // TODO Is this needed at all? Does this even belong in this class?? what was past self thinking!? FRONT FACE IS A GLOBAL STATE AND THE Tesselator CAN'T TOUCH IT.
  54.         glFrontFace(o == Orientation.CW ? GL_CW : GL_CCW);
  55.     }
  56.  
  57.     public enum Orientation {
  58.         CW,
  59.         CCW
  60.     }
  61.  
  62.     @SuppressWarnings("UnnecessaryBreak") // IntelliJ, buddy, you are wrong here.
  63.     public void addQuad(float x, float y, float z, @NotNull QuadDirection direction, float width, float height, float minU, float minV, float maxU, float maxV) {
  64.         float nX = direction.x();
  65.         float nY = direction.y();
  66.         float nZ = direction.z();
  67.  
  68.         float x1, x2, x3, x4;
  69.         float y1, y2, y3, y4;
  70.         float z1, z2, z3, z4;
  71.         float widthHalf = width / 2.0f;
  72.         float heightHalf = height / 2.0f;
  73.  
  74.         switch (direction) {
  75.             case NEG_X -> {
  76.                 x1 = x;
  77.                 x2 = x;
  78.                 x3 = x;
  79.                 x4 = x;
  80.                 y1 = y - heightHalf;
  81.                 y2 = y - heightHalf;
  82.                 y3 = y + heightHalf;
  83.                 y4 = y + heightHalf;
  84.                 z1 = z - widthHalf;
  85.                 z2 = z + widthHalf;
  86.                 z3 = z + widthHalf;
  87.                 z4 = z - widthHalf;
  88.                 break;
  89.             }
  90.             case NEG_Y -> {
  91.                 x1 = x - widthHalf;
  92.                 x2 = x - widthHalf;
  93.                 x3 = x + widthHalf;
  94.                 x4 = x + widthHalf;
  95.                 y1 = y;
  96.                 y2 = y;
  97.                 y3 = y;
  98.                 y4 = y;
  99.                 z1 = z + heightHalf;
  100.                 z2 = z - heightHalf;
  101.                 z3 = z - heightHalf;
  102.                 z4 = z + heightHalf;
  103.                 break;
  104.             }
  105.             case NEG_Z -> {
  106.                 x1 = x + widthHalf;
  107.                 x2 = x - widthHalf;
  108.                 x3 = x - widthHalf;
  109.                 x4 = x + widthHalf;
  110.                 y1 = y - heightHalf;
  111.                 y2 = y - heightHalf;
  112.                 y3 = y + heightHalf;
  113.                 y4 = y + heightHalf;
  114.                 z1 = z;
  115.                 z2 = z;
  116.                 z3 = z;
  117.                 z4 = z;
  118.                 break;
  119.             }
  120.             case POS_X -> {
  121.                 x1 = x;
  122.                 x2 = x;
  123.                 x3 = x;
  124.                 x4 = x;
  125.                 y1 = y - heightHalf;
  126.                 y2 = y - heightHalf;
  127.                 y3 = y + heightHalf;
  128.                 y4 = y + heightHalf;
  129.                 z1 = z + widthHalf;
  130.                 z2 = z - widthHalf;
  131.                 z3 = z - widthHalf;
  132.                 z4 = z + widthHalf;
  133.                 break;
  134.             }
  135.             case POS_Y -> {
  136.                 x1 = x - widthHalf;
  137.                 x2 = x - widthHalf;
  138.                 x3 = x + widthHalf;
  139.                 x4 = x + widthHalf;
  140.                 y1 = y;
  141.                 y2 = y;
  142.                 y3 = y;
  143.                 y4 = y;
  144.                 z1 = z - heightHalf;
  145.                 z2 = z + heightHalf;
  146.                 z3 = z + heightHalf;
  147.                 z4 = z - heightHalf;
  148.                 break;
  149.             }
  150.             case POS_Z -> {
  151.                 x1 = x - widthHalf;
  152.                 x2 = x + widthHalf;
  153.                 x3 = x + widthHalf;
  154.                 x4 = x - widthHalf;
  155.                 y1 = y - heightHalf;
  156.                 y2 = y - heightHalf;
  157.                 y3 = y + heightHalf;
  158.                 y4 = y + heightHalf;
  159.                 z1 = z;
  160.                 z2 = z;
  161.                 z3 = z;
  162.                 z4 = z;
  163.                 break;
  164.             }
  165.             case null -> throw new NullPointerException(":| Please don't.");
  166.         }
  167.  
  168. //        float newQuad[] = { // One new quad :)
  169. //             //  x,  y,  z,    u,    v, nx, ny, nz
  170. //                x1, y1, z1, minU, minV, nX, nY, nZ,
  171. //                x2, y2, z2, minU, maxV, nX, nY, nZ,
  172. //                x3, y3, z3, maxU, maxV, nX, nY, nZ,
  173. //                x4, y4, z4, maxU, minV, nX, nY, nZ // Need to put 32 elements into an array without creating a new object.
  174. //        };
  175.  
  176.         // Never speak of this again
  177.         buffer[bufferPosition++] = x1;
  178.         buffer[bufferPosition++] = y1;
  179.         buffer[bufferPosition++] = z1;
  180.         buffer[bufferPosition++] = minU;
  181.         buffer[bufferPosition++] = minV;
  182.         buffer[bufferPosition++] = nX;
  183.         buffer[bufferPosition++] = nY;
  184.         buffer[bufferPosition++] = nZ;
  185.         buffer[bufferPosition++] = x2;
  186.         buffer[bufferPosition++] = y2;
  187.         buffer[bufferPosition++] = z2;
  188.         buffer[bufferPosition++] = minU;
  189.         buffer[bufferPosition++] = maxV;
  190.         buffer[bufferPosition++] = nX;
  191.         buffer[bufferPosition++] = nY;
  192.         buffer[bufferPosition++] = nZ;
  193.         buffer[bufferPosition++] = x3;
  194.         buffer[bufferPosition++] = y3;
  195.         buffer[bufferPosition++] = z3;
  196.         buffer[bufferPosition++] = maxU;
  197.         buffer[bufferPosition++] = maxV;
  198.         buffer[bufferPosition++] = nX;
  199.         buffer[bufferPosition++] = nY;
  200.         buffer[bufferPosition++] = nZ;
  201.         buffer[bufferPosition++] = x4;
  202.         buffer[bufferPosition++] = y4;
  203.         buffer[bufferPosition++] = z4;
  204.         buffer[bufferPosition++] = maxU;
  205.         buffer[bufferPosition++] = minV;
  206.         buffer[bufferPosition++] = nX;
  207.         buffer[bufferPosition++] = nY;
  208.         buffer[bufferPosition++] = nZ;
  209.  
  210.         quadCount++;
  211.     }
  212.  
  213.     public enum QuadDirection {
  214.         NEG_X(new Vector3f(-1, 0, 0)),
  215.         NEG_Y(new Vector3f(0, -1, 0)),
  216.         NEG_Z(new Vector3f(0, 0, -1)),
  217.         POS_X(new Vector3f(1, 0, 0)),
  218.         POS_Y(new Vector3f(0, 1, 0)),
  219.         POS_Z(new Vector3f(0, 0, 1));
  220.         private final Vector3f normal;
  221.         QuadDirection(Vector3f normal) {
  222.             this.normal = normal;
  223.         }
  224.         public float x() {
  225.             return normal.x;
  226.         }
  227.         public float y() {
  228.             return normal.y;
  229.         }
  230.         public float z() {
  231.             return normal.z;
  232.         }
  233.     }
  234.  
  235.     public Mesh flushMesh() {
  236.         var copyOfBuffer = buffer.clone(); // I want to reset afterward
  237.         Arrays.fill(buffer, 0.0f);
  238.         int oldQuadCount = quadCount;
  239.         int quadCount = 0;
  240.         return new EBOMesh(copyOfBuffer,generateIndices(oldQuadCount * 6),VertexFormat.of(VertexFormatType.VEC3, VertexFormatType.VEC2, VertexFormatType.VEC3)); // Only 2 object allocations (may change)
  241.     }
  242.  
  243.     private int[] generateIndices(int count) {
  244.         int[] newArrayForIndices = new int[count];
  245.         System.arraycopy(premadeIndices, 0, newArrayForIndices, 0, count);
  246.         return newArrayForIndices;
  247.     }
  248. }
Tags: programming
Add Comment
Please, Sign In to add comment