Class ShapeCollection

java.lang.Object
eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection

public class ShapeCollection extends Object
Root container that holds all 3D shapes in a scene and orchestrates their rendering.

ShapeCollection is the top-level scene graph. You add shapes to it, and during each render frame it transforms all shapes from world space to screen space (relative to the camera), sorts them by depth, and paints them back-to-front.

Architecture:

The collection contains a single AbstractCompositeShape as its root container. This root composite:

  • Stores all scene shapes in its sub-shapes registry
  • Triangulates N-vertex polygons (quads, etc.) into triangles during rendering
  • Provides group-based visibility management (show/hide groups)
  • Applies camera transform (position and rotation) to all shapes

Usage example:


 // Get the root shape collection from the view panel
 ShapeCollection scene = viewPanel.getRootShapeCollection();

 // Add shapes to the scene
 scene.addShape(new Line(
     new Point3D(0, 0, 100),
     new Point3D(100, 0, 100),
     Color.RED, 2.0
 ));

 // Add shapes with group identifier for visibility control
 scene.addShape(debugShape, "debug");
 scene.hideGroup("debug");  // hide all debug shapes
 scene.showGroup("debug");  // show them again

 // Add N-vertex polygons (quads, etc.) - automatically triangulated
 scene.addShape(SolidPolygon.quad(p1, p2, p3, p4, color));
 

The addShape(eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractShape) method is synchronized, making it safe to add shapes from any thread while the rendering loop is active.

