2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.sixth.e3d.renderer.octree;
7 import eu.svjatoslav.sixth.e3d.renderer.octree.raytracer.Ray;
8 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
9 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance;
13 * There are 3 cell types:
20 * visible color, after being illuminated by nearby light sources
23 * contains pointers to 8 sub cells
27 public class OctreeVolume {
29 public static final int TRACE_NO_HIT = -1;
33 private static final int CELL_STATE_SOLID = -2;
34 private static final int CELL_STATE_UNUSED = -1;
35 final LineAppearance factory = new LineAppearance();
44 public int cellAllocationPointer = 0;
45 public int usedCellsCount = 0;
46 public int masterCellSize;
48 public OctreeVolume() {
49 initWorld(1500000, 256 * 64);
52 public void breakSolidCell(final int pointer) {
53 final int color = getCellColor(pointer);
54 final int illumination = getCellIllumination(pointer);
56 ce1[pointer] = makeNewCell(color, illumination);
57 ce2[pointer] = makeNewCell(color, illumination);
58 ce3[pointer] = makeNewCell(color, illumination);
59 ce4[pointer] = makeNewCell(color, illumination);
60 ce5[pointer] = makeNewCell(color, illumination);
61 ce6[pointer] = makeNewCell(color, illumination);
62 ce7[pointer] = makeNewCell(color, illumination);
63 ce8[pointer] = makeNewCell(color, illumination);
66 public void clearCell(final int pointer) {
78 public void deleteCell(final int cellPointer) {
79 clearCell(cellPointer);
80 ce1[cellPointer] = CELL_STATE_UNUSED;
84 public int doesIntersect(final int cubeX, final int cubeY, final int cubeZ,
85 final int cubeSize, final Ray r) {
87 // ray starts inside the cube
88 if ((cubeX - cubeSize) < r.x)
89 if ((cubeX + cubeSize) > r.x)
90 if ((cubeY - cubeSize) < r.y)
91 if ((cubeY + cubeSize) > r.y)
92 if ((cubeZ - cubeSize) < r.z)
93 if ((cubeZ + cubeSize) > r.z) {
101 if ((cubeZ - cubeSize) > r.z) {
102 final double mult = ((cubeZ - cubeSize) - r.z) / r.zp;
103 final double hitX = (r.xp * mult) + r.x;
104 if ((cubeX - cubeSize) < hitX)
105 if ((cubeX + cubeSize) > hitX) {
106 final double hitY = (r.yp * mult) + r.y;
107 if ((cubeY - cubeSize) < hitY)
108 if ((cubeY + cubeSize) > hitY) {
111 r.hitZ = cubeZ - cubeSize;
119 if ((cubeY - cubeSize) > r.y) {
120 final double mult = ((cubeY - cubeSize) - r.y) / r.yp;
121 final double hitX = (r.xp * mult) + r.x;
122 if ((cubeX - cubeSize) < hitX)
123 if ((cubeX + cubeSize) > hitX) {
124 final double hitZ = (r.zp * mult) + r.z;
125 if ((cubeZ - cubeSize) < hitZ)
126 if ((cubeZ + cubeSize) > hitZ) {
128 r.hitY = cubeY - cubeSize;
137 if ((cubeX - cubeSize) > r.x) {
138 final double mult = ((cubeX - cubeSize) - r.x) / r.xp;
139 final double hitY = (r.yp * mult) + r.y;
140 if ((cubeY - cubeSize) < hitY)
141 if ((cubeY + cubeSize) > hitY) {
142 final double hitZ = (r.zp * mult) + r.z;
143 if ((cubeZ - cubeSize) < hitZ)
144 if ((cubeZ + cubeSize) > hitZ) {
145 r.hitX = cubeX - cubeSize;
155 if ((cubeZ + cubeSize) < r.z) {
156 final double mult = ((cubeZ + cubeSize) - r.z) / r.zp;
157 final double hitX = (r.xp * mult) + r.x;
158 if ((cubeX - cubeSize) < hitX)
159 if ((cubeX + cubeSize) > hitX) {
160 final double hitY = (r.yp * mult) + r.y;
161 if ((cubeY - cubeSize) < hitY)
162 if ((cubeY + cubeSize) > hitY) {
165 r.hitZ = cubeZ + cubeSize;
173 if ((cubeY + cubeSize) < r.y) {
174 final double mult = ((cubeY + cubeSize) - r.y) / r.yp;
175 final double hitX = (r.xp * mult) + r.x;
176 if ((cubeX - cubeSize) < hitX)
177 if ((cubeX + cubeSize) > hitX) {
178 final double hitZ = (r.zp * mult) + r.z;
179 if ((cubeZ - cubeSize) < hitZ)
180 if ((cubeZ + cubeSize) > hitZ) {
182 r.hitY = cubeY + cubeSize;
191 if ((cubeX + cubeSize) < r.x) {
192 final double mult = ((cubeX + cubeSize) - r.x) / r.xp;
193 final double hitY = (r.yp * mult) + r.y;
194 if ((cubeY - cubeSize) < hitY)
195 if ((cubeY + cubeSize) > hitY) {
196 final double hitZ = (r.zp * mult) + r.z;
197 if ((cubeZ - cubeSize) < hitZ)
198 if ((cubeZ + cubeSize) > hitZ) {
199 r.hitX = cubeX + cubeSize;
212 public void fillRect3D(int x1, int y1, int z1, int x2, int y2, int z2,
233 for (int x = x1; x <= x2; x++)
234 for (int y = y1; y <= y2; y++)
235 for (int z = z1; z <= z2; z++)
236 putCell(x, y, z, 0, 0, 0, masterCellSize, 0, color);
240 public int getCellColor(final int pointer) {
244 public int getCellIllumination(final int pointer) {
248 public void initWorld(final int bufferLength, final int masterCellSize) {
249 // System.out.println("Initializing new world");
251 // initialize world storage buffer
252 this.masterCellSize = masterCellSize;
254 ce1 = new int[bufferLength];
255 ce2 = new int[bufferLength];
256 ce3 = new int[bufferLength];
257 ce4 = new int[bufferLength];
259 ce5 = new int[bufferLength];
260 ce6 = new int[bufferLength];
261 ce7 = new int[bufferLength];
262 ce8 = new int[bufferLength];
264 for (int i = 0; i < bufferLength; i++)
265 ce1[i] = CELL_STATE_UNUSED;
267 // initialize master cell
271 public boolean isCellSolid(final int pointer) {
272 return ce1[pointer] == CELL_STATE_SOLID;
275 public int makeNewCell() {
277 if (cellAllocationPointer >= ce1.length)
278 cellAllocationPointer = 0;
280 if (ce1[cellAllocationPointer] == CELL_STATE_UNUSED) {
282 clearCell(cellAllocationPointer);
285 return cellAllocationPointer;
287 cellAllocationPointer++;
291 public int makeNewCell(final int color, final int illumination) {
292 final int pointer = makeNewCell();
293 markCellAsSolid(pointer);
294 setCellColor(pointer, color);
295 setCellIllumination(pointer, illumination);
299 public void markCellAsSolid(final int pointer) {
300 ce1[pointer] = CELL_STATE_SOLID;
303 public void putCell(final int x, final int y, final int z, final Color color) {
304 putCell(x, y, z, 0, 0, 0, masterCellSize, 0, color);
307 private void putCell(final int x, final int y, final int z,
308 final int cellX, final int cellY, final int cellZ,
309 final int cellSize, final int cellPointer, final Color color) {
313 // if case of big cell
314 if (isCellSolid(cellPointer)) {
316 // if cell is already a needed color, do notheing
317 if (getCellColor(cellPointer) == color.toInt())
320 // otherwise break cell up
321 breakSolidCell(cellPointer);
323 // continue, as if it is cluster now
326 // decide witch subcube to use
328 int subX, subY, subZ;
331 subX = (cellSize / 2) + cellX;
333 subY = (cellSize / 2) + cellY;
335 subZ = (cellSize / 2) + cellZ;
339 subZ = (-cellSize / 2) + cellZ;
344 subY = (-cellSize / 2) + cellY;
346 subZ = (cellSize / 2) + cellZ;
350 subZ = (-cellSize / 2) + cellZ;
356 subX = (-cellSize / 2) + cellX;
358 subY = (cellSize / 2) + cellY;
360 subZ = (cellSize / 2) + cellZ;
364 subZ = (-cellSize / 2) + cellZ;
369 subY = (-cellSize / 2) + cellY;
371 subZ = (cellSize / 2) + cellZ;
375 subZ = (-cellSize / 2) + cellZ;
383 if (subCubeArray[cellPointer] == 0) {
384 // create empty cluster
385 subCubePointer = makeNewCell();
386 subCubeArray[cellPointer] = subCubePointer;
388 subCubePointer = subCubeArray[cellPointer];
390 putCell(x, y, z, subX, subY, subZ, cellSize / 2, subCubePointer,
393 ce1[cellPointer] = CELL_STATE_SOLID;
394 ce2[cellPointer] = color.toInt();
395 ce3[cellPointer] = CELL_STATE_UNUSED;
396 // System.out.println("Cell written!");
400 public void setCellColor(final int pointer, final int color) {
401 ce2[pointer] = color;
404 public void setCellIllumination(final int pointer, final int illumination) {
405 ce3[pointer] = illumination;
409 * @return intersecting cell pointer or -1 if no cell in intersecting this
412 public int traceCell(final int cellX, final int cellY, final int cellZ,
413 final int cellSize, final int pointer, final Ray ray) {
414 if (isCellSolid(pointer)) {
416 if (doesIntersect(cellX, cellY, cellZ, cellSize, ray) != 0) {
417 ray.hitCellSize = cellSize;
418 ray.hitCellX = cellX;
419 ray.hitCellY = cellY;
420 ray.hitCellZ = cellZ;
425 if (doesIntersect(cellX, cellY, cellZ, cellSize, ray) != 0) {
426 final int halfOfCellSize = cellSize / 2;
427 int rayIntersectionResult;
435 if (ce7[pointer] != 0) {
436 rayIntersectionResult = traceCell(cellX
437 + halfOfCellSize, cellY + halfOfCellSize,
438 cellZ + halfOfCellSize, halfOfCellSize,
440 if (rayIntersectionResult >= 0)
441 return rayIntersectionResult;
443 if (ce6[pointer] != 0) {
444 rayIntersectionResult = traceCell(cellX
445 + halfOfCellSize, cellY - halfOfCellSize,
446 cellZ + halfOfCellSize, halfOfCellSize,
448 if (rayIntersectionResult >= 0)
449 return rayIntersectionResult;
451 if (ce8[pointer] != 0) {
452 rayIntersectionResult = traceCell(cellX
453 - halfOfCellSize, cellY + halfOfCellSize,
454 cellZ + halfOfCellSize, halfOfCellSize,
456 if (rayIntersectionResult >= 0)
457 return rayIntersectionResult;
459 if (ce3[pointer] != 0) {
460 rayIntersectionResult = traceCell(cellX
461 + halfOfCellSize, cellY + halfOfCellSize,
462 cellZ - halfOfCellSize, halfOfCellSize,
464 if (rayIntersectionResult >= 0)
465 return rayIntersectionResult;
468 if (ce2[pointer] != 0) {
469 rayIntersectionResult = traceCell(cellX
470 + halfOfCellSize, cellY - halfOfCellSize,
471 cellZ - halfOfCellSize, halfOfCellSize,
473 if (rayIntersectionResult >= 0)
474 return rayIntersectionResult;
476 if (ce4[pointer] != 0) {
477 rayIntersectionResult = traceCell(cellX
478 - halfOfCellSize, cellY + halfOfCellSize,
479 cellZ - halfOfCellSize, halfOfCellSize,
481 if (rayIntersectionResult >= 0)
482 return rayIntersectionResult;
485 if (ce5[pointer] != 0) {
486 rayIntersectionResult = traceCell(cellX
487 - halfOfCellSize, cellY - halfOfCellSize,
488 cellZ + halfOfCellSize, halfOfCellSize,
490 if (rayIntersectionResult >= 0)
491 return rayIntersectionResult;
494 if (ce1[pointer] != 0) {
495 rayIntersectionResult = traceCell(cellX
496 - halfOfCellSize, cellY - halfOfCellSize,
497 cellZ - halfOfCellSize, halfOfCellSize,
499 if (rayIntersectionResult >= 0)
500 return rayIntersectionResult;
506 if (ce3[pointer] != 0) {
507 rayIntersectionResult = traceCell(cellX
508 + halfOfCellSize, cellY + halfOfCellSize,
509 cellZ - halfOfCellSize, halfOfCellSize,
511 if (rayIntersectionResult >= 0)
512 return rayIntersectionResult;
515 if (ce2[pointer] != 0) {
516 rayIntersectionResult = traceCell(cellX
517 + halfOfCellSize, cellY - halfOfCellSize,
518 cellZ - halfOfCellSize, halfOfCellSize,
520 if (rayIntersectionResult >= 0)
521 return rayIntersectionResult;
523 if (ce4[pointer] != 0) {
524 rayIntersectionResult = traceCell(cellX
525 - halfOfCellSize, cellY + halfOfCellSize,
526 cellZ - halfOfCellSize, halfOfCellSize,
528 if (rayIntersectionResult >= 0)
529 return rayIntersectionResult;
532 if (ce7[pointer] != 0) {
533 rayIntersectionResult = traceCell(cellX
534 + halfOfCellSize, cellY + halfOfCellSize,
535 cellZ + halfOfCellSize, halfOfCellSize,
537 if (rayIntersectionResult >= 0)
538 return rayIntersectionResult;
540 if (ce6[pointer] != 0) {
541 rayIntersectionResult = traceCell(cellX
542 + halfOfCellSize, cellY - halfOfCellSize,
543 cellZ + halfOfCellSize, halfOfCellSize,
545 if (rayIntersectionResult >= 0)
546 return rayIntersectionResult;
548 if (ce8[pointer] != 0) {
549 rayIntersectionResult = traceCell(cellX
550 - halfOfCellSize, cellY + halfOfCellSize,
551 cellZ + halfOfCellSize, halfOfCellSize,
553 if (rayIntersectionResult >= 0)
554 return rayIntersectionResult;
557 if (ce1[pointer] != 0) {
558 rayIntersectionResult = traceCell(cellX
559 - halfOfCellSize, cellY - halfOfCellSize,
560 cellZ - halfOfCellSize, halfOfCellSize,
562 if (rayIntersectionResult >= 0)
563 return rayIntersectionResult;
566 if (ce5[pointer] != 0) {
567 rayIntersectionResult = traceCell(cellX
568 - halfOfCellSize, cellY - halfOfCellSize,
569 cellZ + halfOfCellSize, halfOfCellSize,
571 if (rayIntersectionResult >= 0)
572 return rayIntersectionResult;
576 } else if (ray.z > cellZ) {
579 if (ce6[pointer] != 0) {
580 rayIntersectionResult = traceCell(cellX
581 + halfOfCellSize, cellY - halfOfCellSize, cellZ
582 + halfOfCellSize, halfOfCellSize, ce6[pointer],
584 if (rayIntersectionResult >= 0)
585 return rayIntersectionResult;
588 if (ce7[pointer] != 0) {
589 rayIntersectionResult = traceCell(cellX
590 + halfOfCellSize, cellY + halfOfCellSize, cellZ
591 + halfOfCellSize, halfOfCellSize, ce7[pointer],
593 if (rayIntersectionResult >= 0)
594 return rayIntersectionResult;
596 if (ce2[pointer] != 0) {
597 rayIntersectionResult = traceCell(cellX
598 + halfOfCellSize, cellY - halfOfCellSize, cellZ
599 - halfOfCellSize, halfOfCellSize, ce2[pointer],
601 if (rayIntersectionResult >= 0)
602 return rayIntersectionResult;
604 if (ce5[pointer] != 0) {
605 rayIntersectionResult = traceCell(cellX
606 - halfOfCellSize, cellY - halfOfCellSize, cellZ
607 + halfOfCellSize, halfOfCellSize, ce5[pointer],
609 if (rayIntersectionResult >= 0)
610 return rayIntersectionResult;
612 if (ce8[pointer] != 0) {
613 rayIntersectionResult = traceCell(cellX
614 - halfOfCellSize, cellY + halfOfCellSize, cellZ
615 + halfOfCellSize, halfOfCellSize, ce8[pointer],
617 if (rayIntersectionResult >= 0)
618 return rayIntersectionResult;
620 if (ce3[pointer] != 0) {
621 rayIntersectionResult = traceCell(cellX
622 + halfOfCellSize, cellY + halfOfCellSize, cellZ
623 - halfOfCellSize, halfOfCellSize, ce3[pointer],
625 if (rayIntersectionResult >= 0)
626 return rayIntersectionResult;
629 if (ce1[pointer] != 0) {
630 rayIntersectionResult = traceCell(cellX
631 - halfOfCellSize, cellY - halfOfCellSize, cellZ
632 - halfOfCellSize, halfOfCellSize, ce1[pointer],
634 if (rayIntersectionResult >= 0)
635 return rayIntersectionResult;
637 if (ce4[pointer] != 0) {
638 rayIntersectionResult = traceCell(cellX
639 - halfOfCellSize, cellY + halfOfCellSize, cellZ
640 - halfOfCellSize, halfOfCellSize, ce4[pointer],
642 if (rayIntersectionResult >= 0)
643 return rayIntersectionResult;
649 if (ce2[pointer] != 0) {
650 rayIntersectionResult = traceCell(cellX
651 + halfOfCellSize, cellY - halfOfCellSize, cellZ
652 - halfOfCellSize, halfOfCellSize, ce2[pointer],
654 if (rayIntersectionResult >= 0)
655 return rayIntersectionResult;
658 if (ce3[pointer] != 0) {
659 rayIntersectionResult = traceCell(cellX
660 + halfOfCellSize, cellY + halfOfCellSize, cellZ
661 - halfOfCellSize, halfOfCellSize, ce3[pointer],
663 if (rayIntersectionResult >= 0)
664 return rayIntersectionResult;
667 if (ce1[pointer] != 0) {
668 rayIntersectionResult = traceCell(cellX
669 - halfOfCellSize, cellY - halfOfCellSize, cellZ
670 - halfOfCellSize, halfOfCellSize, ce1[pointer],
672 if (rayIntersectionResult >= 0)
673 return rayIntersectionResult;
675 if (ce6[pointer] != 0) {
676 rayIntersectionResult = traceCell(cellX
677 + halfOfCellSize, cellY - halfOfCellSize, cellZ
678 + halfOfCellSize, halfOfCellSize, ce6[pointer],
680 if (rayIntersectionResult >= 0)
681 return rayIntersectionResult;
684 if (ce7[pointer] != 0) {
685 rayIntersectionResult = traceCell(cellX
686 + halfOfCellSize, cellY + halfOfCellSize, cellZ
687 + halfOfCellSize, halfOfCellSize, ce7[pointer],
689 if (rayIntersectionResult >= 0)
690 return rayIntersectionResult;
692 if (ce5[pointer] != 0) {
693 rayIntersectionResult = traceCell(cellX
694 - halfOfCellSize, cellY - halfOfCellSize, cellZ
695 + halfOfCellSize, halfOfCellSize, ce5[pointer],
697 if (rayIntersectionResult >= 0)
698 return rayIntersectionResult;
700 if (ce4[pointer] != 0) {
701 rayIntersectionResult = traceCell(cellX
702 - halfOfCellSize, cellY + halfOfCellSize, cellZ
703 - halfOfCellSize, halfOfCellSize, ce4[pointer],
705 if (rayIntersectionResult >= 0)
706 return rayIntersectionResult;
708 if (ce8[pointer] != 0) {
709 rayIntersectionResult = traceCell(cellX
710 - halfOfCellSize, cellY + halfOfCellSize, cellZ
711 + halfOfCellSize, halfOfCellSize, ce8[pointer],
713 if (rayIntersectionResult >= 0)
714 return rayIntersectionResult;
718 } else if (ray.y > cellY) {
723 if (ce8[pointer] != 0) {
724 rayIntersectionResult = traceCell(cellX
725 - halfOfCellSize, cellY + halfOfCellSize, cellZ
726 + halfOfCellSize, halfOfCellSize, ce8[pointer],
728 if (rayIntersectionResult >= 0)
729 return rayIntersectionResult;
731 if (ce7[pointer] != 0) {
732 rayIntersectionResult = traceCell(cellX
733 + halfOfCellSize, cellY + halfOfCellSize, cellZ
734 + halfOfCellSize, halfOfCellSize, ce7[pointer],
736 if (rayIntersectionResult >= 0)
737 return rayIntersectionResult;
739 if (ce5[pointer] != 0) {
740 rayIntersectionResult = traceCell(cellX
741 - halfOfCellSize, cellY - halfOfCellSize, cellZ
742 + halfOfCellSize, halfOfCellSize, ce5[pointer],
744 if (rayIntersectionResult >= 0)
745 return rayIntersectionResult;
747 if (ce4[pointer] != 0) {
748 rayIntersectionResult = traceCell(cellX
749 - halfOfCellSize, cellY + halfOfCellSize, cellZ
750 - halfOfCellSize, halfOfCellSize, ce4[pointer],
752 if (rayIntersectionResult >= 0)
753 return rayIntersectionResult;
756 if (ce3[pointer] != 0) {
757 rayIntersectionResult = traceCell(cellX
758 + halfOfCellSize, cellY + halfOfCellSize, cellZ
759 - halfOfCellSize, halfOfCellSize, ce3[pointer],
761 if (rayIntersectionResult >= 0)
762 return rayIntersectionResult;
765 if (ce1[pointer] != 0) {
766 rayIntersectionResult = traceCell(cellX
767 - halfOfCellSize, cellY - halfOfCellSize, cellZ
768 - halfOfCellSize, halfOfCellSize, ce1[pointer],
770 if (rayIntersectionResult >= 0)
771 return rayIntersectionResult;
773 if (ce6[pointer] != 0) {
774 rayIntersectionResult = traceCell(cellX
775 + halfOfCellSize, cellY - halfOfCellSize, cellZ
776 + halfOfCellSize, halfOfCellSize, ce6[pointer],
778 if (rayIntersectionResult >= 0)
779 return rayIntersectionResult;
782 if (ce2[pointer] != 0) {
783 rayIntersectionResult = traceCell(cellX
784 + halfOfCellSize, cellY - halfOfCellSize, cellZ
785 - halfOfCellSize, halfOfCellSize, ce2[pointer],
787 if (rayIntersectionResult >= 0)
788 return rayIntersectionResult;
795 if (ce4[pointer] != 0) {
796 rayIntersectionResult = traceCell(cellX
797 - halfOfCellSize, cellY + halfOfCellSize, cellZ
798 - halfOfCellSize, halfOfCellSize, ce4[pointer],
800 if (rayIntersectionResult >= 0)
801 return rayIntersectionResult;
804 if (ce8[pointer] != 0) {
805 rayIntersectionResult = traceCell(cellX
806 - halfOfCellSize, cellY + halfOfCellSize, cellZ
807 + halfOfCellSize, halfOfCellSize, ce8[pointer],
809 if (rayIntersectionResult >= 0)
810 return rayIntersectionResult;
812 if (ce3[pointer] != 0) {
813 rayIntersectionResult = traceCell(cellX
814 + halfOfCellSize, cellY + halfOfCellSize, cellZ
815 - halfOfCellSize, halfOfCellSize, ce3[pointer],
817 if (rayIntersectionResult >= 0)
818 return rayIntersectionResult;
821 if (ce1[pointer] != 0) {
822 rayIntersectionResult = traceCell(cellX
823 - halfOfCellSize, cellY - halfOfCellSize, cellZ
824 - halfOfCellSize, halfOfCellSize, ce1[pointer],
826 if (rayIntersectionResult >= 0)
827 return rayIntersectionResult;
829 if (ce7[pointer] != 0) {
830 rayIntersectionResult = traceCell(cellX
831 + halfOfCellSize, cellY + halfOfCellSize, cellZ
832 + halfOfCellSize, halfOfCellSize, ce7[pointer],
834 if (rayIntersectionResult >= 0)
835 return rayIntersectionResult;
837 if (ce5[pointer] != 0) {
838 rayIntersectionResult = traceCell(cellX
839 - halfOfCellSize, cellY - halfOfCellSize, cellZ
840 + halfOfCellSize, halfOfCellSize, ce5[pointer],
842 if (rayIntersectionResult >= 0)
843 return rayIntersectionResult;
846 if (ce2[pointer] != 0) {
847 rayIntersectionResult = traceCell(cellX
848 + halfOfCellSize, cellY - halfOfCellSize, cellZ
849 - halfOfCellSize, halfOfCellSize, ce2[pointer],
851 if (rayIntersectionResult >= 0)
852 return rayIntersectionResult;
854 if (ce6[pointer] != 0) {
855 rayIntersectionResult = traceCell(cellX
856 + halfOfCellSize, cellY - halfOfCellSize, cellZ
857 + halfOfCellSize, halfOfCellSize, ce6[pointer],
859 if (rayIntersectionResult >= 0)
860 return rayIntersectionResult;
864 } else if (ray.z > cellZ) {
868 if (ce5[pointer] != 0) {
869 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
870 cellY - halfOfCellSize, cellZ + halfOfCellSize,
871 halfOfCellSize, ce5[pointer], ray);
872 if (rayIntersectionResult >= 0)
873 return rayIntersectionResult;
876 if (ce1[pointer] != 0) {
877 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
878 cellY - halfOfCellSize, cellZ - halfOfCellSize,
879 halfOfCellSize, ce1[pointer], ray);
880 if (rayIntersectionResult >= 0)
881 return rayIntersectionResult;
884 if (ce6[pointer] != 0) {
885 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
886 cellY - halfOfCellSize, cellZ + halfOfCellSize,
887 halfOfCellSize, ce6[pointer], ray);
888 if (rayIntersectionResult >= 0)
889 return rayIntersectionResult;
892 if (ce8[pointer] != 0) {
893 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
894 cellY + halfOfCellSize, cellZ + halfOfCellSize,
895 halfOfCellSize, ce8[pointer], ray);
896 if (rayIntersectionResult >= 0)
897 return rayIntersectionResult;
900 if (ce4[pointer] != 0) {
901 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
902 cellY + halfOfCellSize, cellZ - halfOfCellSize,
903 halfOfCellSize, ce4[pointer], ray);
904 if (rayIntersectionResult >= 0)
905 return rayIntersectionResult;
908 if (ce7[pointer] != 0) {
909 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
910 cellY + halfOfCellSize, cellZ + halfOfCellSize,
911 halfOfCellSize, ce7[pointer], ray);
912 if (rayIntersectionResult >= 0)
913 return rayIntersectionResult;
916 if (ce2[pointer] != 0) {
917 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
918 cellY - halfOfCellSize, cellZ - halfOfCellSize,
919 halfOfCellSize, ce2[pointer], ray);
920 if (rayIntersectionResult >= 0)
921 return rayIntersectionResult;
924 if (ce3[pointer] != 0) {
925 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
926 cellY + halfOfCellSize, cellZ - halfOfCellSize,
927 halfOfCellSize, ce3[pointer], ray);
928 if (rayIntersectionResult >= 0)
929 return rayIntersectionResult;
936 if (ce1[pointer] != 0) {
937 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
938 cellY - halfOfCellSize, cellZ - halfOfCellSize,
939 halfOfCellSize, ce1[pointer], ray);
940 if (rayIntersectionResult >= 0)
941 return rayIntersectionResult;
944 if (ce5[pointer] != 0) {
945 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
946 cellY - halfOfCellSize, cellZ + halfOfCellSize,
947 halfOfCellSize, ce5[pointer], ray);
948 if (rayIntersectionResult >= 0)
949 return rayIntersectionResult;
951 if (ce2[pointer] != 0) {
952 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
953 cellY - halfOfCellSize, cellZ - halfOfCellSize,
954 halfOfCellSize, ce2[pointer], ray);
955 if (rayIntersectionResult >= 0)
956 return rayIntersectionResult;
959 if (ce4[pointer] != 0) {
960 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
961 cellY + halfOfCellSize, cellZ - halfOfCellSize,
962 halfOfCellSize, ce4[pointer], ray);
963 if (rayIntersectionResult >= 0)
964 return rayIntersectionResult;
967 if (ce6[pointer] != 0) {
968 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
969 cellY - halfOfCellSize, cellZ + halfOfCellSize,
970 halfOfCellSize, ce6[pointer], ray);
971 if (rayIntersectionResult >= 0)
972 return rayIntersectionResult;
975 if (ce8[pointer] != 0) {
976 rayIntersectionResult = traceCell(cellX - halfOfCellSize,
977 cellY + halfOfCellSize, cellZ + halfOfCellSize,
978 halfOfCellSize, ce8[pointer], ray);
979 if (rayIntersectionResult >= 0)
980 return rayIntersectionResult;
983 if (ce3[pointer] != 0) {
984 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
985 cellY + halfOfCellSize, cellZ - halfOfCellSize,
986 halfOfCellSize, ce3[pointer], ray);
987 if (rayIntersectionResult >= 0)
988 return rayIntersectionResult;
990 if (ce7[pointer] != 0) {
991 rayIntersectionResult = traceCell(cellX + halfOfCellSize,
992 cellY + halfOfCellSize, cellZ + halfOfCellSize,
993 halfOfCellSize, ce7[pointer], ray);
994 if (rayIntersectionResult >= 0)
995 return rayIntersectionResult;