bool Tri::intersect(Ray& _ray, float* thit, Intersection* in) { Ray ray = _ray.transform(inverseTransform); if (!intersectP(ray)) { return false; } if (*thit < t) { return false; } p = ray.getPos() + ray.getDir() * t; w = p - a; vCrossW = glm::cross(v, w); uCrossW = glm::cross(u, w); if (glm::dot(vCrossW, vCrossU) < 0) { return false; } if (glm::dot(uCrossW, uCrossV) < 0) { return false; } beta = glm::length(vCrossW)/denom; gamma = glm::length(uCrossW)/denom; alpha = 1 - beta - gamma; if (!(beta <= 1 && gamma <= 1 && beta + gamma <= 1)) { return false; } *thit = t; in->localGeo.pos = mat4TimesVec3(getTransform(), (ray.getPos() + t * ray.getDir()), 1.0); in->localGeo.normal = getNormal(); //shift position slightly towards normal (epsilon shift) in->localGeo.pos = in->localGeo.pos + in->localGeo.normal * epsilon; in->primitive = this; return true; }
/** * Intersect a Ray with a plane defined by the 4 coefficients Ax + By + Cz + D = 0. * A,B,C are the plane normal */ bool planeIntersect(const Ray& r, const float *plane, PointF& intersection) { Normal normal(plane[0], plane[1], plane[2]); const PointF& rp = r.getPos(); float dotNormalRayDir = Math::dot3(normal, r.getDir()); // Is the ray perpendicular to the plane's normal? if (fabs(dotNormalRayDir) < PLANE_INTERSECTION_THRESHOLD) { return false; } // Determine which side of the plane the point is on float distFromPlane = Math::dot3(normal, rp) + plane[3]; float t = distFromPlane/dotNormalRayDir; // > 0 if ray and normal are in the same direction and // the ray is on the normal side of the plane or // If the ray and normal point in opposite directions and // the ray is not on the normal side of the plane if (t > 0) { return false; } intersection = Math::vec3AXPlusB(r.getDir(), -t, r.getPos()); return true; }
bool World::intersect(Ray & r, double & bestT, vec3 &outn, MaterialInfo &outm) { bestT = numeric_limits<double>::infinity(); if (_DEBUG_INTERSECT1 && abs(r.direction()[0] - 0.146734796) < 0.05 && abs(r.direction()[1] + 0.146734796) < 0.05 && abs(r.direction()[2] + 0.978231971) < 0.05) int i = 0; //debug statement, stops at a ray aimed at the center of one of the spheres in threespheres.scd if (_DEBUG_INTERSECT2 && abs(r.direction()[0] + 0.114776942) < 0.02 && abs(r.direction()[1] - 0.0619082097) < 0.02 && abs(r.direction()[2] + 0.991460351) < 0.02) int i = 0; // debug statement, stops at a ray aimed for the left eye of the bunny in ellipsoids.scd if (_ASSIGNMENT <= 5 || _FINAL_PROJ) { // iterate through spheres to see if any of them are intersected for (vector<Sphere>::iterator sphere = _spheres.begin(); sphere != _spheres.end(); sphere++) { double intersect = sphere->intersect(r); if (intersect < bestT) { //cout << "intersect found" << endl; bestT = intersect; //cout << intersect << " "; vec4 pos = r.getPos(intersect); //cout << pos[0] << "," << pos[1] << "," << pos[2] << " "; outn = vec3(sphere->calculateNormal(pos), VW); //cout << outn[0] << "," << outn[1] << "," << outn[2] << endl; outm = sphere->getMaterial(); //AS4 stuff //if (sphere == _spheres.begin()) { // outm.k[MAT_KSM] *= ksmMod; // outm.k[MAT_KSP] *= kspMod; // if (outm.k[MAT_KSP] < 1.0) outm.k[MAT_KSP] = 1.0; //} } } for (vector<Cube>::iterator cube = _cubes.begin(); cube != _cubes.end(); cube++) { double intersect = cube->intersect(r); if (intersect < bestT) { bestT = intersect; vec4 pos = r.getPos(intersect); outn = vec3(cube->calculateNormal(pos), VW); outm = cube->getMaterial(); outm.color = cube->calculateColor(pos); } } return bestT < numeric_limits<double>::infinity(); } else return _bb->intersect(r, bestT, outn, outm); }
bool intersect_search(Ray ray, Triangle* trig, int nTriangles, PoI* poi) { float min_hit = 99999; int count = 0; float t_hit; for (count = 0; count < nTriangles; count ++) { Triangle t = trig[count]; //t.scale(2, 1, 1); //scale by x-axis by 2 bool hit = t.hit(ray, &t_hit); if (hit && t_hit < min_hit) { min_hit = t_hit; poi->setCollision(ray.getDir() * min_hit + ray.getPos()); poi->setColor(t.kd); Vector myNorm = t.getNormal(); //if normal faces the wrong way, then needs to do soemthing about it //cos(angle) = dot_product / (a.len * b.len) float cosine = myNorm.Vdot(ray.getDir()) / (myNorm.getMag() * ray.getDir().getMag()); if (cosine < 0) { myNorm = myNorm * -1; } poi->setNormal(t.getNormal()); } } if (min_hit != 99999) { return true; } return false; }
bool Tri::intersectP(Ray& ray) { t = (glm::dot(a, planeNormal) - glm::dot(ray.getPos(), planeNormal)) / glm::dot(ray.getDir(), planeNormal); if (t > 0) { return true; } else { return false; } }