11package engine .components ;
22
33import engine .render .Material ;
4+ import math .Bounds ;
5+ import math .Color ;
46import mesh .Mesh3D ;
7+ import mesh .util .MeshBoundsCalculator ;
58import workspace .ui .Graphics ;
69
710/**
8- * Represents a renderable geometry component within the scene graph.
9- * <p>
10- * The Geometry class is a component that encapsulates a 3D mesh and its
11- * associated material. It implements rendering behavior through the
12- * {@link RenderableComponent} interface, allowing it to be drawn during the
13- * rendering pass of the scene graph traversal.
14- * </p>
15- * <p>
16- * This class is responsible for applying the provided {@link Material} during
17- * rendering, ensuring proper visualization of the associated {@link Mesh3D}.
18- * </p>
11+ * The {@code Geometry} class represents a 3D object in a scene with a mesh and
12+ * material applied to it. It is responsible for rendering the mesh and applying
13+ * the appropriate material to it. The class also provides access to the mesh's
14+ * bounding box, which is useful for purposes like culling, spatial
15+ * partitioning, and debugging.
1916 *
20- * <h3>Key Features</h3>
21- * <ul>
22- * <li>Supports a default white material if no custom material is provided.</li>
23- * <li>Handles cleanup by releasing references to the mesh and material.</li>
24- * <li>Integrates with the graphics context to issue rendering commands via the
25- * {@link Graphics} class.</li>
26- * </ul>
17+ * This class implements the {@link RenderableComponent} interface, indicating
18+ * that it has a render method to be invoked during the render loop of the
19+ * engine.
20+ *
21+ * @see RenderableComponent
22+ * @see Material
23+ * @see Mesh3D
24+ * @see Bounds
2725 */
2826public class Geometry extends AbstractComponent implements RenderableComponent {
2927
30- /** The 3D mesh to be rendered by this component . */
28+ /** The mesh representing the geometry of the object . */
3129 private Mesh3D mesh ;
3230
33- /** The material associated with this geometry for rendering purposes . */
31+ /** The material applied to the mesh for rendering. */
3432 private Material material ;
3533
3634 /**
37- * Constructs a Geometry component with a provided mesh and the default white
35+ * The bounding box of the mesh used for culling, spatial partitioning, and
36+ * debugging.
37+ */
38+ private Bounds bounds ;
39+
40+ /**
41+ * Constructs a {@code Geometry} with the specified mesh and a default
3842 * material.
39- *
40- * @param mesh The mesh to associate with this geometry.
43+ *
44+ * @param mesh The {@link Mesh3D} object representing the geometry of the
45+ * object.
46+ * @throws IllegalArgumentException If the mesh is {@code null}.
4147 */
4248 public Geometry (Mesh3D mesh ) {
4349 this (mesh , Material .DEFAULT_WHITE );
4450 }
4551
4652 /**
47- * Constructs a Geometry component with a specific mesh and material.
48- *
49- * @param mesh The 3D mesh to associate with this geometry. Must not be
50- * null .
51- * @param material The material to use for rendering. Must not be null .
52- * @throws IllegalArgumentException if either mesh or material is null.
53+ * Constructs a {@code Geometry} with the specified mesh and material.
54+ *
55+ * @param mesh The {@link Mesh3D} object representing the geometry of the
56+ * object .
57+ * @param material The {@link Material} to be applied to the mesh .
58+ * @throws IllegalArgumentException If the mesh or material is {@code null} .
5359 */
5460 public Geometry (Mesh3D mesh , Material material ) {
5561 validate (mesh , material );
5662 this .mesh = mesh ;
5763 this .material = material ;
64+ this .bounds = MeshBoundsCalculator .calculateBounds (mesh );
5865 }
5966
6067 /**
61- * Validates the provided mesh and material to ensure they are non- null.
62- *
63- * @param mesh The 3D mesh to validate.
64- * @param material The material to validate.
65- * @throws IllegalArgumentException if either mesh or material is null.
68+ * Validates the mesh and material to ensure they are not {@code null} .
69+ *
70+ * @param mesh The {@link Mesh3D} object to validate.
71+ * @param material The {@link Material} to validate.
72+ * @throws IllegalArgumentException If the mesh or material is {@code null} .
6673 */
6774 private void validate (Mesh3D mesh , Material material ) {
6875 if (mesh == null ) {
@@ -74,53 +81,96 @@ private void validate(Mesh3D mesh, Material material) {
7481 }
7582
7683 /**
77- * Cleans up resources associated with this component by nullifying references
78- * to the mesh and material. This is called when the component is no longer
79- * needed or during application shutdown.
84+ * Renders the geometry by applying the material and drawing the mesh using
85+ * the specified graphics context.
86+ *
87+ * @param g The {@link Graphics} context used for rendering.
8088 */
8189 @ Override
82- public void cleanup () {
83- mesh = null ;
84- material = null ;
90+ public void render (Graphics g ) {
91+ material .apply (g );
92+ g .fillFaces (mesh );
93+ material .release (g );
94+ debugRenderBounds (g );
8595 }
8696
8797 /**
88- * Handles rendering of the mesh with its material using the provided graphics
89- * context.
98+ * Debugs the rendering by drawing the bounding box of the mesh using the
99+ * specified graphics context. The bounding box is rendered in red to help
100+ * visualize the mesh's extents. This method can be used for debugging
101+ * purposes to ensure the mesh is properly positioned and scaled in the scene.
90102 *
91103 * <p>
92- * This method applies the material, renders the associated mesh's faces using
93- * the {@link Graphics} instance, and then releases the material's state
94- * afterward .
104+ * Beyond debugging, the bounding box is useful for spatial partitioning
105+ * techniques like frustum culling, as well as for determining the overall
106+ * size and position of the mesh in the 3D world .
95107 * </p>
96- *
97- * @param g The graphics context to use for rendering the geometry.
108+ *
109+ * @param g The {@link Graphics} context used for rendering the debug bounding
110+ * box.
111+ */
112+ public void debugRenderBounds (Graphics g ) {
113+ if (bounds == null ) {
114+ return ;
115+ }
116+
117+ g .setColor (Color .RED );
118+
119+ // Extract corner points for readability
120+ float minX = bounds .getMin ().x ;
121+ float minY = bounds .getMin ().y ;
122+ float minZ = bounds .getMin ().z ;
123+ float maxX = bounds .getMax ().x ;
124+ float maxY = bounds .getMax ().y ;
125+ float maxZ = bounds .getMax ().z ;
126+
127+ // Draw lines for each edge of the bounding box
128+ g .drawLine (minX , minY , minZ , maxX , minY , minZ );
129+ g .drawLine (minX , minY , minZ , minX , maxY , minZ );
130+ g .drawLine (minX , minY , minZ , minX , minY , maxZ );
131+
132+ g .drawLine (maxX , maxY , maxZ , minX , maxY , maxZ );
133+ g .drawLine (maxX , maxY , maxZ , maxX , minY , maxZ );
134+ g .drawLine (maxX , maxY , maxZ , maxX , maxY , minZ );
135+
136+ g .drawLine (minX , maxY , minZ , maxX , maxY , minZ );
137+ g .drawLine (maxX , minY , minZ , maxX , maxY , minZ );
138+ g .drawLine (maxX , minY , minZ , maxX , minY , maxZ );
139+
140+ g .drawLine (minX , maxY , maxZ , minX , minY , maxZ );
141+ g .drawLine (maxX , minY , maxZ , minX , minY , maxZ );
142+ g .drawLine (minX , maxY , maxZ , minX , maxY , minZ );
143+ }
144+
145+ /**
146+ * Updates the state of the geometry. This method is a placeholder for
147+ * potential updates to the mesh state over time.
148+ *
149+ * @param tpf The time per frame used for the update (in seconds).
98150 */
99151 @ Override
100- public void render (Graphics g ) {
101- material .apply (g );
102- g .fillFaces (mesh );
103- material .release (g );
152+ public void update (float tpf ) {
153+ // Placeholder for potential mesh state updates
104154 }
105155
106156 /**
107- * Placeholder for initialization logic if needed in future development.
108- * Currently, no specific initialization is necessary.
157+ * Called when the component is attached to a parent object in the scene. This
158+ * method is a hook for additional initialization or setup when the component
159+ * is added.
109160 */
110161 @ Override
111- public void initialize () {
112- // Initialization logic, if needed
162+ public void onAttach () {
163+ // Hook for additional setup on attachment
113164 }
114165
115166 /**
116- * Updates geometry's state over time, if necessary. Currently, this is a
117- * placeholder for potential future logic.
118- *
119- * @param tpf Time per frame, used to synchronize updates across frames.
167+ * Called when the component is detached from its parent object in the scene.
168+ * This method is a hook for cleanup or other actions when the component is
169+ * removed.
120170 */
121171 @ Override
122- public void update ( float tpf ) {
123- // Placeholder for potential mesh state updates
172+ public void onDetach ( ) {
173+ // Hook for cleanup on detachment
124174 }
125175
126176}
0 commit comments