From a38bc412f8c6ae6c8fdf9466ae9b2073c2a73614 Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Sun, 26 Feb 2023 10:39:03 +0200 Subject: [PATCH] Updated readability of the code. --- .../sixth/e3d/gui/RenderingContext.java | 18 ++++- .../sixth/e3d/gui/UserRelativityTracker.java | 10 +-- .../sixth/e3d/math/TransformsPipeline.java | 60 -------------- .../sixth/e3d/math/TransformsStack.java | 81 +++++++++++++++++++ .../eu/svjatoslav/sixth/e3d/math/Vertex.java | 19 +++-- .../e3d/renderer/raster/ShapeCollection.java | 4 +- .../shapes/AbstractCoordinateShape.java | 6 +- .../renderer/raster/shapes/AbstractShape.java | 4 +- .../base/AbstractCompositeShape.java | 8 +- .../composite/textcanvas/TextCanvas.java | 17 ++-- 10 files changed, 130 insertions(+), 97 deletions(-) delete mode 100644 src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsPipeline.java create mode 100644 src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsStack.java diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java index ce8c4a0..c5c42f6 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/RenderingContext.java @@ -26,8 +26,15 @@ public class RenderingContext { */ public final Point2D centerCoordinate; + /** + * Zoom factor. The bigger the value, the more zoomed in the view is. + */ public final double zoom; final BufferedImage bufferedImage; + /** + * Number of frame that is currently being rendered. + * Every frame has its own number. + */ public int frameNumber = 0; /** @@ -42,8 +49,13 @@ public class RenderingContext { /** * Mouse click event that needs to be processed. + * This event is processed only once per frame. + * If there are multiple objects under mouse cursor, the top-most object will receive the event. + * If there are no objects under mouse cursor, the event will be ignored. + * If there is no event, this field will be null. + * This field is set to null after the event is processed. */ - private MouseEvent mouseEvent; + private MouseEvent mouseEvent; public void setMouseEvent(MouseEvent mouseEvent) { this.mouseEvent = mouseEvent; @@ -54,7 +66,7 @@ public class RenderingContext { } /** - * Item that user clicked on. + * UI component that mouse is currently hovering over. */ private MouseInteractionController currentObjectUnderMouseCursor; @@ -85,7 +97,7 @@ public class RenderingContext { } /** - * @return true if view repaint is needed. + * @return true if view update is needed as a consequence of this mouse event. */ public boolean handlePossibleComponentMouseEvent() { if (mouseEvent == null) return false; diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/UserRelativityTracker.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/UserRelativityTracker.java index 06363ea..48b1016 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/UserRelativityTracker.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/UserRelativityTracker.java @@ -5,8 +5,8 @@ package eu.svjatoslav.sixth.e3d.gui; import eu.svjatoslav.sixth.e3d.geometry.Point3D; +import eu.svjatoslav.sixth.e3d.math.TransformsStack; import eu.svjatoslav.sixth.e3d.math.Vertex; -import eu.svjatoslav.sixth.e3d.math.TransformsPipeline; public class UserRelativityTracker { @@ -19,14 +19,14 @@ public class UserRelativityTracker { } - public void analyze(final TransformsPipeline transformPipe, + public void analyze(final TransformsStack transformPipe, final RenderingContext renderingContext) { - center.transform(transformPipe, renderingContext); + center.calculateLocationRelativeToViewer(transformPipe, renderingContext); if (right != null) { - right.transform(transformPipe, renderingContext); - down.transform(transformPipe, renderingContext); + right.calculateLocationRelativeToViewer(transformPipe, renderingContext); + down.calculateLocationRelativeToViewer(transformPipe, renderingContext); } } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsPipeline.java b/src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsPipeline.java deleted file mode 100644 index 4e9985f..0000000 --- a/src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsPipeline.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Sixth 3D engine. Author: Svjatoslav Agejenko. - * This project is released under Creative Commons Zero (CC0) license. - */ -package eu.svjatoslav.sixth.e3d.math; - -import eu.svjatoslav.sixth.e3d.geometry.Point3D; - -public class TransformsPipeline { - - - private Transform[] transforms = new Transform[100]; - - /** - * The number of transforms in the pipeline. - */ - private int transformsCount = 0; - - /** - * Adds a transform to the pipeline. - * - * @param transform - * The transform to add. - */ - public void addTransform(final Transform transform) { - transforms[transformsCount] = transform; - transformsCount++; - } - - /** - * Clears the pipeline. - */ - public void clear() { - transformsCount = 0; - } - - /** - * Drops the last transform from the pipeline. - */ - public void dropTransform() { - transformsCount--; - } - - /** - * Transforms a point. - * - * @param orinigalPoint - * Original point to transform. Original point is not modified. - * @param transformedPoint - * Transformed point. - */ - public void transform(final Point3D orinigalPoint, final Point3D transformedPoint) { - - transformedPoint.clone(orinigalPoint); - - // apply transforms in reverse order - for (int i = transformsCount - 1; i >= 0; i--) - transforms[i].transform(transformedPoint); - } -} diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsStack.java b/src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsStack.java new file mode 100644 index 0000000..41e1a95 --- /dev/null +++ b/src/main/java/eu/svjatoslav/sixth/e3d/math/TransformsStack.java @@ -0,0 +1,81 @@ +/* + * Sixth 3D engine. Author: Svjatoslav Agejenko. + * This project is released under Creative Commons Zero (CC0) license. + */ +package eu.svjatoslav.sixth.e3d.math; + +import eu.svjatoslav.sixth.e3d.geometry.Point3D; + +/** + *
+ * It is used to store and apply transforms to points.
+ * Transforms are applied in the reverse order they were added to the pipeline.
+ *
+ * Transforms are stacked and then every point is affected by every transform in this stack.
+ * This is needed to support feature where objects in the world are attached to and are relative to each other.
+ *
+ * Example:
+ * There is a ship it the sea. Ship moves along the sea and every object on the ship moves with it.
+ * Inside the ship there is a car. Car moves along the ship and every object on the car moves with it.
+ *
+ * So to calculate an absolute location in the world of particular object within a car,
+ * we must take into account object location relative to the car,
+ * car location relative to the ship,
+ * and ship location relative to the world.
+ * 
+ */ +public class TransformsStack { + + + /** + * Transforms that are currently in the pipeline. + * Array is used for efficiency to avoid memory allocation during the rendering + * because depth of the pipeline needs to change very often. + */ + private final Transform[] transforms = new Transform[100]; + + /** + * The number of transforms in the pipeline. + */ + private int transformsCount = 0; + + /** + * Adds a transform to the pipeline. + * + * @param transform The transform to add. + */ + public void addTransform(final Transform transform) { + transforms[transformsCount] = transform; + transformsCount++; + } + + /** + * Clears the pipeline. + */ + public void clear() { + transformsCount = 0; + } + + /** + * Drops the last transform from the pipeline. + */ + public void dropTransform() { + transformsCount--; + } + + /** + * Transforms a point. + * + * @param coordinate Coordinate to be transformed into result. Original input coordinate is not modified. + * @param result Resulting transformed point. For efficiency reasons, result is stored into preexisting object + * that is passed here as an argument to avoid memory allocation. + */ + public void transform(final Point3D coordinate, final Point3D result) { + + result.clone(coordinate); + + // Apply transforms in reverse order. + for (int i = transformsCount - 1; i >= 0; i--) + transforms[i].transform(result); + } +} diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/math/Vertex.java b/src/main/java/eu/svjatoslav/sixth/e3d/math/Vertex.java index 0c77868..6e083fc 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/math/Vertex.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/math/Vertex.java @@ -21,14 +21,19 @@ public class Vertex { /** * Vertex coordinate relative to the viewer after transformation. + * Visible vertices have positive z coordinate. + * Viewer is located at (0, 0, 0). */ public Point3D transformedCoordinate; /** - * Vertex coordinate on screen after transformation. + * Vertex coordinate in pixels relative to the top left corner of the screen after transformation. */ public Point2D onScreenCoordinate; + /** + * The frame number when this vertex was last transformed. + */ private int lastTransformedFrame; public Vertex() { @@ -43,14 +48,16 @@ public class Vertex { onScreenCoordinate = new Point2D(); } + /** - * Transforms the coordinate. + * Transforms vertex coordinate to calculate its location relative to the viewer. + * It also calculates its location on the screen. * - * @param transforms The transforms pipeline. - * @param renderContext The rendering context. + * @param transforms Transforms pipeline. + * @param renderContext Rendering context. */ - public void transform(final TransformsPipeline transforms, - final RenderingContext renderContext) { + public void calculateLocationRelativeToViewer(final TransformsStack transforms, + final RenderingContext renderContext) { if (lastTransformedFrame == renderContext.frameNumber) return; diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java index 302abc1..b58de06 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/ShapeCollection.java @@ -9,7 +9,7 @@ import eu.svjatoslav.sixth.e3d.gui.Avatar; import eu.svjatoslav.sixth.e3d.gui.RenderingContext; import eu.svjatoslav.sixth.e3d.gui.ViewPanel; import eu.svjatoslav.sixth.e3d.math.Transform; -import eu.svjatoslav.sixth.e3d.math.TransformsPipeline; +import eu.svjatoslav.sixth.e3d.math.TransformsStack; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractShape; import java.util.ArrayList; @@ -19,7 +19,7 @@ import java.util.List; public class ShapeCollection { private final RenderAggregator aggregator = new RenderAggregator(); - private final TransformsPipeline transformPipe = new TransformsPipeline(); + private final TransformsStack transformPipe = new TransformsStack(); private final List shapes = new ArrayList<>(); public synchronized void addShape(final AbstractShape shape) { diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractCoordinateShape.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractCoordinateShape.java index f2fdde0..7f0daf1 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractCoordinateShape.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractCoordinateShape.java @@ -6,8 +6,8 @@ package eu.svjatoslav.sixth.e3d.renderer.raster.shapes; import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.gui.RenderingContext; +import eu.svjatoslav.sixth.e3d.math.TransformsStack; import eu.svjatoslav.sixth.e3d.math.Vertex; -import eu.svjatoslav.sixth.e3d.math.TransformsPipeline; import eu.svjatoslav.sixth.e3d.renderer.raster.RenderAggregator; import java.util.concurrent.atomic.AtomicInteger; @@ -43,7 +43,7 @@ public abstract class AbstractCoordinateShape extends AbstractShape { public abstract void paint(RenderingContext renderBuffer); @Override - public void transform(final TransformsPipeline transforms, + public void transform(final TransformsStack transforms, final RenderAggregator aggregator, final RenderingContext renderingContext) { @@ -51,7 +51,7 @@ public abstract class AbstractCoordinateShape extends AbstractShape { boolean paint = true; for (final Vertex geometryPoint : coordinates) { - geometryPoint.transform(transforms, renderingContext); + geometryPoint.calculateLocationRelativeToViewer(transforms, renderingContext); accumulatedZ += geometryPoint.transformedCoordinate.z; diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractShape.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractShape.java index 4c1aba3..7909d70 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractShape.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/AbstractShape.java @@ -6,7 +6,7 @@ package eu.svjatoslav.sixth.e3d.renderer.raster.shapes; import eu.svjatoslav.sixth.e3d.gui.RenderingContext; import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController; -import eu.svjatoslav.sixth.e3d.math.TransformsPipeline; +import eu.svjatoslav.sixth.e3d.math.TransformsStack; import eu.svjatoslav.sixth.e3d.renderer.raster.RenderAggregator; public abstract class AbstractShape { @@ -18,7 +18,7 @@ public abstract class AbstractShape { this.mouseInteractionController = mouseInteractionController; } - public abstract void transform(final TransformsPipeline transforms, + public abstract void transform(final TransformsStack transforms, final RenderAggregator aggregator, final RenderingContext renderingContext); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/base/AbstractCompositeShape.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/base/AbstractCompositeShape.java index 184d57a..747dd08 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/base/AbstractCompositeShape.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/base/AbstractCompositeShape.java @@ -9,7 +9,7 @@ import eu.svjatoslav.sixth.e3d.gui.RenderingContext; import eu.svjatoslav.sixth.e3d.gui.UserRelativityTracker; import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController; import eu.svjatoslav.sixth.e3d.math.Transform; -import eu.svjatoslav.sixth.e3d.math.TransformsPipeline; +import eu.svjatoslav.sixth.e3d.math.TransformsStack; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.RenderAggregator; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractShape; @@ -64,7 +64,7 @@ public class AbstractCompositeShape extends AbstractShape { * This method should be overridden by anyone wanting to customize shape * before it is rendered. */ - public void beforeTransformHook(final TransformsPipeline transformPipe, + public void beforeTransformHook(final TransformsStack transformPipe, final RenderingContext context) { } @@ -181,7 +181,7 @@ public class AbstractCompositeShape extends AbstractShape { final List result = new ArrayList<>(); final Slicer slicer = new Slicer(currentSliceFactor); - originalSubShapes.stream().filter(subShape -> subShape.isVisible()).forEach(subShape -> { + originalSubShapes.stream().filter(SubShape::isVisible).forEach(subShape -> { if (subShape.getShape() instanceof TexturedPolygon) slicer.slice((TexturedPolygon) subShape.getShape()); else @@ -194,7 +194,7 @@ public class AbstractCompositeShape extends AbstractShape { } @Override - public void transform(final TransformsPipeline transformPipe, + public void transform(final TransformsStack transformPipe, final RenderAggregator aggregator, final RenderingContext context) { // add current composite shape transform to the end of the transform diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/textcanvas/TextCanvas.java b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/textcanvas/TextCanvas.java index fd78bf9..7a0c5e5 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/textcanvas/TextCanvas.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/renderer/raster/shapes/composite/textcanvas/TextCanvas.java @@ -8,7 +8,7 @@ import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.gui.RenderingContext; import eu.svjatoslav.sixth.e3d.gui.TextPointer; import eu.svjatoslav.sixth.e3d.math.Transform; -import eu.svjatoslav.sixth.e3d.math.TransformsPipeline; +import eu.svjatoslav.sixth.e3d.math.TransformsStack; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.TexturedRectangle; @@ -22,7 +22,7 @@ import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.WHITE; public class TextCanvas extends TexturedRectangle { - // character size in world coordiates + // character size in world coordinates public static final int FONT_CHAR_WIDTH = 8; public static final int FONT_CHAR_HEIGHT = 16; @@ -36,7 +36,7 @@ public class TextCanvas extends TexturedRectangle { private static final String GROUP_CHARACTERS = "characters"; private final TextPointer size; private final TextPointer cursorLocation = new TextPointer(); - CanvasCharacter lines[][]; + CanvasCharacter[][] lines; private RenderMode renderMode = null; private Color backgroundColor = BLACK; private Color foregroundColor = WHITE; @@ -118,7 +118,7 @@ public class TextCanvas extends TexturedRectangle { } @Override - public void beforeTransformHook(final TransformsPipeline transformPipe, + public void beforeTransformHook(final TransformsStack transformPipe, final RenderingContext context) { final double textRelativeSize = context.width @@ -145,7 +145,7 @@ public class TextCanvas extends TexturedRectangle { setRenderMode(RenderMode.CHARACTERS); } - public void cls() { + public void clear() { for (final CanvasCharacter[] line : lines) for (final CanvasCharacter character : line) { character.setValue(' '); @@ -295,11 +295,4 @@ public class TextCanvas extends TexturedRectangle { character.setForegroundColor(color); } - // @Override - // public void transform(final TransformPipe transformPipe, - // final RenderAggregator aggregator, final RenderingContext buffer) { - // - // super.transform(transformPipe, aggregator, buffer); - // - // } } -- 2.20.1