From: Svjatoslav Agejenko Date: Mon, 30 Mar 2026 16:45:36 +0000 (+0300) Subject: refactor(demos): adopt new sixth-3d API and add tutorial docs X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=9a923eda489f9f2e391604e919ed46c0c363ba9b;p=sixth-3d-demos.git refactor(demos): adopt new sixth-3d API and add tutorial docs Update all demos to use the modernized sixth-3d engine API with fluent factory methods and in-place CSG operations. Add comprehensive tutorial documentation in the Essentials section with screenshots and code examples. - Use static imports: Point3D.point(), Color.hex() - Replace CSG class usage with in-place union/subtract/intersect methods - Update to renamed classes: SolidTriangle, TexturedTriangle - Use SolidPolygon.quad() for quad surfaces instead of two triangles - Add Minimal Example tutorial with step-by-step walkthrough - Add screenshots for CSG, Coordinate System, Shape Gallery, Winding Order - Rename AxisArrowsDemo to CoordinateSystemDemo with class references --- diff --git a/doc/Screenshots/Essentials/CSG demo.png b/doc/Screenshots/Essentials/CSG demo.png new file mode 100644 index 0000000..5602255 Binary files /dev/null and b/doc/Screenshots/Essentials/CSG demo.png differ diff --git a/doc/Screenshots/Essentials/Coordinate system.png b/doc/Screenshots/Essentials/Coordinate system.png new file mode 100644 index 0000000..7896688 Binary files /dev/null and b/doc/Screenshots/Essentials/Coordinate system.png differ diff --git a/doc/Screenshots/Essentials/Minimal example.png b/doc/Screenshots/Essentials/Minimal example.png new file mode 100644 index 0000000..6bee1cb Binary files /dev/null and b/doc/Screenshots/Essentials/Minimal example.png differ diff --git a/doc/Screenshots/Essentials/Shape gallery.png b/doc/Screenshots/Essentials/Shape gallery.png new file mode 100644 index 0000000..76a4fe5 Binary files /dev/null and b/doc/Screenshots/Essentials/Shape gallery.png differ diff --git a/doc/Screenshots/Essentials/Winding order.png b/doc/Screenshots/Essentials/Winding order.png new file mode 100644 index 0000000..f939231 Binary files /dev/null and b/doc/Screenshots/Essentials/Winding order.png differ diff --git a/doc/index.org b/doc/index.org index cb10d9b..734d9cb 100644 --- a/doc/index.org +++ b/doc/index.org @@ -53,34 +53,291 @@ It requires Java 21 or newer to run. To start the demo application, use command: : java -jar sixth-3d-demos.jar -* Navigating in space +* Essentials + +*Resources to help you understand the Sixth 3D library:* +- Read online [[https://www3.svjatoslav.eu/projects/sixth-3d/apidocs/][JavaDoc]]. +- See [[https://www3.svjatoslav.eu/projects/sixth-3d/graphs/][Sixth 3D class diagrams]]. (Diagrams were generated by using + [[https://www3.svjatoslav.eu/projects/javainspect/][JavaInspect]] utility) + +** Minimal example :PROPERTIES: -:CUSTOM_ID: navigating-in-space -:ID: 0aca7419-48df-48ac-b18b-a8bf7b9db0ac +:CUSTOM_ID: minimal-example +:ID: 1a2b3c4d-5e6f-7890-abcd-ef1234567890 :END: -| key | result | -|---------------------+--------------------------------------| -| Keyboard arrow keys | Move: left, right, forward, backward | -| Mouse scroll wheel | Move: up <-> down | -| Mouse drag | Turn head around in 3D space | +This is the "Hello World" of *Sixth 3D* - the minimal boilerplate +needed to render any 3D geometry. + +: eu.svjatoslav.sixth.e3d.examples.essentials.MinimalExample + +*Brief tutorial:* + +Here we guide you through creating your first 3D scene with Sixth 3D +engine. + +Prerequisites: +- Java 21 or later installed +- Maven 3.x +- Basic Java knowledge -* Example scenes +*** Add Dependency to Your Project :PROPERTIES: -:CUSTOM_ID: example-scenes -:ID: 5f88b493-6ab3-4659-8280-803f75dbd5e0 +:CUSTOM_ID: add-dependency-to-your-project +:ID: 3fffc32e-ae66-40b7-ad7d-fab6093c778b +:END: + +Add *Sixth 3D* to your pom.xml: + +#+BEGIN_SRC xml + + + eu.svjatoslav + sixth-3d + 1.4-SNAPSHOT + + + + + + svjatoslav.eu + Svjatoslav repository + https://www3.svjatoslav.eu/maven/ + + +#+END_SRC + + +*** Create Your First 3D Scene +:PROPERTIES: +:CUSTOM_ID: create-your-first-3d-scene +:ID: 564fa596-9b2b-418a-9df9-baa46f0d0a66 :END: + +#+BEGIN_SRC java + import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; + import eu.svjatoslav.sixth.e3d.gui.ViewFrame; + import eu.svjatoslav.sixth.e3d.math.Transform; + import eu.svjatoslav.sixth.e3d.renderer.raster.Color; + import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; + import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonRectangularBox; + + public class MyFirstScene { + public static void main(String[] args) { + // Create the application window + ViewFrame viewFrame = new ViewFrame("My First Scene"); + + // Get the collection where you add 3D shapes + ShapeCollection shapes = viewFrame.getViewPanel().getRootShapeCollection(); + + // Create a red box centered at origin + final Transform boxTransform = new Transform(); + SolidPolygonRectangularBox box = new SolidPolygonRectangularBox( + point(-50, -50, -50), + point(50, 50, 50), + Color.RED + ); + box.setTransform(boxTransform); + shapes.addShape(box); + + // Position your camera + viewFrame.getViewPanel().getCamera().getTransform() + .setTranslation(point(0, -100, -300)); + + // Trigger initial render + viewFrame.getViewPanel().repaintDuringNextViewUpdate(); + } + } +#+END_SRC + +Compile and run *MyFirstScene* class. A new window should open that will +display 3D scene with red box. + + +You should see this: +#+attr_html: :class responsive-img +#+attr_latex: :width 1000px +[[file:Screenshots/Essentials/Minimal example.png]] + + +*Navigating the scene:* + +| Input | Action | +|--------------------+-----------------------------| +| Arrow Up | Move forward | +| Arrow Down | Move backward | +| Arrow Left | Move left (strafe) | +| Arrow Right | Move right (strafe) | +| Mouse drag | Look around (rotate camera) | +| Mouse scroll wheel | Move up / down | + +Movement uses physics-based acceleration for smooth, natural +motion. The faster you're moving, the more acceleration builds up, +creating an intuitive flying experience. + Press *F12* in any demo to open the [[https://www3.svjatoslav.eu/projects/sixth-3d/#outline-container-developer-tools][Developer Tools panel]]. This debugging interface provides real-time insight into the rendering pipeline with diagnostic toggles. +** Coordinate system +:PROPERTIES: +:CUSTOM_ID: coordinate-system +:ID: 2b3c4d5e-6f7a-8901-bcde-f12345678901 +:END: + +: eu.svjatoslav.sixth.e3d.examples.essentials.CoordinateSystemDemo + +#+attr_html: :class responsive-img +#+attr_latex: :width 1000px +[[file:Screenshots/Essentials/Coordinate system.png]] + +Visual reference for the Sixth 3D coordinate system using three colored +arrows originating from (0,0,0): + +| Axis | Color | Direction | +|------+-------+------------------------------------| +| X | Red | Points RIGHT (positive X) | +| Y | Green | Points DOWN (positive Y) | +| Z | Blue | Points AWAY from viewer (positive Z) | + +A wireframe grid on the Y=0 plane provides spatial context and scale. Text +labels (X, Y, Z) appear at each arrow tip. + +This demo is essential for understanding Sixth 3D's coordinate system where: +- Positive Y goes down (screen coordinates convention) +- Positive Z goes into the screen (away from camera) +- Positive X goes to the right + +See the [[https://www3.svjatoslav.eu/projects/sixth-3d/#coordinate-system][Coordinate System]] section in the Sixth 3D documentation +for a detailed explanation of the axis conventions and coordinate math. + +** Winding order +:PROPERTIES: +:CUSTOM_ID: winding-order +:ID: 3c4d5e6f-7a8b-9012-cdef-123456789012 +:END: + +: eu.svjatoslav.sixth.e3d.examples.essentials.WindingOrderDemo + +#+attr_html: :class responsive-img +#+attr_latex: :width 1000px +[[file:Screenshots/Essentials/Winding order.png]] + +This demo demonstrates polygon winding order and backface culling - fundamental +concepts for efficient 3D rendering. + +The green triangle uses counter-clockwise (CCW) vertex ordering: +1. Upper-center vertex +2. Lower-left vertex +3. Lower-right vertex + +With backface culling enabled: +- *CCW winding* (negative signed area) = front-facing = visible +- *CW winding* (positive signed area) = back-facing = culled (not rendered) + +This optimization prevents rendering polygons facing away from the camera, +improving performance by roughly 50% for closed meshes. Navigate around the +scene and observe that the triangle becomes invisible when viewed from behind, +demonstrating the culling effect. + +See the [[https://www3.svjatoslav.eu/projects/sixth-3d/#winding-order-backface-culling][Winding Order & Backface Culling]] section +in the Sixth 3D documentation for a detailed explanation with diagrams. + +** Shape gallery +:PROPERTIES: +:CUSTOM_ID: shape-gallery +:ID: 4d5e6f7a-8b9c-0123-def0-234567890123 +:END: + +: eu.svjatoslav.sixth.e3d.examples.essentials.ShapeGalleryDemo + +#+attr_html: :class responsive-img +#+attr_latex: :width 1000px +[[file:Screenshots/Essentials/Shape gallery.png]] + +Comprehensive showcase of all primitive 3D shapes available in Sixth 3D, +organized in a 7×2 grid: + +| Column | Shape Type | Description | +|--------+------------+--------------------------------| +| 1 | Arrow | 3D arrow with conical tip | +| 2 | Cone | Circular base cone | +| 3 | Cube | Regular hexahedron | +| 4 | Cylinder | Tube with circular caps | +| 5 | Pyramid | Square base pyramid | +| 6 | Box | Rectangular parallelepiped | +| 7 | Sphere | Geodesic sphere approximation | + +*Top row:* Wireframe versions - edges only, no surfaces +*Bottom row:* Solid polygon versions - filled surfaces with lighting + +Additional features demonstrated: +- Dynamic lighting from 10 orbiting colored light sources (visible as small + glowing dots) +- Per-shape color assignment for visual distinction +- Grid floor showing spatial layout and alignment +- Text labels identifying each shape type +- Shading enabled on solid shapes to show lighting effects + +See the [[https://www3.svjatoslav.eu/projects/sixth-3d/#mesh][Mesh]] section in the Sixth 3D documentation +for an explanation of 3D mesh fundamentals and how shapes are constructed. + +** CSG demo +:PROPERTIES: +:CUSTOM_ID: csg-demo +:ID: 5e6f7a8b-9c0d-1234-ef01-345678901234 +:END: + +: eu.svjatoslav.sixth.e3d.examples.essentials.CSGDemo + +#+attr_html: :class responsive-img +#+attr_latex: :width 1000px +[[file:Screenshots/Essentials/CSG demo.png]] + +Constructive Solid Geometry (CSG) boolean operations on 3D meshes. Three +operations displayed left to right: + +1. *Subtract (Cube - Sphere)* - A red cube with a spherical cavity carved out + where a blue sphere intersects it. Shows the cube's interior surfaces. + +2. *Union (Cube + Sphere)* - A merged shape combining both volumes. Red + surfaces from the cube, blue surfaces from the sphere, seamlessly joined. + +3. *Intersect (Cube ∩ Sphere)* - Only the volume shared by both shapes + remains. Shows which parts of space were occupied by both the cube and + sphere simultaneously. + +Color scheme: +- *Red* = geometry from the first operand (cube) +- *Blue* = geometry from the second operand (sphere) + +Each operation includes a text description panel below the shape. The demo +uses: +- SolidPolygonCube (red) +- SolidPolygonSphere (blue) +- CSGSolid.subtract(), union(), intersect() methods +- toMesh() conversion for rendering +- Backface culling and shading enabled + +CSG is powerful for procedural modeling, allowing complex shapes to be built +from simple primitives through boolean combinations. + +* Advanced examples +:PROPERTIES: +:CUSTOM_ID: example-scenes +:ID: 5f88b493-6ab3-4659-8280-803f75dbd5e0 +:END: + + ** Conway's Game of Life :PROPERTIES: :CUSTOM_ID: conways-game-of-life :ID: 08914390-742b-4c78-88bf-602ab9640082 :END: +: eu.svjatoslav.sixth.e3d.examples.life_demo.Main + The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970. @@ -94,9 +351,9 @@ devised by the British mathematician John Horton Conway in 1970. [[file:Screenshots/Life.png]] -Current application projects 2D game grid/matrix onto three -dimensional space. Extra dimension (height) is used to visualize -history (previous iterations) using glowing dots suspended in space. +This demo projects the 2D game grid onto three-dimensional space. The extra +dimension (height) visualizes history (previous iterations) using glowing dots +suspended in space. Usage: | key | result | @@ -112,26 +369,26 @@ Usage: :ID: 39250157-db8e-4861-a21b-8568912bd160 :END: +: eu.svjatoslav.sixth.e3d.examples.TextEditorDemo + [[file:Screenshots/Text editors.png]] -Initial test for creating user interfaces in 3D and: +Initial test for creating user interfaces in 3D, demonstrating: + window focus handling -+ picking objects using mouse -+ redirecting keyboard input to focused window - ++ picking objects using the mouse ++ redirecting keyboard input to the focused window Window focus acts like a stack. -When window is clicked with the mouse, previously focused window (if -any) is pushed to the focus stack and new window receives focus. Red +When a window is clicked with the mouse, the previously focused window (if +any) is pushed to the focus stack and the new window receives focus. A red frame appears around the window to indicate this. -When ESC key is pressed, window focus is returned to previous window -(if any). +When the ESC key is pressed, focus is returned to the previous window (if any). -When any window is focused, all keyboard input is redirected to that -window, including cursor keys. To be able to navigate around the world -again, window must be unfocused first using ESC key. +When any window is focused, all keyboard input is redirected to that window, +including cursor keys. To navigate around the world again, the window must be +unfocused first by pressing the ESC key. + TODO: @@ -151,11 +408,13 @@ again, window must be unfocused first using ESC key. :ID: a7b8c9d0-e1f2-3456-0123-567890123456 :END: +: eu.svjatoslav.sixth.e3d.examples.TextEditorDemo2 + *Quite a lot of text editors can be rendered:* [[file:Screenshots/Text editors 2.png]] -See also [[https://hackers-1995.vercel.app/][similar looking web based demo]] ! :) +See also this [[https://hackers-1995.vercel.app/][similar-looking web-based demo]]! ** Math graphs demo :PROPERTIES: @@ -163,6 +422,8 @@ See also [[https://hackers-1995.vercel.app/][similar looking web based demo]] ! :ID: b1c2d3e4-f5a6-7890-bcde-f12345678901 :END: +: eu.svjatoslav.sixth.e3d.examples.graph_demo.MathGraphsDemo + [[file:Screenshots/Mathematical formulas.png]] + TODO: instead of projecting 2D visualizations onto 3D space, @@ -174,6 +435,8 @@ See also [[https://hackers-1995.vercel.app/][similar looking web based demo]] ! :ID: b2c3d4e5-f6a7-8901-bcde-f12345678901 :END: +: eu.svjatoslav.sixth.e3d.examples.SineHeightmap + [[file:Screenshots/Sine heightmap and sphere.png]] Simple test scene. Easy to implement and looks nice. @@ -184,6 +447,8 @@ Simple test scene. Easy to implement and looks nice. :ID: c3d4e5f6-a7b8-9012-cdef-123456789012 :END: +: eu.svjatoslav.sixth.e3d.examples.OctreeDemo + [[file:Screenshots/Raytracing fractal in voxel polygon hybrid scene.png]] Test scene that is generated simultaneously using: @@ -192,31 +457,33 @@ Test scene that is generated simultaneously using: + voxels + for on-demand raytracing -Instead of storing voxels in dumb [X * Y * Z] array, dynamically -partitioned [[https://en.wikipedia.org/wiki/Octree][octree]] is used to compress data. Press "r" key anywhere in -the scene to raytrace current view through compressed voxel +Instead of storing voxels in a naive [X × Y × Z] array, a dynamically +partitioned [[https://en.wikipedia.org/wiki/Octree][octree]] compresses the data. Press the "r" key anywhere in +the scene to raytrace the current view through the compressed voxel data structure. -** Graphics Benchmark +* Graphics Benchmark :PROPERTIES: :CUSTOM_ID: graphics-benchmark :ID: e5f6a7b8-c9d0-1234-ef01-345678901234 :END: +: eu.svjatoslav.sixth.e3d.examples.benchmark.GraphicsBenchmark + An automated graphics benchmark that measures the engine's rendering performance across different rendering modes. [[file:Screenshots/Benchmark.png]] -The benchmark will cycle through different scenes that utilize different -rendering primitives (textured polygons, billboards, solid polygons, -etc.) to measure their relative performance. +The benchmark cycles through scenes that utilize different rendering +primitives (textured polygons, billboards, solid polygons, etc.) to measure +their relative performance. The camera follows a deterministic orbital path around the scene, ensuring reproducible results across runs. -At the end, the benchmark will output a report that is easy to preserve for -later comparisons. +Upon completion, the benchmark outputs a report suitable for preservation +and later comparisons. Example benchmark report: #+begin_example @@ -252,8 +519,8 @@ Star Grid 318.97 :ID: d4e5f6a7-b8c9-0123-def0-234567890123 :END: -*This program is free software: released under Creative Commons Zero -(CC0) license* +*This program is free software, released under the Creative Commons Zero +(CC0) license.* *Program author:* - Svjatoslav Agejenko @@ -268,5 +535,5 @@ Star Grid 318.97 : git clone https://www2.svjatoslav.eu/git/sixth-3d-demos.git *Understanding the Sixth 3D demos source code:* -- Read online [[https://www3.svjatoslav.eu/projects/sixth-3d-demos/apidocs/][JavaDoc]]. -- Study underlying [[https://www3.svjatoslav.eu/projects/sixth-3d/][Sixth 3D]] engine. +- Read the online [[https://www3.svjatoslav.eu/projects/sixth-3d-demos/apidocs/][JavaDoc]]. +- Study the underlying [[https://www3.svjatoslav.eu/projects/sixth-3d/][Sixth 3D]] engine. diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/ArrowDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/ArrowDemo.java index a04c237..3b45854 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/ArrowDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/ArrowDemo.java @@ -14,6 +14,9 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolyg import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonCone; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.Grid3D; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; + /** * Demo showcasing the SolidPolygonArrow shape with various colors, sizes, * orientations, and transparency levels. @@ -34,13 +37,13 @@ public class ArrowDemo { final ShapeCollection shapes = viewPanel.getRootShapeCollection(); // Position camera to view the scene - viewPanel.getCamera().getTransform().setTranslation(new Point3D(0, -200, -600)); + viewPanel.getCamera().getTransform().setTranslation(point(0, -200, -600)); // Add a 3D grid for spatial reference - final LineAppearance gridAppearance = new LineAppearance(1, new Color(100, 100, 100, 80)); + final LineAppearance gridAppearance = new LineAppearance(1, hex("64646450")); final Grid3D grid = new Grid3D( - new Point3D(-300, -200, -300), - new Point3D(300, 200, 300), + point(-300, -200, -300), + point(300, 200, 300), 100, gridAppearance ); @@ -50,49 +53,49 @@ public class ArrowDemo { // Red arrow pointing up (negative Y direction) final SolidPolygonArrow redArrow = new SolidPolygonArrow( - new Point3D(0, 150, 0), - new Point3D(0, -150, 0), + point(0, 150, 0), + point(0, -150, 0), 8, Color.RED ); shapes.addShape(redArrow); // Green arrow pointing along positive X final SolidPolygonArrow greenArrow = new SolidPolygonArrow( - new Point3D(-200, 0, 0), - new Point3D(0, 0, 0), + point(-200, 0, 0), + point(0, 0, 0), 6, Color.GREEN ); shapes.addShape(greenArrow); // Blue arrow pointing along positive Z final SolidPolygonArrow blueArrow = new SolidPolygonArrow( - new Point3D(0, 0, -200), - new Point3D(0, 0, 0), + point(0, 0, -200), + point(0, 0, 0), 6, Color.BLUE ); shapes.addShape(blueArrow); // Yellow arrow pointing diagonally final SolidPolygonArrow yellowArrow = new SolidPolygonArrow( - new Point3D(100, 100, 100), - new Point3D(300, -100, 300), + point(100, 100, 100), + point(300, -100, 300), 10, Color.YELLOW ); shapes.addShape(yellowArrow); // Semi-transparent cyan arrow (50% opacity) final SolidPolygonArrow transparentCyanArrow = new SolidPolygonArrow( - new Point3D(-150, 50, -100), - new Point3D(-50, -100, 100), - 8, new Color(0, 255, 255, 128) + point(-150, 50, -100), + point(-50, -100, 100), + 8, hex("00FFFF80") ); shapes.addShape(transparentCyanArrow); // Semi-transparent magenta arrow (25% opacity) final SolidPolygonArrow transparentMagentaArrow = new SolidPolygonArrow( - new Point3D(50, 200, 50), - new Point3D(50, 0, 50), - 12, new Color(255, 0, 255, 64) + point(50, 200, 50), + point(50, 0, 50), + 12, hex("FF00FF40") ); shapes.addShape(transparentMagentaArrow); @@ -105,21 +108,21 @@ public class ArrowDemo { final double endX = (radius + 80) * Math.cos(angle); final double endZ = (radius + 80) * Math.sin(angle); -final SolidPolygonArrow circleArrow = new SolidPolygonArrow( - new Point3D(startX, -80, startZ), - new Point3D(endX, -80, endZ), - 4, Color.WHITE - ); + final SolidPolygonArrow circleArrow = new SolidPolygonArrow( + point(startX, -80, startZ), + point(endX, -80, endZ), + 4, Color.WHITE + ); shapes.addShape(circleArrow); } // A standalone cone to demonstrate SolidPolygonCone final SolidPolygonCone standaloneCone = new SolidPolygonCone( - new Point3D(-300, 0, 0), + point(-300, 0, 0), 40, 80, 16, - new Color(255, 128, 0) + hex("FF8000FF") ); shapes.addShape(standaloneCone); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/OctreeDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/OctreeDemo.java index aedc08c..d4e1c9c 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/OctreeDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/OctreeDemo.java @@ -28,6 +28,9 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.Grid3D import java.awt.event.KeyEvent; import java.util.Vector; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; + /** * Demo showing volumetric octree rendering with raytracing capability. * Creates a 3D scene with various geometric shapes stored in an octree data structure. @@ -39,12 +42,12 @@ public class OctreeDemo extends WorldNavigationUserInputTracker { * Scale factor for rendering octree voxels in the scene. */ private static final double magnification = 5; - private final LineAppearance gridAppearance = new LineAppearance(40, new Color(255, - 0, 0, 60)); + private final LineAppearance gridAppearance = new LineAppearance(40, hex("FF00003C")); private final Vector lights = new Vector<>(); private OctreeVolume octreeVolume; private ShapeCollection shapeCollection; private ViewPanel viewPanel; + /** * Creates a new OctreeDemo instance. */ @@ -70,13 +73,13 @@ public class OctreeDemo extends WorldNavigationUserInputTracker { private void addLightToBothSystems(final Point3D location, final Color color, final float brightness) { shapeCollection.addShape(new LightSourceMarker(new Point3D(location) - .scaleUp(magnification), color)); + .multiply(magnification), color)); lights.add(new eu.svjatoslav.sixth.e3d.renderer.octree.raytracer.LightSource( location, color, brightness)); viewPanel.getLightingManager().addLight(new LightSource( - new Point3D(location).scaleUp(magnification), color, brightness * 50)); + new Point3D(location).multiply(magnification), color, brightness * 50)); } /** @@ -143,32 +146,32 @@ public class OctreeDemo extends WorldNavigationUserInputTracker { shapeCollection = viewPanel.getRootShapeCollection(); shapeCollection.addShape(new Grid3D( - new Point3D(-10000, -10000, -10000), new Point3D(10000, 10000, + point(-10000, -10000, -10000), point(10000, 10000, 10000), 4000, gridAppearance)); - addLightToBothSystems(new Point3D(20, -450, 240), new Color(255, 255, 255), 100); - addLightToBothSystems(new Point3D(-150, -116, 141), new Color(255, 0, 0), 10); + addLightToBothSystems(point(20, -450, 240), new Color(255, 255, 255), 100); + addLightToBothSystems(point(-150, -116, 141), new Color(255, 0, 0), 10); dotSpiral(); // arbitrary rectangles putRect(new IntegerPoint(-10, -10, -10), new IntegerPoint(10, 10, -20), - new Color(200, 255, 200, 100)); + hex("C8FFC864")); putRect(new IntegerPoint(-3, 0, -30), new IntegerPoint(12, 3, 300), - new Color(255, 200, 200, 100)); + hex("FFC8C864")); putRect(new IntegerPoint(-20, 20, -20), new IntegerPoint(20, 80, 20), - new Color(255, 200, 255, 100)); + hex("FFC8FF64")); tiledFloor(); fractal(-50, 20, 100, 32, 1); - final TextCanvas message = new TextCanvas(new Transform(new Point3D( + final TextCanvas message = new TextCanvas(new Transform(point( -10, 20, -180)), "Press \"r\" to raytrace current view", Color.WHITE, Color.PURPLE); shapeCollection.addShape(message); @@ -204,8 +207,8 @@ public class OctreeDemo extends WorldNavigationUserInputTracker { */ private void putPixel(final int x, final int y, final int z, final Color color) { - shapeCollection.addShape(new GlowingPoint(new Point3D(x, y, z) - .scaleUp(magnification), 3 * magnification, color)); + shapeCollection.addShape(new GlowingPoint(point(x, y, z) + .multiply(magnification), 3 * magnification, color)); octreeVolume.putCell(x, y, z, color); } @@ -219,8 +222,8 @@ public class OctreeDemo extends WorldNavigationUserInputTracker { */ private void putRect(IntegerPoint p1, IntegerPoint p2, final Color color) { final SolidPolygonRectangularBox box = new SolidPolygonRectangularBox( - new Point3D(p1).scaleUp(magnification), - new Point3D(p2).scaleUp(magnification), color); + new Point3D(p1).multiply(magnification), + new Point3D(p2).multiply(magnification), color); box.setShadingEnabled(true); shapeCollection.addShape(box); octreeVolume.fillRectangle(p1, p2, color); @@ -247,7 +250,7 @@ public class OctreeDemo extends WorldNavigationUserInputTracker { private void tiledFloor() { final int step = 40; final int size = step - 15; - Color color = new Color(255, 255, 255, 100); + Color color = hex("FFFFFF64"); for (int x = -200; x < 200; x += step) for (int z = -200; z < 200; z += step) putRect( diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/RainingNumbersDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/RainingNumbersDemo.java index c2c82cd..bc6f6b8 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/RainingNumbersDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/RainingNumbersDemo.java @@ -12,6 +12,8 @@ import eu.svjatoslav.sixth.e3d.gui.ViewPanel; import eu.svjatoslav.sixth.e3d.gui.FrameListener; import eu.svjatoslav.sixth.e3d.math.Transform; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; + +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractShape; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas.TextCanvas; @@ -87,7 +89,7 @@ public class RainingNumbersDemo implements FrameListener { Random random = new Random(); for (int i = 0; i < NUMBERS_COUNT; i++) { - final Point3D location = new Point3D((Math.random() * AREA) + final Point3D location = point((Math.random() * AREA) - AREA_HALF, (Math.random() * AREA) - AREA_HALF, (Math.random() * AREA) - AREA_HALF); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/SineHeightmap.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/SineHeightmap.java index 25642dd..64433da 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/SineHeightmap.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/SineHeightmap.java @@ -1,5 +1,5 @@ /* - * Sixth 3D engine demos. Author: Svjatoslav Agejenko. + * Sixth 3D engine demos. Author: Svjatoslav Agejenko. * This project is released under Creative Commons Zero (CC0) license. * */ @@ -14,49 +14,56 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon.SolidPolygon; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.WireframeSphere; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.origin; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; + /** * Demo showing a sine heightmap surface with a central wireframe sphere. * Two wobbly surfaces are positioned above and below the sphere. */ public class SineHeightmap { + /** + * Frequency of the wave pattern in the wobbly surfaces. + */ + private static final double WAVE_FREQUENCY = 50d; + /** + * Amplitude of the wave pattern in the wobbly surfaces. + */ + private static final double WAVE_AMPLITUDE = 50d; + /** + * Color for the square plates in the wobbly surfaces. + */ + private static final Color SQUARE_PLATE_COLOR = hex("88F7"); /** * Creates a new GraphDemo instance. */ public SineHeightmap() { } - /** Frequency of the wave pattern in the wobbly surfaces. */ - private static final double WAVE_FREQUENCY = 50d; - /** Amplitude of the wave pattern in the wobbly surfaces. */ - private static final double WAVE_AMPLITUDE = 50d; - /** Color for the square plates in the wobbly surfaces. */ - private static final Color SQUARE_PLATE_COLOR = new Color("88F7"); - /** Scale factor for the graph rendering. */ - private static final double GRAPH_SCALE = 50d; - /** * Creates a single square plate at the specified position. + * * @param shapeCollection the collection to add the plate to - * @param y the Y coordinate (elevation) - * @param x the X coordinate - * @param z the Z coordinate + * @param y the Y coordinate (elevation) + * @param x the X coordinate + * @param z the Z coordinate */ private static void makeSquarePlate(final ShapeCollection shapeCollection, final double y, final double x, final double z) { - final Point3D p1 = new Point3D(x, y, z); - final Point3D p2 = new Point3D(x + 20, y, z); - final Point3D p3 = new Point3D(x, y, z + 20); - final Point3D p4 = new Point3D(x + 20, y, z + 20); - final SolidPolygon polygon1 = new SolidPolygon(p1, p2, p3, SQUARE_PLATE_COLOR); - final SolidPolygon polygon2 = new SolidPolygon(p4, p2, p3, SQUARE_PLATE_COLOR); - shapeCollection.addShape(polygon1); - shapeCollection.addShape(polygon2); + final Point3D p1 = point(x, y, z); + final Point3D p2 = point(x + 20, y, z); + final Point3D p3 = point(x, y, z + 20); + final Point3D p4 = point(x + 20, y, z + 20); + final SolidPolygon quad = SolidPolygon.quad(p1, p2, p4, p3, SQUARE_PLATE_COLOR); + shapeCollection.addShape(quad); } /** * Creates a wobbly surface composed of square plates arranged in a wave pattern. - * @param shapeCollection the collection to add plates to + * + * @param shapeCollection the collection to add plates to * @param surfaceElevation the base Y elevation of the surface */ private static void addWobblySurface(final ShapeCollection shapeCollection, @@ -75,6 +82,7 @@ public class SineHeightmap { /** * Entry point for the graph demo. + * * @param args command line arguments (ignored) */ public static void main(final String[] args) { @@ -83,25 +91,26 @@ public class SineHeightmap { final ShapeCollection geometryCollection = viewFrame.getViewPanel() .getRootShapeCollection(); - viewFrame.getViewPanel().getCamera().getTransform().setTranslation(new Point3D(0, 0, -500)); + viewFrame.getViewPanel().getCamera().getTransform().setTranslation(point(0, 0, -500)); addSphere(geometryCollection); addWobblySurface(geometryCollection, 200); addWobblySurface(geometryCollection, -200); - + viewFrame.getViewPanel().repaintDuringNextViewUpdate(); } /** * Adds a wireframe sphere at the center of the scene. + * * @param geometryCollection the collection to add the sphere to */ private static void addSphere(ShapeCollection geometryCollection) { - geometryCollection.addShape(new WireframeSphere(new Point3D(0, 0, 0), + geometryCollection.addShape(new WireframeSphere(origin(), 100, new LineAppearance( 4, - new Color(255,0, 0, 30)) + hex("FF00001E")) )); } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo.java index 676c3fc..79fa5ad 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo.java @@ -1,24 +1,25 @@ /* - * Sixth 3D engine demos. Author: Svjatoslav Agejenko. + * Sixth 3D engine demos. Author: Svjatoslav Agejenko. * This project is released under Creative Commons Zero (CC0) license. * -*/ + */ package eu.svjatoslav.sixth.e3d.examples; import eu.svjatoslav.sixth.e3d.geometry.Point2D; -import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.geometry.Rectangle; import eu.svjatoslav.sixth.e3d.gui.ViewFrame; import eu.svjatoslav.sixth.e3d.gui.ViewPanel; import eu.svjatoslav.sixth.e3d.gui.textEditorComponent.LookAndFeel; import eu.svjatoslav.sixth.e3d.gui.textEditorComponent.TextEditComponent; import eu.svjatoslav.sixth.e3d.math.Transform; -import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.Grid2D; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; + /** * Demo showing a grid of 3D text editor components. * Creates a 5x5 grid of text editors floating in 3D space with a decorative grid @@ -34,6 +35,7 @@ public class TextEditorDemo { /** * Entry point for the text editor demo. + * * @param args command line arguments (ignored) */ public static void main(final String[] args) { @@ -49,27 +51,28 @@ public class TextEditorDemo { addGrid(shapeCollection); addTextEditors(viewPanel, shapeCollection); - + viewFrame.getViewPanel().repaintDuringNextViewUpdate(); } /** * Adds a decorative grid below the text editors. + * * @param shapeCollection the collection to add the grid to */ private static void addGrid(ShapeCollection shapeCollection) { final Transform transform = Transform.fromAngles(0, 100, 0, 0, Math.PI / 2, 0); final Rectangle rectangle = new Rectangle(2000); - final LineAppearance appearance = new LineAppearance(10, new Color( - "00b3ad")); + final LineAppearance appearance = new LineAppearance(10, hex("00b3ad")); shapeCollection.addShape(new Grid2D(transform, rectangle, 10, 10, appearance)); } /** * Creates a grid of text editor components arranged in 3D space. - * @param viewPanel the view panel for the text editors + * + * @param viewPanel the view panel for the text editors * @param shapeCollection the collection to add editors to */ private static void addTextEditors(ViewPanel viewPanel, ShapeCollection shapeCollection) { @@ -78,7 +81,7 @@ public class TextEditorDemo { for (double x = -500 * m; x <= (500 * m); x += 250 * m) { final TextEditComponent textEditor = new TextEditComponent( - new Transform(new Point3D(x, 0, z)), viewPanel, + new Transform(point(x, 0, z)), viewPanel, new Point2D(200, 120), new LookAndFeel()); shapeCollection.addShape(textEditor); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo2.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo2.java index 28b0246..ed38515 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo2.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/TextEditorDemo2.java @@ -1,20 +1,18 @@ /* - * Sixth 3D engine demos. Author: Svjatoslav Agejenko. + * Sixth 3D engine demos. Author: Svjatoslav Agejenko. * This project is released under Creative Commons Zero (CC0) license. * -*/ + */ package eu.svjatoslav.sixth.e3d.examples; import eu.svjatoslav.sixth.e3d.geometry.Point2D; -import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.geometry.Rectangle; import eu.svjatoslav.sixth.e3d.gui.ViewFrame; import eu.svjatoslav.sixth.e3d.gui.ViewPanel; import eu.svjatoslav.sixth.e3d.gui.textEditorComponent.LookAndFeel; import eu.svjatoslav.sixth.e3d.gui.textEditorComponent.TextEditComponent; import eu.svjatoslav.sixth.e3d.math.Transform; -import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.Grid2D; @@ -26,7 +24,9 @@ import java.io.InputStreamReader; import java.net.URISyntaxException; import java.util.stream.Collectors; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; import static eu.svjatoslav.sixth.e3d.math.Transform.fromAngles; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; import static java.lang.Math.PI; /** @@ -45,6 +45,7 @@ public class TextEditorDemo2 { /** * Entry point for the text editor city demo. + * * @param args command line arguments (ignored) */ public static void main(final String[] args) { @@ -57,10 +58,43 @@ public class TextEditorDemo2 { } } + /** + * Adds a grid to the scene for visual reference. + * + * @param shapeCollection the collection to add the grid to + */ + private static void addGrid(ShapeCollection shapeCollection) { + final Transform transform = fromAngles(0, 100, 0, 0, PI / 2, 0); + + final Rectangle rectangle = new Rectangle(10000); + final LineAppearance appearance = new LineAppearance(10, hex("00b3ad")); + + shapeCollection.addShape(new Grid2D(transform, rectangle, 50, 50, appearance)); + } + + /** + * Reads a resource file as a string. + * + * @param fileName the name of the resource file + * @return the file contents as a string, or null if not found + * @throws IOException if an I/O error occurs + */ + static String getResourceFileAsString(String fileName) throws IOException { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + try (InputStream is = classLoader.getResourceAsStream(fileName)) { + if (is == null) return null; + try (InputStreamReader isr = new InputStreamReader(is); + BufferedReader reader = new BufferedReader(isr)) { + return reader.lines().collect(Collectors.joining(System.lineSeparator())); + } + } + } + /** * Builds and displays the 3D city scene with text editors. + * * @throws URISyntaxException if resource URI is malformed - * @throws IOException if demo text file cannot be read + * @throws IOException if demo text file cannot be read */ public void build() throws URISyntaxException, IOException { final ViewFrame viewFrame = new ViewFrame("Text Editors City"); @@ -74,66 +108,53 @@ public class TextEditorDemo2 { addGrid(shapeCollection); addCity(viewPanel, shapeCollection); - + viewFrame.getViewPanel().repaintDuringNextViewUpdate(); } /** * Creates a grid of buildings in the city. - * @param viewPanel the view panel for the text editors + * + * @param viewPanel the view panel for the text editors * @param shapeCollection the collection to add buildings to * @throws URISyntaxException if resource URI is malformed - * @throws IOException if demo text file cannot be read + * @throws IOException if demo text file cannot be read */ private void addCity(ViewPanel viewPanel, ShapeCollection shapeCollection) throws URISyntaxException, IOException { int citySize = 4000; - for (int z = -citySize; z< citySize; z+= 1000 ){ - for (int x = -citySize; x< citySize; x+= 1000 ){ + for (int z = -citySize; z < citySize; z += 1000) { + for (int x = -citySize; x < citySize; x += 1000) { addBuilding(viewPanel, shapeCollection, x, z); } } } - - /** - * Adds a grid to the scene for visual reference. - * @param shapeCollection the collection to add the grid to - */ - private static void addGrid(ShapeCollection shapeCollection) { - final Transform transform = fromAngles(0, 100, 0, 0, PI / 2, 0); - - final Rectangle rectangle = new Rectangle(10000); - final LineAppearance appearance = new LineAppearance(10, new Color( - "00b3ad")); - - shapeCollection.addShape(new Grid2D(transform, rectangle, 50, 50, appearance)); - } - - /** * Adds a single building with four text editor panels facing different directions. - * @param viewPanel the view panel for the text editors + * + * @param viewPanel the view panel for the text editors * @param shapeCollection the collection to add the building to - * @param x the X coordinate of the building center - * @param z the Z coordinate of the building center + * @param x the X coordinate of the building center + * @param z the Z coordinate of the building center * @throws URISyntaxException if resource URI is malformed - * @throws IOException if demo text file cannot be read + * @throws IOException if demo text file cannot be read */ private void addBuilding(ViewPanel viewPanel, ShapeCollection shapeCollection, double x, double z) throws URISyntaxException, IOException { - addTextEditor(viewPanel, shapeCollection, new Transform(new Point3D(x, -390, z-200))); + addTextEditor(viewPanel, shapeCollection, new Transform(point(x, -390, z - 200))); - addTextEditor(viewPanel, shapeCollection, fromAngles(x, -390, z+200, PI, 0, 0)); + addTextEditor(viewPanel, shapeCollection, fromAngles(x, -390, z + 200, PI, 0, 0)); - addTextEditor(viewPanel, shapeCollection, fromAngles(x-200, -390, z, PI/2, 0, 0)); + addTextEditor(viewPanel, shapeCollection, fromAngles(x - 200, -390, z, PI / 2, 0, 0)); - addTextEditor(viewPanel, shapeCollection, fromAngles(x+200, -390, z, PI/2*3f, 0, 0)); + addTextEditor(viewPanel, shapeCollection, fromAngles(x + 200, -390, z, PI / 2 * 3f, 0, 0)); } /** * Adds a single text editor component at the specified transform. - * @param viewPanel the view panel for the text editor + * + * @param viewPanel the view panel for the text editor * @param shapeCollection the collection to add the editor to - * @param transform the position and orientation of the editor + * @param transform the position and orientation of the editor * @throws IOException if demo text file cannot be read */ private void addTextEditor(ViewPanel viewPanel, ShapeCollection shapeCollection, Transform transform) throws IOException { @@ -144,42 +165,26 @@ public class TextEditorDemo2 { viewPanel, new Point2D(400, 1000), lookAndFeel - ); + ); String text = getResourceFileAsString("demo.txt"); textEditor.setText(text); - textEditor.goToLine((int)(Math.random()*200f)); + textEditor.goToLine((int) (Math.random() * 200f)); shapeCollection.addShape(textEditor); } /** * Creates the look and feel for text editors with a dark theme. + * * @return a LookAndFeel configured with dark blue background and light text */ private LookAndFeel getLookAndFeel() { LookAndFeel lookAndFeel = new LookAndFeel(); - lookAndFeel.background = new Color(20, 20, 50, 150); + lookAndFeel.background = hex("141E3296"); lookAndFeel.tabStopBackground = lookAndFeel.background; - lookAndFeel.foreground = new Color(150, 150, 255,250); + lookAndFeel.foreground = hex("9696FFFA"); return lookAndFeel; } - /** - * Reads a resource file as a string. - * @param fileName the name of the resource file - * @return the file contents as a string, or null if not found - * @throws IOException if an I/O error occurs - */ - static String getResourceFileAsString(String fileName) throws IOException { - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - try (InputStream is = classLoader.getResourceAsStream(fileName)) { - if (is == null) return null; - try (InputStreamReader isr = new InputStreamReader(is); - BufferedReader reader = new BufferedReader(isr)) { - return reader.lines().collect(Collectors.joining(System.lineSeparator())); - } - } - } - } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/TexturedCube.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/TexturedCube.java index ecb883e..f4ddb33 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/TexturedCube.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/TexturedCube.java @@ -8,7 +8,7 @@ package eu.svjatoslav.sixth.e3d.examples.benchmark; import eu.svjatoslav.sixth.e3d.geometry.Point2D; import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.math.Vertex; -import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.texturedpolygon.TexturedPolygon; +import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.texturedpolygon.TexturedTriangle; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape; import eu.svjatoslav.sixth.e3d.renderer.raster.texture.Texture; @@ -54,7 +54,7 @@ public class TexturedCube extends AbstractCompositeShape { private void addTexturedFace(Point3D p1, Point3D p2, Point3D p3, Point3D p4, Point2D t1, Point2D t2, Point2D t3, Point2D t4, Texture texture) { - TexturedPolygon tri1 = new TexturedPolygon( + TexturedTriangle tri1 = new TexturedTriangle( new Vertex(p1, t1), new Vertex(p2, t2), new Vertex(p3, t3), @@ -62,7 +62,7 @@ public class TexturedCube extends AbstractCompositeShape { ); tri1.setBackfaceCulling(true); - TexturedPolygon tri2 = new TexturedPolygon( + TexturedTriangle tri2 = new TexturedTriangle( new Vertex(p1, t1), new Vertex(p3, t3), new Vertex(p4, t4), diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/AxisArrowsDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/AxisArrowsDemo.java deleted file mode 100644 index 8bcd0a0..0000000 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/AxisArrowsDemo.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Sixth 3D engine demos. Author: Svjatoslav Agejenko. - * This project is released under Creative Commons Zero (CC0) license. - */ -package eu.svjatoslav.sixth.e3d.examples.essentials; - -import eu.svjatoslav.sixth.e3d.geometry.Point3D; -import eu.svjatoslav.sixth.e3d.gui.ViewFrame; -import eu.svjatoslav.sixth.e3d.gui.ViewPanel; -import eu.svjatoslav.sixth.e3d.renderer.raster.Color; -import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; -import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance; -import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.ForwardOrientedTextBlock; -import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonArrow; -import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.Grid3D; - -/** - * Demo displaying coordinate system axes using 3D arrows. - * - *

This demo illustrates the Sixth 3D coordinate system with three colored - * arrows originating from the origin (0,0,0), each pointing along a positive - * axis direction:

- * - * - * - *

A reference grid at Y=0 provides spatial context. Text labels identify - * each axis.

- * - * @see SolidPolygonArrow - * @see ForwardOrientedTextBlock - */ -public class AxisArrowsDemo { - - /** - * Length of each axis arrow. - */ - private static final double ARROW_LENGTH = 200; - - /** - * Radius of the arrow body (cylindrical shaft). - */ - private static final double BODY_RADIUS = 6; - - /** - * Distance from arrow tip to text label position. - */ - private static final double LABEL_OFFSET = 20; - - /** - * Scale factor for text labels. - */ - private static final double LABEL_SCALE = 20.0; - - /** - * Entry point for the axis arrows demo. - * - * @param args command line arguments (ignored) - */ - public static void main(final String[] args) { - final ViewFrame viewFrame = new ViewFrame("Axis Arrows Demo"); - final ViewPanel viewPanel = viewFrame.getViewPanel(); - final ShapeCollection shapes = viewPanel.getRootShapeCollection(); - - // Position camera to view all three axes - viewPanel.getCamera().getTransform().set(130.66, -65.49, -248.18, -0.06, -0.36, -0.00); - - // Create reference grid at Y=0 plane - createReferenceGrid(shapes); - - // Create axis arrows - createAxisArrows(shapes); - - viewPanel.repaintDuringNextViewUpdate(); - } - - /** - * Creates a reference grid on the Y=0 plane. - * - * @param shapes the shape collection to add the grid to - */ - private static void createReferenceGrid(final ShapeCollection shapes) { - final LineAppearance gridAppearance = new LineAppearance( - 1, new Color(80, 80, 100)); - final Grid3D grid = new Grid3D( - new Point3D(-300, 0, -300), - new Point3D(300, 0, 300), - 50, - gridAppearance - ); - shapes.addShape(grid); - } - - /** - * Creates the three axis arrows and their labels. - * - * @param shapes the shape collection to add the arrows to - */ - private static void createAxisArrows(final ShapeCollection shapes) { - // X-axis arrow (RED) - points in positive X direction (RIGHT) - final SolidPolygonArrow xArrow = new SolidPolygonArrow( - new Point3D(0, 0, 0), - new Point3D(ARROW_LENGTH, 0, 0), - BODY_RADIUS, new Color(255, 0, 0, 180) - ); - shapes.addShape(xArrow); - createLabel(shapes, "X", new Point3D(ARROW_LENGTH + LABEL_OFFSET, 0, 0), Color.RED); - - // Y-axis arrow (GREEN) - points in positive Y direction (DOWN) - final SolidPolygonArrow yArrow = new SolidPolygonArrow( - new Point3D(0, 0, 0), - new Point3D(0, ARROW_LENGTH, 0), - BODY_RADIUS, new Color(0, 255, 0, 180) - ); - shapes.addShape(yArrow); - createLabel(shapes, "Y", new Point3D(0, ARROW_LENGTH + LABEL_OFFSET, 0), Color.GREEN); - - // Z-axis arrow (BLUE) - points in positive Z direction (AWAY) - final SolidPolygonArrow zArrow = new SolidPolygonArrow( - new Point3D(0, 0, 0), - new Point3D(0, 0, ARROW_LENGTH), - BODY_RADIUS, new Color(0, 0, 255, 180) - ); - shapes.addShape(zArrow); - createLabel(shapes, "Z", new Point3D(0, 0, ARROW_LENGTH + LABEL_OFFSET), Color.BLUE); - } - - /** - * Creates a text label at the specified position. - * - * @param shapes the shape collection to add the label to - * @param text the label text - * @param position the 3D position of the label - * @param color the text color - */ - private static void createLabel(final ShapeCollection shapes, - final String text, - final Point3D position, - final Color color) { - final ForwardOrientedTextBlock label = new ForwardOrientedTextBlock( - position, LABEL_SCALE, 2, text, color - ); - shapes.addShape(label); - } -} \ No newline at end of file diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/CSGDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/CSGDemo.java index b8d2cda..6169fc0 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/CSGDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/CSGDemo.java @@ -5,17 +5,21 @@ */ package eu.svjatoslav.sixth.e3d.examples.essentials; -import eu.svjatoslav.sixth.e3d.csg.CSG; import eu.svjatoslav.sixth.e3d.geometry.Point3D; +import eu.svjatoslav.sixth.e3d.gui.TextPointer; import eu.svjatoslav.sixth.e3d.gui.ViewFrame; import eu.svjatoslav.sixth.e3d.gui.ViewPanel; +import eu.svjatoslav.sixth.e3d.math.Transform; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.lighting.LightSource; -import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.ForwardOrientedTextBlock; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonCube; -import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonMesh; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonSphere; +import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas.TextCanvas; + +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.origin; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; /** * Demo showcasing Constructive Solid Geometry (CSG) boolean operations. @@ -27,40 +31,35 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolyg *
  • Intersect: The volume shared by a cube and sphere
  • * * - *

    Shapes are rendered with slight transparency (85% opacity) to allow - * seeing internal structure. The demo demonstrates how existing composite - * shapes like {@link SolidPolygonCube} and {@link SolidPolygonSphere} can - * be used with CSG operations.

    + *

    All operations use a consistent color scheme: red for the first argument + * (cube) and blue for the second argument (sphere). This makes it easy to see + * which parts of the result came from which input shape.

    * *

    Run this demo:

    *
    {@code
    - * java -cp target/sixth-3d-demos.jar eu.svjatoslav.sixth.e3d.examples.CSGDemo
    + * java -cp target/sixth-3d-demos.jar eu.svjatoslav.sixth.e3d.examples.essentials.CSGDemo
      * }
    * - * @see CSG the CSG solid class - * @see SolidPolygonMesh the renderable mesh + * @see eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape#union + * @see eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape#subtract + * @see eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape#intersect */ public class CSGDemo { /** - * Distance between shapes on the X axis. - */ - private static final double SPACING = 500; - - /** - * Size of the cube (half-edge length). + * Color for the first argument in boolean operations (cube). */ - private static final double CUBE_SIZE = 80; + private static final Color COLOR_FIRST = hex("FF6464D9"); /** - * Radius of the sphere (slightly larger for interesting intersection). + * Color for the second argument in boolean operations (sphere). */ - private static final double SPHERE_RADIUS = 96; + private static final Color COLOR_SECOND = hex("6496FFD9"); /** - * Number of segments for the sphere (smoothness). + * Distance between shapes on the X axis. */ - private static final int SPHERE_SEGMENTS = 12; + private static final double SPACING = 400; /** * Entry point for the CSG demo. @@ -68,26 +67,23 @@ public class CSGDemo { * @param args command line arguments (ignored) */ public static void main(final String[] args) { - final ViewFrame viewFrame = new ViewFrame("CSG Demo - Boolean Operations"); + final ViewFrame viewFrame = new ViewFrame("CSG demo - Boolean operations"); final ViewPanel viewPanel = viewFrame.getViewPanel(); final ShapeCollection shapes = viewPanel.getRootShapeCollection(); // Position camera to view all three shapes - viewPanel.getCamera().getTransform().set(0, -150, -600, 0, 0, 0); + viewPanel.getCamera().getTransform().set(-244.24, 254.40, -458.83, -0.26, 0.24, -0.00); // Set up lighting - viewPanel.getLightingManager().setAmbientLight(new Color(60, 60, 70)); + viewPanel.getLightingManager().setAmbientLight(hex("3C3C46")); // Create lights createLights(viewPanel, shapes); // Create the three CSG demonstrations - createSubtractDemo(shapes, -SPACING, 0, 0); - createUnionDemo(shapes, 0, 0, 0); - createIntersectDemo(shapes, SPACING, 0, 0); - - // Add labels - createLabels(shapes); + createSubtractDemo(shapes, point(-SPACING, 0, 0)); + createUnionDemo(shapes, origin()); + createIntersectDemo(shapes, point(SPACING, 0, 0)); viewPanel.repaintDuringNextViewUpdate(); } @@ -96,118 +92,100 @@ public class CSGDemo { * Creates the subtract operation demo: cube - sphere. * Results in a cube with a spherical cavity. * - * @param shapes the shape collection - * @param x the X position - * @param y the Y position - * @param z the Z position + * @param shapes the shape collection + * @param location the position for the result */ - private static void createSubtractDemo(final ShapeCollection shapes, - final double x, final double y, final double z) { - final SolidPolygonCube cube = new SolidPolygonCube( - new Point3D(0, 0, 0), CUBE_SIZE, Color.WHITE); - final SolidPolygonSphere sphere = new SolidPolygonSphere( - new Point3D(0, 0, 0), SPHERE_RADIUS, SPHERE_SEGMENTS, Color.WHITE); - - final CSG cubeCSG = CSG.fromCompositeShape(cube); - final CSG sphereCSG = CSG.fromCompositeShape(sphere); + private static void createSubtractDemo(final ShapeCollection shapes, final Point3D location) { - final CSG result = cubeCSG.subtract(sphereCSG); + final SolidPolygonCube cube = new SolidPolygonCube(origin(), 80, COLOR_FIRST); + cube.subtract(new SolidPolygonSphere(origin(), 96, 12, COLOR_SECOND)); - final SolidPolygonMesh mesh = result.toMesh(new Color(255, 100, 100, 217), new Point3D(x, y, z)); - mesh.setShadingEnabled(true); - mesh.setBackfaceCulling(true); + shapes.addShape(cube + .setTransform(new Transform(location)) + .setShadingEnabled(true) + .setBackfaceCulling(true)); - shapes.addShape(mesh); + final String description = + "Subtract: Cube - Sphere\n" + + "\n" + + "Red = Cube (kept)\n" + + "Blue = Sphere (carved out)"; - System.out.println("Subtract (cube - sphere): " + mesh.getTriangleCount() + " triangles"); + shapes.addShape(createDescriptionPanel(location, description)); } /** * Creates the union operation demo: cube + sphere. * Results in a combined shape. * - * @param shapes the shape collection - * @param x the X position - * @param y the Y position - * @param z the Z position + * @param shapes the shape collection + * @param location the position for the result */ - private static void createUnionDemo(final ShapeCollection shapes, - final double x, final double y, final double z) { - final SolidPolygonCube cube = new SolidPolygonCube( - new Point3D(0, 0, 0), CUBE_SIZE, Color.WHITE); - final SolidPolygonSphere sphere = new SolidPolygonSphere( - new Point3D(0, 0, 0), SPHERE_RADIUS, SPHERE_SEGMENTS, Color.WHITE); + private static void createUnionDemo(final ShapeCollection shapes, final Point3D location) { - final CSG cubeCSG = CSG.fromCompositeShape(cube); - final CSG sphereCSG = CSG.fromCompositeShape(sphere); + final SolidPolygonCube cube = new SolidPolygonCube(origin(), 80, COLOR_FIRST); + cube.union(new SolidPolygonSphere(origin(), 96, 12, COLOR_SECOND)); - final CSG result = cubeCSG.union(sphereCSG); + shapes.addShape(cube + .setTransform(new Transform(location)) + .setShadingEnabled(true) + .setBackfaceCulling(true)); - final SolidPolygonMesh mesh = result.toMesh(new Color(100, 255, 100, 217), new Point3D(x, y, z)); - mesh.setShadingEnabled(true); - mesh.setBackfaceCulling(true); + final String description = + "Union: Cube + Sphere\n" + + "\n" + + "Red = Cube\n" + + "Blue = Sphere"; - shapes.addShape(mesh); - - System.out.println("Union (cube + sphere): " + mesh.getTriangleCount() + " triangles"); + shapes.addShape(createDescriptionPanel(location, description)); } /** * Creates the intersect operation demo: cube ∩ sphere. * Results in the volume shared by both shapes. * - * @param shapes the shape collection - * @param x the X position - * @param y the Y position - * @param z the Z position + * @param shapes the shape collection + * @param location the position for the result */ - private static void createIntersectDemo(final ShapeCollection shapes, - final double x, final double y, final double z) { - final SolidPolygonCube cube = new SolidPolygonCube( - new Point3D(0, 0, 0), CUBE_SIZE, Color.WHITE); - final SolidPolygonSphere sphere = new SolidPolygonSphere( - new Point3D(0, 0, 0), SPHERE_RADIUS, SPHERE_SEGMENTS, Color.WHITE); - - final CSG cubeCSG = CSG.fromCompositeShape(cube); - final CSG sphereCSG = CSG.fromCompositeShape(sphere); + private static void createIntersectDemo(final ShapeCollection shapes, final Point3D location) { - final CSG result = cubeCSG.intersect(sphereCSG); + final SolidPolygonCube cube = new SolidPolygonCube(origin(), 80, COLOR_FIRST); + cube.intersect(new SolidPolygonSphere(origin(), 96, 12, COLOR_SECOND)); - final SolidPolygonMesh mesh = result.toMesh(new Color(100, 150, 255, 217), new Point3D(x, y, z)); - mesh.setShadingEnabled(true); - mesh.setBackfaceCulling(true); + shapes.addShape(cube + .setTransform(new Transform(location)) + .setShadingEnabled(true) + .setBackfaceCulling(true)); - shapes.addShape(mesh); + final String description = + "Intersect: Cube ∩ Sphere\n" + + "\n" + + "Red = from Cube\n" + + "Blue = from Sphere"; - System.out.println("Intersect (cube ∩ sphere): " + mesh.getTriangleCount() + " triangles"); + shapes.addShape(createDescriptionPanel(location, description)); } /** - * Creates labels for each operation. + * Creates a description panel positioned below a shape. * - * @param shapes the shape collection + * @param location the position of the associated shape + * @param text the description text to display + * @return a TextCanvas positioned below the shape */ - private static void createLabels(final ShapeCollection shapes) { - final double labelY = -150; - final double labelZ = 0; - - // Subtract label - shapes.addShape(new ForwardOrientedTextBlock( - new Point3D(-SPACING, labelY, labelZ), - 8.0, 2, "Subtract", Color.RED - )); - - // Union label - shapes.addShape(new ForwardOrientedTextBlock( - new Point3D(0, labelY, labelZ), - 8.0, 2, "Union", Color.GREEN - )); - - // Intersect label - shapes.addShape(new ForwardOrientedTextBlock( - new Point3D(SPACING, labelY, labelZ), - 8.0, 2, "Intersect", Color.BLUE - )); + private static TextCanvas createDescriptionPanel(final Point3D location, final String text) { + final Transform transform = Transform.fromAngles( + point(location.x, location.y + 220, location.z), + 0, 0); + + final TextCanvas panel = new TextCanvas( + transform, + new TextPointer(5, 35), + Color.WHITE, + new Color(0, 0, 40, 180)); + + panel.setText(text); + return panel; } /** @@ -219,16 +197,16 @@ public class CSGDemo { private static void createLights(final ViewPanel viewPanel, final ShapeCollection shapes) { // Main light from above-front final LightSource mainLight = new LightSource( - new Point3D(0, -300, -400), - new Color(255, 255, 255), + point(0, -300, -400), + hex("FFFFFF"), 1.5 ); viewPanel.getLightingManager().addLight(mainLight); // Fill light from the side final LightSource fillLight = new LightSource( - new Point3D(500, 100, -200), - new Color(150, 150, 200), + point(500, 100, -200), + hex("9696C8"), 0.8 ); viewPanel.getLightingManager().addLight(fillLight); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/CoordinateSystemDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/CoordinateSystemDemo.java new file mode 100644 index 0000000..dafd300 --- /dev/null +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/CoordinateSystemDemo.java @@ -0,0 +1,152 @@ +/* + * Sixth 3D engine demos. Author: Svjatoslav Agejenko. + * This project is released under Creative Commons Zero (CC0) license. + */ +package eu.svjatoslav.sixth.e3d.examples.essentials; + +import eu.svjatoslav.sixth.e3d.geometry.Point3D; +import eu.svjatoslav.sixth.e3d.gui.ViewFrame; +import eu.svjatoslav.sixth.e3d.gui.ViewPanel; +import eu.svjatoslav.sixth.e3d.renderer.raster.Color; +import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; +import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance; +import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.ForwardOrientedTextBlock; +import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonArrow; +import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.Grid3D; + +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.origin; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; + +/** + * Demo displaying coordinate system axes using 3D arrows. + * + *

    This demo illustrates the Sixth 3D coordinate system with three colored + * arrows originating from the origin (0,0,0), each pointing along a positive + * axis direction:

    + * + * + * + *

    A reference grid at Y=0 provides spatial context. Text labels identify + * each axis.

    + * + * @see SolidPolygonArrow + * @see ForwardOrientedTextBlock + */ +public class CoordinateSystemDemo { + + /** + * Length of each axis arrow. + */ + private static final double ARROW_LENGTH = 200; + + /** + * Radius of the arrow body (cylindrical shaft). + */ + private static final double BODY_RADIUS = 6; + + /** + * Distance from arrow tip to text label position. + */ + private static final double LABEL_OFFSET = 20; + + /** + * Scale factor for text labels. + */ + private static final double LABEL_SCALE = 20.0; + + /** + * Entry point for the coordinate system demo. + * + * @param args command line arguments (ignored) + */ + public static void main(final String[] args) { + final ViewFrame viewFrame = new ViewFrame("Coordinate System Demo"); + final ViewPanel viewPanel = viewFrame.getViewPanel(); + final ShapeCollection shapes = viewPanel.getRootShapeCollection(); + + // Position camera to view all three axes + viewPanel.getCamera().getTransform().set(130.66, -65.49, -248.18, -0.06, -0.36, -0.00); + + // Create reference grid at Y=0 plane + createReferenceGrid(shapes); + + // Create axis arrows + createAxisArrows(shapes); + + viewPanel.repaintDuringNextViewUpdate(); + } + + /** + * Creates a reference grid on the Y=0 plane. + * + * @param shapes the shape collection to add the grid to + */ + private static void createReferenceGrid(final ShapeCollection shapes) { + final LineAppearance gridAppearance = new LineAppearance( + 1, hex("505064FF")); + final Grid3D grid = new Grid3D( + point(-300, 0, -300), + point(300, 0, 300), + 50, + gridAppearance + ); + shapes.addShape(grid); + } + + /** + * Creates the three axis arrows and their labels. + * + * @param shapes the shape collection to add the arrows to + */ + private static void createAxisArrows(final ShapeCollection shapes) { + // X-axis arrow (RED) - points in positive X direction (RIGHT) + final SolidPolygonArrow xArrow = new SolidPolygonArrow( + origin(), + point(ARROW_LENGTH, 0, 0), + BODY_RADIUS, hex("FF0000B4") + ); + shapes.addShape(xArrow); + createLabel(shapes, "X", point(ARROW_LENGTH + LABEL_OFFSET, 0, 0), Color.RED); + + // Y-axis arrow (GREEN) - points in positive Y direction (DOWN) + final SolidPolygonArrow yArrow = new SolidPolygonArrow( + origin(), + point(0, ARROW_LENGTH, 0), + BODY_RADIUS, hex("00FF00B4") + ); + shapes.addShape(yArrow); + createLabel(shapes, "Y", point(0, ARROW_LENGTH + LABEL_OFFSET, 0), Color.GREEN); + + // Z-axis arrow (BLUE) - points in positive Z direction (AWAY) + final SolidPolygonArrow zArrow = new SolidPolygonArrow( + origin(), + point(0, 0, ARROW_LENGTH), + BODY_RADIUS, hex("0000FFB4") + ); + shapes.addShape(zArrow); + createLabel(shapes, "Z", point(0, 0, ARROW_LENGTH + LABEL_OFFSET), Color.BLUE); + } + + /** + * Creates a text label at the specified position. + * + * @param shapes the shape collection to add the label to + * @param text the label text + * @param position the 3D position of the label + * @param color the text color + */ + private static void createLabel(final ShapeCollection shapes, + final String text, + final Point3D position, + final Color color) { + final ForwardOrientedTextBlock label = new ForwardOrientedTextBlock( + position, LABEL_SCALE, 2, text, color + ); + shapes.addShape(label); + } +} \ No newline at end of file diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/MinimalExample.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/MinimalExample.java index b526eb3..aa4347c 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/MinimalExample.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/MinimalExample.java @@ -5,13 +5,14 @@ */ package eu.svjatoslav.sixth.e3d.examples.essentials; -import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.gui.ViewFrame; import eu.svjatoslav.sixth.e3d.math.Transform; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid.SolidPolygonRectangularBox; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; + /** * Minimal example demonstrating how to create a basic 3D scene. *

    @@ -29,12 +30,12 @@ public class MinimalExample { ViewFrame viewFrame = new ViewFrame("Minimal example"); ShapeCollection shapes = viewFrame.getViewPanel().getRootShapeCollection(); - viewFrame.getViewPanel().getCamera().getTransform().setTranslation(new Point3D(0, -100, -300)); + viewFrame.getViewPanel().getCamera().getTransform().setTranslation(point(0, -100, -300)); - Transform boxTransform = Transform.fromAngles(0, 0, 0, 0, 0, 0); + final Transform boxTransform = new Transform(); SolidPolygonRectangularBox box = new SolidPolygonRectangularBox( - new Point3D(-50, -50, -50), - new Point3D(50, 50, 50), + point(-50, -50, -50), + point(50, 50, 50), Color.RED ); box.setTransform(boxTransform); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/ShapeGalleryDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/ShapeGalleryDemo.java index 28e6337..9efa14b 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/ShapeGalleryDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/ShapeGalleryDemo.java @@ -17,7 +17,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; import static eu.svjatoslav.sixth.e3d.math.Transform.fromAngles; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; /** * Gallery demo showcasing all available 3D shapes in the Sixth 3D engine. @@ -69,13 +71,13 @@ public class ShapeGalleryDemo { * Color palette - one color per column (shape type). */ private static final Color[] SHAPE_COLORS = { - new Color(255, 100, 100), // Arrow - Red - new Color(255, 180, 100), // Cone - Orange - new Color(255, 255, 100), // Cube - Yellow - new Color(100, 255, 100), // Cylinder - Green - new Color(100, 255, 255), // Pyramid - Cyan - new Color(100, 150, 255), // RectangularBox - Blue - new Color(200, 150, 255), // Sphere - Purple + hex("FF6464FF"), // Arrow - Red + hex("FFB464FF"), // Cone - Orange + hex("FFFF64FF"), // Cube - Yellow + hex("64FF64FF"), // Cylinder - Green + hex("64FFFFFF"), // Pyramid - Cyan + hex("6496FFFF"), // RectangularBox - Blue + hex("C896FFFF"), // Sphere - Purple }; /** @@ -105,7 +107,7 @@ public class ShapeGalleryDemo { viewPanel.getCamera().getTransform().set(-615.31, -299.50, -378.64, -0.62, -0.66, 0.00); // Set up lighting - viewPanel.getLightingManager().setAmbientLight(new Color(40, 40, 50)); + viewPanel.getLightingManager().setAmbientLight(hex("282832FF")); // Create floor grid createFloorGrid(shapes); @@ -125,14 +127,14 @@ public class ShapeGalleryDemo { * @param shapes the shape collection to add the grid to */ private static void createFloorGrid(final ShapeCollection shapes) { - final LineAppearance gridAppearance = new LineAppearance(1, new Color(80, 80, 100)); + final LineAppearance gridAppearance = new LineAppearance(1, hex("505064FF")); // Calculate grid bounds: 7 columns, 2 rows, centered around origin final double halfWidth = (COLUMN_COUNT * CELL_SIZE) / 2.0; final double gridDepth = 2 * CELL_SIZE; - final Point3D cornerA = new Point3D(-halfWidth, 0, -CELL_SIZE / 2); - final Point3D cornerB = new Point3D(halfWidth, 0, gridDepth - CELL_SIZE / 2); + final Point3D cornerA = point(-halfWidth, 0, -CELL_SIZE / 2); + final Point3D cornerB = point(halfWidth, 0, gridDepth - CELL_SIZE / 2); final Grid3D grid = new Grid3D(cornerA, cornerB, CELL_SIZE, gridAppearance); shapes.addShape(grid); @@ -150,12 +152,12 @@ public class ShapeGalleryDemo { final String name = SHAPE_NAMES[col]; // Row 0: Solid polygon shapes - final Point3D solidPos = new Point3D(x, 0, 0); + final Point3D solidPos = point(x, 0, 0); createSolidShape(shapes, col, solidPos, color); createLabel(shapes, solidPos, name, color); // Row 1: Wireframe shapes - final Point3D wireframePos = new Point3D(x, 0, CELL_SIZE); + final Point3D wireframePos = point(x, 0, CELL_SIZE); createWireframeShape(shapes, col, wireframePos, color); createLabel(shapes, wireframePos, "Wireframe " + name, color); } @@ -184,8 +186,8 @@ public class ShapeGalleryDemo { switch (col) { case 0: // Arrow final SolidPolygonArrow arrow = new SolidPolygonArrow( - new Point3D(pos.x, SHAPE_RADIUS, pos.z), - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), + point(pos.x, SHAPE_RADIUS, pos.z), + point(pos.x, -SHAPE_RADIUS, pos.z), 8, color); arrow.setShadingEnabled(true); shapes.addShape(arrow); @@ -193,8 +195,8 @@ public class ShapeGalleryDemo { case 1: // Cone (pointing upward) final SolidPolygonCone cone = new SolidPolygonCone( - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), // apex above - new Point3D(pos.x, SHAPE_RADIUS / 2, pos.z), // base below + point(pos.x, -SHAPE_RADIUS, pos.z), // apex above + point(pos.x, SHAPE_RADIUS / 2, pos.z), // base below SHAPE_RADIUS * 0.8, SEGMENTS, color); cone.setShadingEnabled(true); shapes.addShape(cone); @@ -208,8 +210,8 @@ public class ShapeGalleryDemo { case 3: // Cylinder final SolidPolygonCylinder cylinder = new SolidPolygonCylinder( - new Point3D(pos.x, SHAPE_RADIUS, pos.z), - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), + point(pos.x, SHAPE_RADIUS, pos.z), + point(pos.x, -SHAPE_RADIUS, pos.z), SHAPE_RADIUS * 0.7, SEGMENTS, color); cylinder.setShadingEnabled(true); shapes.addShape(cylinder); @@ -217,8 +219,8 @@ public class ShapeGalleryDemo { case 4: // Pyramid final SolidPolygonPyramid pyramid = new SolidPolygonPyramid( - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), // apex above - new Point3D(pos.x, SHAPE_RADIUS / 2, pos.z), // base below + point(pos.x, -SHAPE_RADIUS, pos.z), // apex above + point(pos.x, SHAPE_RADIUS / 2, pos.z), // base below SHAPE_RADIUS * 0.8, color); pyramid.setShadingEnabled(true); shapes.addShape(pyramid); @@ -226,8 +228,8 @@ public class ShapeGalleryDemo { case 5: // RectangularBox final SolidPolygonRectangularBox box = new SolidPolygonRectangularBox( - new Point3D(pos.x - SHAPE_RADIUS * 0.35, pos.y - SHAPE_RADIUS, pos.z - SHAPE_RADIUS * 0.35), - new Point3D(pos.x + SHAPE_RADIUS * 0.35, pos.y + SHAPE_RADIUS, pos.z + SHAPE_RADIUS * 0.35), + point(pos.x - SHAPE_RADIUS * 0.35, pos.y - SHAPE_RADIUS, pos.z - SHAPE_RADIUS * 0.35), + point(pos.x + SHAPE_RADIUS * 0.35, pos.y + SHAPE_RADIUS, pos.z + SHAPE_RADIUS * 0.35), color); box.setShadingEnabled(true); shapes.addShape(box); @@ -259,16 +261,16 @@ public class ShapeGalleryDemo { switch (col) { case 0: // Arrow final WireframeArrow arrow = new WireframeArrow( - new Point3D(pos.x, SHAPE_RADIUS, pos.z), - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), + point(pos.x, SHAPE_RADIUS, pos.z), + point(pos.x, -SHAPE_RADIUS, pos.z), 8, appearance); shapes.addShape(arrow); break; case 1: // Cone final WireframeCone cone = new WireframeCone( - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), // apex above - new Point3D(pos.x, SHAPE_RADIUS / 2, pos.z), // base below + point(pos.x, -SHAPE_RADIUS, pos.z), // apex above + point(pos.x, SHAPE_RADIUS / 2, pos.z), // base below SHAPE_RADIUS * 0.8, SEGMENTS, appearance); shapes.addShape(cone); break; @@ -280,24 +282,24 @@ public class ShapeGalleryDemo { case 3: // Cylinder final WireframeCylinder cylinder = new WireframeCylinder( - new Point3D(pos.x, SHAPE_RADIUS, pos.z), - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), + point(pos.x, SHAPE_RADIUS, pos.z), + point(pos.x, -SHAPE_RADIUS, pos.z), SHAPE_RADIUS * 0.7, SEGMENTS, appearance); shapes.addShape(cylinder); break; case 4: // Pyramid final WireframePyramid pyramid = new WireframePyramid( - new Point3D(pos.x, -SHAPE_RADIUS, pos.z), // apex above - new Point3D(pos.x, SHAPE_RADIUS / 2, pos.z), // base below + point(pos.x, -SHAPE_RADIUS, pos.z), // apex above + point(pos.x, SHAPE_RADIUS / 2, pos.z), // base below SHAPE_RADIUS * 0.8, appearance); shapes.addShape(pyramid); break; case 5: // Box (WireframeBox) final WireframeBox box = new WireframeBox( - new Point3D(pos.x - SHAPE_RADIUS * 0.35, pos.y - SHAPE_RADIUS, pos.z - SHAPE_RADIUS * 0.35), - new Point3D(pos.x + SHAPE_RADIUS * 0.35, pos.y + SHAPE_RADIUS, pos.z + SHAPE_RADIUS * 0.35), + point(pos.x - SHAPE_RADIUS * 0.35, pos.y - SHAPE_RADIUS, pos.z - SHAPE_RADIUS * 0.35), + point(pos.x + SHAPE_RADIUS * 0.35, pos.y + SHAPE_RADIUS, pos.z + SHAPE_RADIUS * 0.35), appearance); shapes.addShape(box); break; @@ -322,7 +324,7 @@ public class ShapeGalleryDemo { */ private static void createLabel(final ShapeCollection shapes, final Point3D pos, final String text, final Color color) { - final Point3D labelPos = new Point3D(pos.x, pos.y + LABEL_Y_OFFSET, pos.z); + final Point3D labelPos = point(pos.x, pos.y + LABEL_Y_OFFSET, pos.z); final ForwardOrientedTextBlock label = new ForwardOrientedTextBlock( labelPos, 8.0, 2, text, color); shapes.addShape(label); @@ -353,7 +355,7 @@ public class ShapeGalleryDemo { final int axis = random.nextInt(3); final double ellipseFactor = 0.7 + random.nextDouble() * 0.3; - final LightSource light = new LightSource(new Point3D(0, 0, CELL_SIZE / 2), color, intensity); + final LightSource light = new LightSource(point(0, 0, CELL_SIZE / 2), color, intensity); final LightSourceMarker marker = new LightSourceMarker(light.getPosition(), color); viewPanel.getLightingManager().addLight(light); @@ -428,7 +430,7 @@ public class ShapeGalleryDemo { break; } - final Point3D newPosition = new Point3D(x, y + centerY, z); + final Point3D newPosition = point(x, y + centerY, z); orbitingLight.light.setPosition(newPosition); orbitingLight.marker.setTransform(fromAngles( newPosition.x, newPosition.y, newPosition.z, 0, 0, 0)); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/WindingOrderDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/WindingOrderDemo.java index 250fc62..fceba7b 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/WindingOrderDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/essentials/WindingOrderDemo.java @@ -12,6 +12,8 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.Color; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon.SolidPolygon; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; + /** * Demo to test winding order and backface culling documentation. *

    @@ -36,17 +38,17 @@ public class WindingOrderDemo { * @param args command line arguments (ignored) */ public static void main(String[] args) { - ViewFrame viewFrame = new ViewFrame("Winding Order Demo"); + ViewFrame viewFrame = new ViewFrame("Winding order demo"); ViewPanel viewPanel = viewFrame.getViewPanel(); ShapeCollection shapes = viewPanel.getRootShapeCollection(); - viewPanel.getCamera().getTransform().setTranslation(new Point3D(0, 0, -500)); + viewPanel.getCamera().getTransform().setTranslation(point(0, 0, -500)); double size = 150; - Point3D upperCenter = new Point3D(0, -size, 0); - Point3D lowerLeft = new Point3D(-size, +size, 0); - Point3D lowerRight = new Point3D(+size, +size, 0); + Point3D upperCenter = point(0, -size, 0); + Point3D lowerLeft = point(-size, +size, 0); + Point3D lowerRight = point(+size, +size, 0); SolidPolygon triangle = new SolidPolygon(upperCenter, lowerLeft, lowerRight, Color.GREEN); triangle.setBackfaceCulling(true); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/MathGraphsDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/MathGraphsDemo.java index 1f28002..508fb7c 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/MathGraphsDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/MathGraphsDemo.java @@ -10,6 +10,9 @@ import eu.svjatoslav.sixth.e3d.geometry.Point2D; import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.gui.ViewFrame; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; + +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.origin; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.Graph; @@ -163,22 +166,22 @@ public class MathGraphsDemo { */ private static void addMathFormulas(ShapeCollection geometryCollection) { int z = 1000; - Point3D location = new Point3D(-600, -300, z); + Point3D location = point(-600, -300, z); geometryCollection.addShape(getSineGraph(location)); - location = new Point3D(600, -300, z); + location = point(600, -300, z); geometryCollection.addShape(getFormula1Graph(location)); - location = new Point3D(-600, 0, z); + location = point(-600, 0, z); geometryCollection.addShape(getCosineGraph(location)); - location = new Point3D(600, 0, z); + location = point(600, 0, z); geometryCollection.addShape(getFormula2Graph(location)); - location = new Point3D(-600, 300, z); + location = point(-600, 300, z); geometryCollection.addShape(getTangentGraph(location)); - location = new Point3D(600, 300, z); + location = point(600, 300, z); geometryCollection.addShape(getFormula3Graph(location)); } @@ -196,7 +199,7 @@ public class MathGraphsDemo { new Color(150, 150, 150, 180), Color.WHITE, scale, - new Point3D(0, 0, 0) + origin() ); surface.addYIntersectionCurve(4, function, new Color(255, 255, 0, 220), 1.2); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/SurfaceGraph3D.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/SurfaceGraph3D.java index 661a854..c4507d3 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/SurfaceGraph3D.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/graph_demo/SurfaceGraph3D.java @@ -122,13 +122,9 @@ public class SurfaceGraph3D extends AbstractCompositeShape { } private void addQuad(final Point3D p1, final Point3D p2, final Point3D p3, final Point3D p4) { - final SolidPolygon poly1 = new SolidPolygon(p1, p2, p3, surfaceColor); - poly1.setBackfaceCulling(false); - addShape(poly1); - - final SolidPolygon poly2 = new SolidPolygon(p2, p4, p3, surfaceColor); - poly2.setBackfaceCulling(false); - addShape(poly2); + final SolidPolygon quad = SolidPolygon.quad(p1, p2, p4, p3, surfaceColor); + quad.setBackfaceCulling(false); + addShape(quad); } private void addGridLines(final Point3D p1, final Point3D p2, final Point3D p3, final Point3D p4) { diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java index 86cda8a..550e60d 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java @@ -11,7 +11,7 @@ import eu.svjatoslav.sixth.e3d.examples.RainingNumbersDemo; import eu.svjatoslav.sixth.e3d.examples.SineHeightmap; import eu.svjatoslav.sixth.e3d.examples.TextEditorDemo; import eu.svjatoslav.sixth.e3d.examples.TextEditorDemo2; -import eu.svjatoslav.sixth.e3d.examples.essentials.AxisArrowsDemo; +import eu.svjatoslav.sixth.e3d.examples.essentials.CoordinateSystemDemo; import eu.svjatoslav.sixth.e3d.examples.essentials.CSGDemo; import eu.svjatoslav.sixth.e3d.examples.essentials.MinimalExample; import eu.svjatoslav.sixth.e3d.examples.essentials.ShapeGalleryDemo; @@ -44,13 +44,13 @@ class ApplicationListPanel extends JPanel { new DemoEntry("Winding order", "Triangle demo for winding order & backface culling", new ShowWindingOrder()), - new DemoEntry("Axis arrows", + new DemoEntry("Coordinate system", "Coordinate system axes: X (red), Y (green), Z (blue)", - new ShowAxisArrows()), + new ShowCoordinateSystem()), new DemoEntry("Shape gallery", "All 3D shapes with orbiting colored light sources", new ShowShadedShapes()), - new DemoEntry("CSG Demo", + new DemoEntry("CSG demo", "Boolean operations: union, subtract, intersect on 3D shapes", new ShowCSG()), }; @@ -174,7 +174,7 @@ class ApplicationListPanel extends JPanel { private static class ShowMinimalExample extends AbstractAction { ShowMinimalExample() { - putValue(NAME, "Minimal Example"); + putValue(NAME, "Minimal example"); } @Override @@ -185,7 +185,7 @@ class ApplicationListPanel extends JPanel { private static class ShowWindingOrder extends AbstractAction { ShowWindingOrder() { - putValue(NAME, "Winding Order"); + putValue(NAME, "Winding order"); } @Override @@ -293,14 +293,14 @@ class ApplicationListPanel extends JPanel { } } - private static class ShowAxisArrows extends AbstractAction { - ShowAxisArrows() { - putValue(NAME, "Axis arrows"); + private static class ShowCoordinateSystem extends AbstractAction { + ShowCoordinateSystem() { + putValue(NAME, "Coordinate system"); } @Override public void actionPerformed(final ActionEvent e) { - AxisArrowsDemo.main(null); + CoordinateSystemDemo.main(null); } } @@ -328,7 +328,7 @@ class ApplicationListPanel extends JPanel { private static class ShowCSG extends AbstractAction { ShowCSG() { - putValue(NAME, "CSG Demo"); + putValue(NAME, "CSG demo"); } @Override diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Cell.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Cell.java index 80622ff..c9be293 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Cell.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Cell.java @@ -15,14 +15,16 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCom class Cell extends AbstractCompositeShape implements MouseInteractionController { - /** Visual size of each cell in world units. */ + /** + * Visual size of each cell in world units. + */ static final int SIZE = 20; /** * Color of the active cell (R, G, B, A) */ private static final Color ACTIVE_COLOR = new Color("A8FF"); /** - * Color of the active cell (R, G, B, A) while mouse is over it. + * Color of the active cell (R, G, B, A) while the mouse is over it. */ private static final Color ACTIVE_COLOR_MOUSE_OVER = new Color("F9FF"); /** @@ -49,6 +51,7 @@ class Cell extends AbstractCompositeShape implements /** * Constructs a cell at the specified center position. + * * @param center the 3D position of the cell center */ public Cell(final Point3D center) { @@ -60,7 +63,9 @@ class Cell extends AbstractCompositeShape implements setMouseInteractionController(this); } - /** Creates the visual representation of the cell as two triangles. */ + /** + * Creates the visual representation of the cell as two triangles. + */ private void createCellShape() { final double halfSize = SIZE / 2f; @@ -80,6 +85,7 @@ class Cell extends AbstractCompositeShape implements /** * Computes the cell color based on active state and mouse hover. + * * @return the appropriate color for the current state */ private Color computeCellColor() { @@ -96,6 +102,7 @@ class Cell extends AbstractCompositeShape implements /** * Returns whether this cell is currently active (alive). + * * @return true if the cell is active */ public boolean isActive() { @@ -104,6 +111,7 @@ class Cell extends AbstractCompositeShape implements /** * Sets the active state of this cell and updates its color. + * * @param active true to make the cell active, false for inactive */ public void setActive(final boolean active) { @@ -113,6 +121,7 @@ class Cell extends AbstractCompositeShape implements /** * Handles mouse click by toggling the cell state. + * * @param button the mouse button that was clicked * @return true to indicate the event was consumed */ @@ -124,6 +133,7 @@ class Cell extends AbstractCompositeShape implements /** * Handles mouse entering the cell area by highlighting it. + * * @return true to indicate the event was consumed */ @Override @@ -134,6 +144,7 @@ class Cell extends AbstractCompositeShape implements /** * Handles mouse exiting the cell area by removing highlight. + * * @return true to indicate the event was consumed */ @Override @@ -144,6 +155,7 @@ class Cell extends AbstractCompositeShape implements /** * Sets the mouse-over state and updates the cell color. + * * @param isMouseOver true if mouse is over the cell */ private void setMouseOver(final boolean isMouseOver) { @@ -151,7 +163,9 @@ class Cell extends AbstractCompositeShape implements updateColor(); } - /** Updates the cell's visual color to match its current state. */ + /** + * Updates the cell's visual color to match its current state. + */ private void updateColor() { setColor(computeCellColor()); } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Main.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Main.java index 0e77299..d60dad7 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Main.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/life_demo/Main.java @@ -8,6 +8,10 @@ import eu.svjatoslav.sixth.e3d.gui.ViewPanel; import eu.svjatoslav.sixth.e3d.gui.humaninput.WorldNavigationUserInputTracker; import eu.svjatoslav.sixth.e3d.math.Transform; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; + +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.origin; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance; import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas.TextCanvas; @@ -34,7 +38,7 @@ public class Main extends WorldNavigationUserInputTracker { * The game of life matrix, centered at the origin. */ private static final Matrix MATRIX = new Matrix( - new Point3D() // position matrix in the center of the scene + origin() // position matrix in the center of the scene ); /** @@ -116,7 +120,7 @@ public class Main extends WorldNavigationUserInputTracker { 5, 5, new LineAppearance(3, - new Color("FF000050") + hex("FF000050") ) ); } @@ -147,7 +151,7 @@ public class Main extends WorldNavigationUserInputTracker { "Hover - Highlight cell"; final Transform location = Transform.fromAngles( - new Point3D(500, -80, 0), + point(500, -80, 0), -Math.PI / 2, 0 ); @@ -158,7 +162,7 @@ public class Main extends WorldNavigationUserInputTracker { location, dimensions, Color.WHITE, - new Color(0, 0, 80, 200) + hex("000050C8") ); panel.setText(helpText); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/terrain_demo/TerrainDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/terrain_demo/TerrainDemo.java index 1ad9d43..1bf03ec 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/terrain_demo/TerrainDemo.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/terrain_demo/TerrainDemo.java @@ -9,6 +9,10 @@ import eu.svjatoslav.sixth.e3d.geometry.Point3D; import eu.svjatoslav.sixth.e3d.gui.ViewFrame; import eu.svjatoslav.sixth.e3d.gui.ViewPanel; import eu.svjatoslav.sixth.e3d.renderer.raster.Color; + +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.origin; +import static eu.svjatoslav.sixth.e3d.geometry.Point3D.point; +import static eu.svjatoslav.sixth.e3d.renderer.raster.Color.hex; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; import eu.svjatoslav.sixth.e3d.renderer.raster.lighting.LightSource; import eu.svjatoslav.sixth.e3d.renderer.raster.lighting.LightingManager; @@ -41,7 +45,7 @@ public class TerrainDemo { // Get terrain height at center and place tree trunk on it final double terrainHeight = terrain.getHeightAt(0, 0); - shapes.addShape(new FractalTree(new Point3D(0, terrainHeight, 0), 30, 6)); + shapes.addShape(new FractalTree(point(0, terrainHeight, 0), 30, 6)); viewPanel.repaintDuringNextViewUpdate(); } @@ -54,21 +58,21 @@ public class TerrainDemo { */ private static void setLights(ViewFrame viewFrame, ShapeCollection shapes) { LightingManager lightingManager = viewFrame.getViewPanel().getLightingManager(); - lightingManager.setAmbientLight(new Color(250, 150, 100)); + lightingManager.setAmbientLight(hex("FA9664FF")); final LightSource warmLight = new LightSource( - new Point3D(-400, -500, 0), - new Color(255, 180, 100), + point(-400, -500, 0), + hex("FFB464FF"), 190.0 ); final LightSource coolLight = new LightSource( - new Point3D(400, -500, 0), - new Color(100, 200, 255), + point(400, -500, 0), + hex("64C8FFFF"), 220.0 ); final LightSource neutralLight = new LightSource( - new Point3D(0, -600, 300), - new Color(255, 255, 255), + point(0, -600, 300), + hex("FFFFFFFF"), 250.0 ); @@ -76,8 +80,8 @@ public class TerrainDemo { lightingManager.addLight(coolLight); lightingManager.addLight(neutralLight); - shapes.addShape(new LightSourceMarker(warmLight.getPosition(), new Color(255, 180, 100))); - shapes.addShape(new LightSourceMarker(coolLight.getPosition(), new Color(100, 200, 255))); - shapes.addShape(new LightSourceMarker(neutralLight.getPosition(), new Color(255, 255, 255))); + shapes.addShape(new LightSourceMarker(warmLight.getPosition(), hex("FFB464FF"))); + shapes.addShape(new LightSourceMarker(coolLight.getPosition(), hex("64C8FFFF"))); + shapes.addShape(new LightSourceMarker(neutralLight.getPosition(), hex("FFFFFFFF"))); } } \ No newline at end of file