void R3Vector:: InverseTransform(const R3Matrix& matrix) { // Transform vector by inverse *this = matrix.Inverse() * (*this); }
int IntersectNode(R3Node *node, R3Ray r, R3Point *position, R3Vector *normal, double *t, R3Node **intersectingnode, R3Node *excludenode) { *t = DBL_MAX; R3Ray orig_r = r; R3Point intersectionpoint; R3Vector intersectionnormal; double t_intersection; R3Matrix tmatrix = node->transformation; R3Matrix tinvmatrix = tmatrix.Inverse(); r.Transform(tinvmatrix); if(node->shape != NULL && excludenode != node) { R3Shape *shape = node->shape; int intersects = -1; if(shape->type == R3_SPHERE_SHAPE) { R3Sphere *s = shape->sphere; intersects = IntersectSphere(s, r, &intersectionpoint, &intersectionnormal, &t_intersection); } else if(shape->type == R3_BOX_SHAPE) { R3Box *b = shape->box; intersects = IntersectBox(b, r, &intersectionpoint, &intersectionnormal, &t_intersection); } else if(shape->type == R3_MESH_SHAPE) { R3Mesh *m = shape->mesh; intersects = IntersectMesh(m, r, &intersectionpoint, &intersectionnormal, &t_intersection); } else if(shape->type == R3_CYLINDER_SHAPE) { R3Cylinder *c = shape->cylinder; intersects = IntersectCylinder(c, r, &intersectionpoint, &intersectionnormal, &t_intersection); } else if(shape->type == R3_CONE_SHAPE) { R3Cone *c = shape->cone; intersects = IntersectCone(c, r, &intersectionpoint, &intersectionnormal, &t_intersection); } if(intersects == 1) { if(t_intersection > 0 && t_intersection < *t) { *t = t_intersection; *position = intersectionpoint; *normal = intersectionnormal; *intersectingnode = node; } } } for(unsigned int i=0; i<node->children.size(); i++) { R3Node *child = node->children[i]; R3Node *temp_intersectingnode; if(IntersectBox(&(child->bbox), r, &intersectionpoint, &intersectionnormal, &t_intersection) == 1) { if(t_intersection > *t) continue; } else { continue; } if(IntersectNode(child, r, &intersectionpoint, &intersectionnormal, &t_intersection, &temp_intersectingnode, excludenode) == 1) { if(t_intersection > 0 && t_intersection < *t) { *t = t_intersection; *position = intersectionpoint; *normal = intersectionnormal; *intersectingnode = temp_intersectingnode; } } } if(*t < DBL_MAX) { normal->Transform(tmatrix); normal->Normalize(); position->Transform(tmatrix); if(orig_r.Vector()[0] != 0) *t = (*position - orig_r.Start())[0] / orig_r.Vector()[0]; else if(orig_r.Vector()[1] != 0) *t = (*position - orig_r.Start())[1] / orig_r.Vector()[1]; else *t = (*position - orig_r.Start())[2] / orig_r.Vector()[2]; return 1; } else { return 0; } }