See Also:
  • Constructor Details

    • ShapeCollection

      public ShapeCollection()
      Creates a new empty shape collection with a root composite.
  • Method Details

    • addShape

      public void addShape(AbstractShape shape)
      Adds a shape to this collection without a group identifier. This method is thread-safe.
      Parameters:
      shape - the shape to add to the scene
    • collectRenderTriangles

      public void collectRenderTriangles(List<AbstractCoordinateShape> out)
      Collects the triangles currently rendered for this collection (render lists of all composites, recursively). Used by derived structures like the global-illumination scene snapshot. Render lists build lazily during transform, so the result may be empty until the first frame.
      Parameters:
      out - list receiving the polygons
    • addShape

      public void addShape(AbstractShape shape, String groupId)
      Adds a shape to this collection with a group identifier for visibility control. This method is thread-safe.

      Grouped shapes can be shown, hidden, or removed together using showGroup(java.lang.String), hideGroup(java.lang.String), and removeGroup(java.lang.String).

      Parameters:
      shape - the shape to add
      groupId - the group identifier, or null for ungrouped shapes
    • getShapes

      public Collection<AbstractShape> getShapes()
      Returns all shapes currently in this collection (including hidden ones).

      This returns the sub-shapes from the registry, unwrapped from their SubShape containers. For access to group and visibility metadata, use getSubShapesRegistry().

      Returns:
      a collection of all shapes in the scene
    • getSubShapesRegistry

      public List<SubShape> getSubShapesRegistry()
      Returns the sub-shapes registry with group and visibility metadata.

      This provides direct access to the registry for advanced operations like inspecting group assignments or visibility states.

      Returns:
      the list of sub-shapes with their metadata
    • clear

      public void clear()
      Removes all shapes from this collection. This method is thread-safe.
    • showGroup

      public void showGroup(String groupId)
      Shows all shapes belonging to the specified group.
      Parameters:
      groupId - the group identifier to show
    • hideGroup

      public void hideGroup(String groupId)
      Hides all shapes belonging to the specified group. Hidden shapes are not rendered but remain in the collection.
      Parameters:
      groupId - the group identifier to hide
    • removeGroup

      public void removeGroup(String groupId)
      Permanently removes all shapes belonging to the specified group.
      Parameters:
      groupId - the group identifier to remove
    • getGroup

      public List<SubShape> getGroup(String groupId)
      Returns all sub-shapes belonging to the specified group.
      Parameters:
      groupId - the group identifier to match
      Returns:
      list of matching sub-shapes
    • transformShapes

      public void transformShapes(ViewPanel viewPanel, RenderingContext renderingContext)
      Transforms all shapes to screen space and queues them for rendering. This is phase 1 of the multi-threaded render pipeline.

      Updates the root composite's transform to match the camera position and rotation, then delegates to the root composite's transform method which handles all shapes.

      Frustum culling: The view frustum is computed from camera state and screen dimensions before transforming shapes. Composite shapes can test their bounding boxes against this frustum to skip invisible objects.

      Culling statistics: Statistics are reset and total shape count computed at the start of each frame. Visible shapes are counted as they are queued.

      Parameters:
      viewPanel - the view panel providing the camera state
      renderingContext - the rendering context with frame metadata
    • transformShapes

      public void transformShapes(Camera camera, RenderingContext renderingContext)
      Camera-based variant of transformShapes(ViewPanel, RenderingContext) for headless rendering without a ViewPanel (off-screen snapshots, golden-image tests, GI scene setup).
      Parameters:
      camera - the camera providing position and orientation
      renderingContext - the rendering context with frame metadata
    • transformShapesBegin

      public void transformShapesBegin(ViewPanel viewPanel, RenderingContext renderingContext)
      First half of transformShapes(eu.svjatoslav.sixth.e3d.gui.ViewPanel, eu.svjatoslav.sixth.e3d.gui.RenderingContext): resets the frame's aggregator, computes the frustum and walks the scene tree, forking heavy composites into chunk tasks on the frame's coordinator. Returns WITHOUT waiting for the chunk tasks; the caller hands the coordinator to drainTransformShapes(eu.svjatoslav.sixth.e3d.gui.RenderingContext) later (the pipeline drains it inside the asynchronous sort/bin/paint continuation on a worker thread).
      Parameters:
      viewPanel - the view panel providing the camera state
      renderingContext - the pass rendering context
    • transformShapesBegin

      public void transformShapesBegin(Camera camera, RenderingContext renderingContext)
      Camera-based variant of transformShapesBegin(ViewPanel, RenderingContext) for headless rendering without a ViewPanel.
      Parameters:
      camera - the camera providing position and orientation
      renderingContext - the pass rendering context
    • drainTransformShapes

      public void drainTransformShapes(RenderingContext renderingContext)
      Second half of transformShapes(eu.svjatoslav.sixth.e3d.gui.ViewPanel, eu.svjatoslav.sixth.e3d.gui.RenderingContext): waits for all transform chunk tasks and merges their aggregators into the frame's root aggregator. Safe to call from a worker thread while the render thread already walks the NEXT pass: chunk tasks capture their own transform-stack snapshots, and the aggregator is addressed by the pass's projection slot, so passes never touch the same state.
      Parameters:
      renderingContext - the pass rendering context
    • sortShapes

      public void sortShapes()
      Sorts all queued shapes by Z-depth (back to front). This is phase 2 of the multi-threaded render pipeline.
    • sortShapes

      public void sortShapes(int slot)
      Sorts the given buffer slot's queued shapes by Z-depth.
      Parameters:
      slot - buffer slot to sort (0 or 1)
    • sortShapes

      public void sortShapes(int slot, ExecutorService executor)
      Sorts the given buffer slot's queued shapes by Z-depth, parallelized over the given executor (instrumented parallel merge sort).
      Parameters:
      slot - buffer slot to sort
      executor - executor for parallel sorting
    • binShapesForTiles

      public void binShapesForTiles(int tilesX, int tilesY, int originX, int width, int height, ExecutorService executor)
      Bins the sorted render queue per rectangular paint tile by screen-space overlap, so each paint thread iterates only the shapes that can touch its tile instead of the whole queue. Call after sortShapes(), before tile painting.
      Parameters:
      tilesX - tile columns across the viewport
      tilesY - tile rows down the viewport
      originX - X origin of the tiled viewport (eye offset in stereo)
      width - tiled viewport width in pixels
      height - full render height in pixels
      executor - executor for parallel binning, or null for serial
    • binShapesForTiles

      public void binShapesForTiles(int slot, int tilesX, int tilesY, int originX, int width, int height, ExecutorService executor)
      Slot-selecting variant of binShapesForTiles(int, int, int, int, int, ExecutorService) for the double-buffered pipeline.
      Parameters:
      slot - buffer slot whose queue gets binned (0 or 1)
      tilesX - tile columns across the viewport
      tilesY - tile rows down the viewport
      originX - X origin of the tiled viewport (eye offset in stereo)
      width - tiled viewport width in pixels
      height - full render height in pixels
      executor - executor for parallel binning, or null for serial
    • paintShapes

      public void paintShapes(RenderingContext renderingContext)
      Paints all already-sorted shapes to the rendering context. This is phase 3 of the multi-threaded render pipeline. Can be called multiple times with different segment contexts.
      Parameters:
      renderingContext - the rendering context to paint into
    • getQueuedShapeCount

      public int getQueuedShapeCount()
      Returns the number of shapes queued for rendering.
      Returns:
      the shape count
    • getRootComposite

      public AbstractCompositeShape getRootComposite()
      Returns the root composite shape containing all scene shapes.

      Useful for headless setups that must transform the scene without going through the full collection pipeline (e.g. pre-building render lists before a GI snapshot reads them via collectRenderTriangles(java.util.List<eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape>)).

      Returns:
      the root composite (never null)
    • setCacheNeedsRebuild

      public void setCacheNeedsRebuild(boolean needsRebuild)
      Sets the cache rebuild flag on the root composite.

      Used internally to force a render-list rebuild. Public for advanced use cases.

      Parameters:
      needsRebuild - true to force cache rebuild