Package limn.render3d

Class MeshData

java.lang.Object
limn.render3d.MeshData

public final class MeshData extends Object
CPU-side geometry: one float array per VertexAttribute plus a triangle index list. Upload it once with Graphics3D.upload(...) to get a GpuMesh. VertexAttribute.POSITION is required. All attributes must have the same vertex count.

Geometry that changes every frame uploads once with MeshUsage.DYNAMIC and is rewritten through GpuMesh.update(limn.render3d.MeshData). Such a producer sizes its arrays to the worst case, rewrites them in place, and calls counts(int, int) to say how much of them is live this frame, so a frame costs no allocation at all. The arrays are held by reference, never copied, which is what makes writing into them afterwards work.

  • Constructor Details

    • MeshData

      public MeshData()
  • Method Details

    • put

      public MeshData put(VertexAttribute attribute, float[] data)
      Adds/replaces an attribute; its length must be vertexCount × components.
    • indices

      public MeshData indices(int[] triangleIndices)
      Sets the triangle index buffer; three consecutive indices are one triangle.
    • counts

      public MeshData counts(int vertexCount, int indexCount)
      Narrows this mesh to a live prefix: the first vertexCount vertices of every attribute array and the first indexCount entries of the index list. Everything past the prefix is capacity, and is ignored by vertexCount(), indexCount(), bounds() and by an upload.

      This is how a per-frame producer avoids reallocating: size the arrays once to the worst case, write this frame's data into the front of them, and declare how much is live. put(limn.render3d.VertexAttribute, float[]) and indices reset the prefix to the whole array (they are describing new backing storage), so call counts last.

      Leaving stale data past the prefix is not merely wasteful, it is wrong if anything reads it: last frame's vertex sitting at a far-away position would inflate bounds(), and nothing about the picture would look off while picking and shadow fitting quietly used the bigger box. Hence the prefix.

      Throws:
      IllegalArgumentException - if either count is negative or exceeds capacity
    • presentAttributes

      public Set<VertexAttribute> presentAttributes()
      Which vertex attributes this mesh actually carries.
    • has

      public boolean has(VertexAttribute attribute)
      Whether one attribute is present, what a shader checks before binding it.
    • get

      public float[] get(VertexAttribute attribute)
      The backing array for attribute: the whole capacity, not the live prefix.
    • vertexCount

      public int vertexCount()
      Live vertices: what an upload reads, and what bounds() measures.
    • vertexCapacity

      public int vertexCapacity()
      Vertices the backing arrays hold; equals vertexCount() unless narrowed.
    • indices

      public int[] indices()
      The backing index array: the whole capacity, not the live prefix.
    • indexCount

      public int indexCount()
      Live indices: what an upload draws.
    • bounds

      public Aabb bounds()
      Object-space bounds over the live prefix of VertexAttribute.POSITION.