| author | Radek Brich <radek.brich@devl.cz> | 
| Thu, 13 Dec 2007 00:08:11 +0100 | |
| branch | pyrit | 
| changeset 36 | b490093b0ac3 | 
| parent 35 | fb170fccb19f | 
| child 37 | 5f954c0d34fc | 
| permissions | -rw-r--r-- | 
| 35 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 1 | /* | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 2 | * Pyrit Ray Tracer | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 3 | * file: octree.cc | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 4 | * | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 5 | * Radek Brich, 2006-2007 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 6 | */ | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 7 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 8 | #include "octree.h" | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 9 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 10 | OctreeNode::~OctreeNode() | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 11 | {
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 12 | if (shapes != NULL) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 13 | delete shapes; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 14 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 15 | delete[] children; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 16 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 17 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 18 | void OctreeNode::subdivide(BBox bbox, int maxdepth) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 19 | {
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 20 | if (maxdepth <= 0 || shapes->size() <= 4) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 21 | return; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 22 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 23 | // make children | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 24 | children = new OctreeNode[8]; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 25 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 26 | // evaluate centres for axes | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 27 | const Float xsplit = (bbox.L.x + bbox.H.x)*0.5; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 28 | const Float ysplit = (bbox.L.y + bbox.H.y)*0.5; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 29 | const Float zsplit = (bbox.L.z + bbox.H.z)*0.5; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 30 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 31 | // set bounding boxes for children | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 32 | 	BBox childbb[8] = {bbox, bbox, bbox, bbox, bbox, bbox, bbox, bbox};
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 33 | for (int i = 0; i < 4; i++) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 34 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 35 | // this is little obfuscated, so on right are listed affected children | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 36 | // the idea is to cut every axis once per child, making 8 combinations | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 37 | childbb[i].H.x = xsplit; // 0,1,2,3 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 38 | childbb[i+4].L.x = xsplit; // 4,5,6,7 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 39 | childbb[i+(i>>1<<1)].H.y = ysplit; // 0,1,4,5 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 40 | childbb[i+(i>>1<<1)+2].L.y = ysplit;// 2,3,6,7 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 41 | childbb[i<<1].H.z = zsplit; // 0,2,4,6 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 42 | childbb[(i<<1)+1].L.z = zsplit; // 1,3,5,7 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 43 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 44 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 45 | // distribute shapes to children | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 46 | ShapeList::iterator sh; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 47 | unsigned int shapenum = 0; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 48 | for (sh = shapes->begin(); sh != shapes->end(); sh++) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 49 | 	{
 | 
| 36 
b490093b0ac3
new virtual Shape::intersect_bbox
 Radek Brich <radek.brich@devl.cz> parents: 
35diff
changeset | 50 | for (int i = 0; i < 8; i++) | 
| 
b490093b0ac3
new virtual Shape::intersect_bbox
 Radek Brich <radek.brich@devl.cz> parents: 
35diff
changeset | 51 | if ((*sh)->intersect_bbox(childbb[i])) | 
| 35 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 52 | 			{
 | 
| 36 
b490093b0ac3
new virtual Shape::intersect_bbox
 Radek Brich <radek.brich@devl.cz> parents: 
35diff
changeset | 53 | getChild(i)->addShape(*sh); | 
| 
b490093b0ac3
new virtual Shape::intersect_bbox
 Radek Brich <radek.brich@devl.cz> parents: 
35diff
changeset | 54 | shapenum++; | 
| 35 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 55 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 56 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 57 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 58 | if (shapes->size() <= 8 && shapenum > 2*shapes->size()) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 59 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 60 | // bad subdivision, revert | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 61 | delete[] children; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 62 | return; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 63 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 64 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 65 | // remove shapes and set this node to non-leaf | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 66 | delete shapes; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 67 | shapes = NULL; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 68 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 69 | // recursive subdivision | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 70 | for (int i = 0; i < 8; i++) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 71 | children[i].subdivide(childbb[i], maxdepth-1); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 72 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 73 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 74 | void Octree::build() | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 75 | {
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 76 | dbgmsg(1, "* building octree\n"); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 77 | root = new OctreeNode(); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 78 | ShapeList::iterator shape; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 79 | for (shape = shapes.begin(); shape != shapes.end(); shape++) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 80 | root->addShape(*shape); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 81 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 82 | root->subdivide(bbox, max_depth); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 83 | built = true; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 84 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 85 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 86 | static inline int first_node(const Float tx0, const Float ty0, const Float tz0, | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 87 | const Float txm, const Float tym, const Float tzm) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 88 | {
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 89 | int res = 0; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 90 | if (tx0 > ty0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 91 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 92 | if (tx0 > tz0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 93 | 		{ // YZ
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 94 | if (tym < tx0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 95 | res |= 2; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 96 | if (tzm < tx0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 97 | res |= 1; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 98 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 99 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 100 | 		{ // XY
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 101 | if (txm < tz0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 102 | res |= 4; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 103 | if (tym < tz0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 104 | res |= 2; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 105 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 106 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 107 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 108 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 109 | if (ty0 > tz0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 110 | 		{ // XZ
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 111 | if (txm < ty0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 112 | res |= 4; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 113 | if (tzm < ty0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 114 | res |= 1; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 115 | return res; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 116 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 117 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 118 | 		{ // XY
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 119 | if (txm < tz0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 120 | res |= 4; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 121 | if (tym < tz0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 122 | res |= 2; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 123 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 124 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 125 | return res; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 126 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 127 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 128 | static inline int next_node(const Float txm, const int xnode, | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 129 | const Float tym, const int ynode, const Float tzm, const int znode) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 130 | {
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 131 | if (txm < tym) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 132 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 133 | if (txm < tzm) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 134 | return xnode; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 135 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 136 | return znode; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 137 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 138 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 139 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 140 | if (tym < tzm) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 141 | return ynode; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 142 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 143 | return znode; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 144 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 145 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 146 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 147 | static Shape *proc_subtree(const int a, const Float tx0, const Float ty0, const Float tz0, | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 148 | const Float tx1, const Float ty1, const Float tz1, OctreeNode *node, | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 149 | const Shape *origin_shape, const Ray &ray, Float &nearest_distance) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 150 | {
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 151 | Float txm, tym, tzm; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 152 | int curr_node; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 153 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 154 | // if ray does not intersect this node | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 155 | if (tx1 < 0.0 || ty1 < 0.0 || tz1 < 0.0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 156 | return NULL; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 157 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 158 | if (node->isLeaf()) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 159 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 160 | Shape *nearest_shape = NULL; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 161 | ShapeList::iterator shape; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 162 | Float mindist = max(max(tx0,ty0),tz0); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 163 | Float dist = min(min(min(tx1,ty1),tz1),nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 164 | for (shape = node->shapes->begin(); shape != node->shapes->end(); shape++) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 165 | if (*shape != origin_shape && (*shape)->intersect(ray, dist) && dist >= mindist) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 166 | 			{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 167 | nearest_shape = *shape; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 168 | nearest_distance = dist; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 169 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 170 | return nearest_shape; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 171 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 172 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 173 | txm = 0.5 * (tx0+tx1); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 174 | tym = 0.5 * (ty0+ty1); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 175 | tzm = 0.5 * (tz0+tz1); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 176 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 177 | curr_node = first_node(tx0,ty0,tz0,txm,tym,tzm); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 178 | Shape *shape = NULL; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 179 | while (curr_node < 8) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 180 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 181 | switch (curr_node) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 182 | 		{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 183 | case 0: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 184 | shape =proc_subtree (a,tx0,ty0,tz0,txm,tym,tzm,node->getChild(a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 185 | curr_node = next_node(txm, 4, tym, 2, tzm, 1); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 186 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 187 | case 1: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 188 | shape =proc_subtree (a,tx0,ty0,tzm,txm,tym,tz1,node->getChild(1^a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 189 | curr_node = next_node(txm, 5, tym, 3, tz1, 8); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 190 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 191 | case 2: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 192 | shape =proc_subtree (a,tx0,tym,tz0,txm,ty1,tzm,node->getChild(2^a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 193 | curr_node = next_node(txm, 6, ty1, 8, tzm, 3); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 194 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 195 | case 3: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 196 | shape =proc_subtree (a,tx0,tym,tzm,txm,ty1,tz1,node->getChild(3^a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 197 | curr_node = next_node(txm, 7, ty1, 8, tz1, 8); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 198 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 199 | case 4: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 200 | shape =proc_subtree (a,txm,ty0,tz0,tx1,tym,tzm,node->getChild(4^a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 201 | curr_node = next_node(tx1, 8, tym, 6, tzm, 5); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 202 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 203 | case 5: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 204 | shape =proc_subtree (a,txm,ty0,tzm,tx1,tym,tz1,node->getChild(5^a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 205 | curr_node = next_node(tx1, 8, tym, 7, tz1, 8); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 206 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 207 | case 6: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 208 | shape =proc_subtree (a,txm,tym,tz0,tx1,ty1,tzm,node->getChild(6^a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 209 | curr_node = next_node(tx1, 8, ty1, 8, tzm, 7); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 210 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 211 | case 7: | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 212 | shape =proc_subtree (a,txm,tym,tzm,tx1,ty1,tz1,node->getChild(7^a), origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 213 | curr_node = 8; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 214 | break; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 215 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 216 | if (shape != NULL) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 217 | return shape; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 218 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 219 | return NULL; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 220 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 221 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 222 | /* | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 223 | traversal algorithm paper as described in paper | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 224 | "An Efficient Parametric Algorithm for Octree Traversal" | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 225 | by J. Revelles, C. Urena and M. Lastra. | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 226 | */ | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 227 | Shape * Octree::nearest_intersection(const Shape *origin_shape, const Ray &ray, | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 228 | Float &nearest_distance) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 229 | {
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 230 | /* if we have no tree, fall back to naive test */ | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 231 | if (!built) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 232 | return Container::nearest_intersection(origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 233 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 234 | int a = 0; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 235 | Vector3 ro = ray.o; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 236 | Vector3 rdir = ray.dir; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 237 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 238 | if (rdir.x < 0.0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 239 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 240 | ro.x = (bbox.L.x+bbox.H.x) - ro.x; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 241 | rdir.x = -rdir.x; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 242 | a |= 4; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 243 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 244 | if (rdir.y < 0.0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 245 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 246 | ro.y = (bbox.L.y+bbox.H.y) - ro.y; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 247 | rdir.y = -rdir.y; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 248 | a |= 2; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 249 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 250 | if (rdir.z < 0.0) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 251 | 	{
 | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 252 | ro.z = (bbox.L.z+bbox.H.z) - ro.z; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 253 | rdir.z = -rdir.z; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 254 | a |= 1; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 255 | } | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 256 | Float tx0 = (bbox.L.x - ro.x) / rdir.x; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 257 | Float tx1 = (bbox.H.x - ro.x) / rdir.x; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 258 | Float ty0 = (bbox.L.y - ro.y) / rdir.y; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 259 | Float ty1 = (bbox.H.y - ro.y) / rdir.y; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 260 | Float tz0 = (bbox.L.z - ro.z) / rdir.z; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 261 | Float tz1 = (bbox.H.z - ro.z) / rdir.z; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 262 | |
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 263 | if (max(max(tx0,ty0),tz0) < min (min(tx1,ty1),tz1)) | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 264 | return proc_subtree(a,tx0,ty0,tz0,tx1,ty1,tz1,root, | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 265 | origin_shape, ray, nearest_distance); | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 266 | else | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 267 | return NULL; | 
| 
fb170fccb19f
new space partitioning structure: octree
 Radek Brich <radek.brich@devl.cz> parents: diff
changeset | 268 | } |