osuObject* track(const ray &r, point &p, double bestT ) { osuObject *closest = NULL; std::vector<osuObject*>::iterator it; for ( it = ObjectList.begin(); it < ObjectList.end(); ++it ) { double t = (*it)->intersection(r); if ( t > INTERSECTIOnormalTOLERANCE && t < bestT ) { closest = *it; bestT = t; } } if ( closest == NULL ) { p.w = 0.0; return NULL; } else { findPointOnRay(r, bestT, p); return closest; } }
/* If something is hit, returns the finite intersection point p, the normal vector n to the surface at that point, and the surface material m. If no hit, returns an infinite point (p->w = 0.0) */ void firstHit(ray* r, point* p, vector* n, material* *m) { int i; int index; int flag_cyl, flag_hyp; double t = 0; /* parameter value at first hit */ int hit = FALSE; //SURFACE_TYPE objects[objnum] = { PLAIN, SPHERE, SPHERE, SPHERE, CYLINDER, HYPERBOLOID }; int hits[objnum] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; double tvalues[objnum] = { -1.0, -1.0, -1.0, -1.0, -1.0, -1.0 }; for (i = 0; i < objnum; ++i) { switch (i) { case 0: hits[i] = rayPlainIntersect(r,pln1,&tvalues[i]); if (hits[i]) { index = i; hit = TRUE; } break; case 1: hits[i] = raySphereIntersect(r,sph0,&tvalues[i]); if (hits[i]) { index = i; hit = TRUE; } break; case 2: hits[i] = raySphereIntersect(r,sph1,&tvalues[i]); if (hits[i]) { index = i; hit = TRUE; } break; case 3: hits[i] = raySphereIntersect(r,sph2,&tvalues[i]); if (hits[i]) { index = i; hit = TRUE; } break; case 4: hits[i] = rayCylinderIntersect(r,cyl0,&tvalues[i],&flag_cyl); if (hits[i]) { index = i; hit = TRUE; } break; case 5: hits[i] = rayHyperbolIntersect(r,hyp0,&tvalues[i],&flag_hyp); if (hits[i]) { index = i; hit = TRUE; } break; default: break; } } if ( hit ) { findMin(tvalues, objnum, &t, &index); findPointOnRay(r, t, p); switch (index) { case 0: *m = pln1->m; findPlainNormal(pln1,p,n); break; case 1: *m = sph0->m; findSphereNormal(sph0,p,n); break; case 2: *m = sph1->m; findSphereNormal(sph1,p,n); break; case 3: *m = sph2->m; findSphereNormal(sph2,p,n); break; case 4: *m = cyl0->m; findCylinderNormal(cyl0,p,n,flag_cyl); break; case 5: *m = hyp0->m; findHyperbolNormal(hyp0,p,n,flag_hyp); break; default: break; } } else { /* no hit */ p->w = 0.0; } }