Updated readability of the code.
[sixth-3d.git] / src / main / java / eu / svjatoslav / sixth / e3d / renderer / octree / OctreeVolume.java
index 9bcbc23..e1b7269 100755 (executable)
@@ -1,12 +1,10 @@
 /*
  * Sixth 3D engine. Author: Svjatoslav Agejenko. 
  * This project is released under Creative Commons Zero (CC0) license.
- *
-*
  */
-
 package eu.svjatoslav.sixth.e3d.renderer.octree;
 
+import eu.svjatoslav.sixth.e3d.geometry.Point3D;
 import eu.svjatoslav.sixth.e3d.renderer.octree.raytracer.Ray;
 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance;
@@ -29,21 +27,23 @@ import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance;
 
 public class OctreeVolume {
 
+    // cell is not hit by the ray
     public static final int TRACE_NO_HIT = -1;
-    /**
-     * Single solid color.
-     */
+
+    // solid cell (contains color and illumination)
     private static final int CELL_STATE_SOLID = -2;
+
+    // unused cell
     private static final int CELL_STATE_UNUSED = -1;
-    final LineAppearance factory = new LineAppearance();
-    public int ce1[];
-    public int ce2[];
-    public int ce3[];
-    public int ce4[];
-    public int ce5[];
-    public int ce6[];
-    public int ce7[];
-    public int ce8[];
+
+    public int[] ce1;
+    public int[] ce2;
+    public int[] ce3;
+    public int[] ce4;
+    public int[] ce5;
+    public int[] ce6;
+    public int[] ce7;
+    public int[] ce8;
     public int cellAllocationPointer = 0;
     public int usedCellsCount = 0;
     public int masterCellSize;
@@ -88,120 +88,112 @@ public class OctreeVolume {
                              final int cubeSize, final Ray r) {
 
         // ray starts inside the cube
-        if ((cubeX - cubeSize) < r.x)
-            if ((cubeX + cubeSize) > r.x)
-                if ((cubeY - cubeSize) < r.y)
-                    if ((cubeY + cubeSize) > r.y)
-                        if ((cubeZ - cubeSize) < r.z)
-                            if ((cubeZ + cubeSize) > r.z) {
-                                r.hitX = r.x;
-                                r.hitY = r.y;
-                                r.hitZ = r.z;
+        if ((cubeX - cubeSize) < r.origin.x)
+            if ((cubeX + cubeSize) > r.origin.x)
+                if ((cubeY - cubeSize) < r.origin.y)
+                    if ((cubeY + cubeSize) > r.origin.y)
+                        if ((cubeZ - cubeSize) < r.origin.z)
+                            if ((cubeZ + cubeSize) > r.origin.z) {
+                                r.hitPoint = r.origin.clone();
                                 return 1;
                             }
         // back face
-        if (r.zp > 0)
-            if ((cubeZ - cubeSize) > r.z) {
-                final double mult = ((cubeZ - cubeSize) - r.z) / r.zp;
-                final double hitX = (r.xp * mult) + r.x;
+        if (r.direction.z > 0)
+            if ((cubeZ - cubeSize) > r.origin.z) {
+                final double mult = ((cubeZ - cubeSize) - r.origin.z) / r.direction.z;
+                final double hitX = (r.direction.x * mult) + r.origin.x;
                 if ((cubeX - cubeSize) < hitX)
                     if ((cubeX + cubeSize) > hitX) {
-                        final double hitY = (r.yp * mult) + r.y;
+                        final double hitY = (r.direction.y * mult) + r.origin.y;
                         if ((cubeY - cubeSize) < hitY)
                             if ((cubeY + cubeSize) > hitY) {
-                                r.hitX = hitX;
-                                r.hitY = hitY;
-                                r.hitZ = cubeZ - cubeSize;
+                                r.hitPoint = new Point3D(hitX, hitY, cubeZ
+                                        - cubeSize);
                                 return 2;
                             }
                     }
             }
 
         // up face
-        if (r.yp > 0)
-            if ((cubeY - cubeSize) > r.y) {
-                final double mult = ((cubeY - cubeSize) - r.y) / r.yp;
-                final double hitX = (r.xp * mult) + r.x;
+        if (r.direction.y > 0)
+            if ((cubeY - cubeSize) > r.origin.y) {
+                final double mult = ((cubeY - cubeSize) - r.origin.y) / r.direction.y;
+                final double hitX = (r.direction.x * mult) + r.origin.x;
                 if ((cubeX - cubeSize) < hitX)
                     if ((cubeX + cubeSize) > hitX) {
-                        final double hitZ = (r.zp * mult) + r.z;
+                        final double hitZ = (r.direction.z * mult) + r.origin.z;
                         if ((cubeZ - cubeSize) < hitZ)
                             if ((cubeZ + cubeSize) > hitZ) {
-                                r.hitX = hitX;
-                                r.hitY = cubeY - cubeSize;
-                                r.hitZ = hitZ;
+                                r.hitPoint = new Point3D(hitX, cubeY - cubeSize,
+                                        hitZ);
                                 return 3;
                             }
                     }
             }
 
         // left face
-        if (r.xp > 0)
-            if ((cubeX - cubeSize) > r.x) {
-                final double mult = ((cubeX - cubeSize) - r.x) / r.xp;
-                final double hitY = (r.yp * mult) + r.y;
+        if (r.direction.x > 0)
+            if ((cubeX - cubeSize) > r.origin.x) {
+                final double mult = ((cubeX - cubeSize) - r.origin.x) / r.direction.x;
+                final double hitY = (r.direction.y * mult) + r.origin.y;
                 if ((cubeY - cubeSize) < hitY)
                     if ((cubeY + cubeSize) > hitY) {
-                        final double hitZ = (r.zp * mult) + r.z;
+                        final double hitZ = (r.direction.z * mult) + r.origin.z;
                         if ((cubeZ - cubeSize) < hitZ)
                             if ((cubeZ + cubeSize) > hitZ) {
-                                r.hitX = cubeX - cubeSize;
-                                r.hitY = hitY;
-                                r.hitZ = hitZ;
+                                r.hitPoint = new Point3D(cubeX - cubeSize, hitY,
+                                        hitZ);
                                 return 4;
                             }
                     }
             }
 
         // front face
-        if (r.zp < 0)
-            if ((cubeZ + cubeSize) < r.z) {
-                final double mult = ((cubeZ + cubeSize) - r.z) / r.zp;
-                final double hitX = (r.xp * mult) + r.x;
+        if (r.direction.z < 0)
+            if ((cubeZ + cubeSize) < r.origin.z) {
+                final double mult = ((cubeZ + cubeSize) - r.origin.z) / r.direction.z;
+                final double hitX = (r.direction.x * mult) + r.origin.x;
                 if ((cubeX - cubeSize) < hitX)
                     if ((cubeX + cubeSize) > hitX) {
-                        final double hitY = (r.yp * mult) + r.y;
+                        final double hitY = (r.direction.y * mult) + r.origin.y;
                         if ((cubeY - cubeSize) < hitY)
                             if ((cubeY + cubeSize) > hitY) {
-                                r.hitX = hitX;
-                                r.hitY = hitY;
-                                r.hitZ = cubeZ + cubeSize;
+                                r.hitPoint = new Point3D(hitX, hitY, cubeZ
+                                        + cubeSize);
                                 return 5;
                             }
                     }
             }
 
         // down face
-        if (r.yp < 0)
-            if ((cubeY + cubeSize) < r.y) {
-                final double mult = ((cubeY + cubeSize) - r.y) / r.yp;
-                final double hitX = (r.xp * mult) + r.x;
+        if (r.direction.y < 0)
+            if ((cubeY + cubeSize) < r.origin.y) {
+                final double mult = ((cubeY + cubeSize) - r.origin.y) / r.direction.y;
+                final double hitX = (r.direction.x * mult) + r.origin.x;
                 if ((cubeX - cubeSize) < hitX)
                     if ((cubeX + cubeSize) > hitX) {
-                        final double hitZ = (r.zp * mult) + r.z;
+                        final double hitZ = (r.direction.z * mult) + r.origin.z;
                         if ((cubeZ - cubeSize) < hitZ)
                             if ((cubeZ + cubeSize) > hitZ) {
-                                r.hitX = hitX;
-                                r.hitY = cubeY + cubeSize;
-                                r.hitZ = hitZ;
+                                r.hitPoint = new Point3D(hitX, cubeY + cubeSize,
+                                        hitZ);
                                 return 6;
                             }
                     }
             }
 
         // right face
-        if (r.xp < 0)
-            if ((cubeX + cubeSize) < r.x) {
-                final double mult = ((cubeX + cubeSize) - r.x) / r.xp;
-                final double hitY = (r.yp * mult) + r.y;
+        if (r.direction.x < 0)
+            if ((cubeX + cubeSize) < r.origin.x) {
+                final double mult = ((cubeX + cubeSize) - r.origin.x) / r.direction.x;
+                final double hitY = (r.direction.y * mult) + r.origin.y;
                 if ((cubeY - cubeSize) < hitY)
                     if ((cubeY + cubeSize) > hitY) {
-                        final double hitZ = (r.zp * mult) + r.z;
+                        final double hitZ = (r.direction.z * mult) + r.origin.z;
                         if ((cubeZ - cubeSize) < hitZ)
                             if ((cubeZ + cubeSize) > hitZ) {
-                                r.hitX = cubeX + cubeSize;
-                                r.hitY = hitY;
-                                r.hitZ = hitZ;
+                                r.hitPoint = new Point3D(cubeX + cubeSize, hitY,
+                                        hitZ);
                                 return 7;
                             }
                     }
@@ -327,7 +319,7 @@ public class OctreeVolume {
             }
 
             // decide witch subcube to use
-            int subCubeArray[];
+            int[] subCubeArray;
             int subX, subY, subZ;
 
             if (x > cellX) {
@@ -409,8 +401,9 @@ public class OctreeVolume {
     }
 
     /**
-     * @return intersecting cell pointer or -1 if no cell in intersecting this
-     * ray.
+     * Trace ray through the world and return pointer to intersecting cell.
+     *
+     * @return pointer to intersecting cell or TRACE_NO_HIT if no intersection.
      */
     public int traceCell(final int cellX, final int cellY, final int cellZ,
                          final int cellSize, final int pointer, final Ray ray) {
@@ -429,9 +422,9 @@ public class OctreeVolume {
                 final int halfOfCellSize = cellSize / 2;
                 int rayIntersectionResult;
 
-                if (ray.x > cellX) {
-                    if (ray.y > cellY) {
-                        if (ray.z > cellZ) {
+                if (ray.origin.x > cellX) {
+                    if (ray.origin.y > cellY) {
+                        if (ray.origin.z > cellZ) {
                             // 7
                             // 6 8 3 5 2 4 1
 
@@ -576,7 +569,7 @@ public class OctreeVolume {
                             }
 
                         }
-                    } else if (ray.z > cellZ) {
+                    } else if (ray.origin.z > cellZ) {
                         // 6
                         // 5 2 7 8 1 3 4
                         if (ce6[pointer] != 0) {
@@ -718,8 +711,8 @@ public class OctreeVolume {
                         }
 
                     }
-                } else if (ray.y > cellY) {
-                    if (ray.z > cellZ) {
+                } else if (ray.origin.y > cellY) {
+                    if (ray.origin.z > cellZ) {
                         // 8
                         // 5 7 4 1 6 3 2
 
@@ -864,7 +857,7 @@ public class OctreeVolume {
                         }
 
                     }
-                } else if (ray.z > cellZ) {
+                } else if (ray.origin.z > cellZ) {
                     // 5
                     // 1 6 8 4 2 7 3