IntersectionData KDTree::searchNode(KDNode *node, const ray &viewRay, double tmin, double tmax, int curAxis) { assert(tmin <= tmax); assert(curAxis >= 0 && curAxis < 3); if(node->is_leaf) { return closestIntersection(node->objects, viewRay); } int nextAxis = (curAxis + 1) % 3; double tSplit = (node->split_pos - viewRay.orig(curAxis)) / viewRay.dir(curAxis); KDNode *nearNode, *farNode; if(viewRay.orig(curAxis) < node->split_pos) { nearNode = node->left; farNode = node->right; } else { nearNode = node->right; farNode = node->left; } if(tSplit > tmax) { return searchNode(nearNode, viewRay, tmin, tmax, nextAxis); } else if (tSplit < tmin) { if(tSplit > 0) return searchNode(farNode, viewRay, tmin, tmax, nextAxis); else if(tSplit < 0) return searchNode(nearNode, viewRay, tmin, tmax, nextAxis); else { if(viewRay.dir(curAxis) < 0) return searchNode(node->left, viewRay, tmin, tmax, nextAxis); else return searchNode(node->right, viewRay, tmin, tmax, nextAxis); } } else { if(tSplit > 0) { IntersectionData test = searchNode(nearNode, viewRay, tmin, tSplit, nextAxis); if(test.obj != NULL && test.time < tSplit + EPSILON) return test; else return searchNode(farNode, viewRay, tSplit, tmax, nextAxis); } else { return searchNode(nearNode, viewRay, tSplit, tmax, nextAxis); } } }