bool NaiadFoamParticle::IntersectP(const Ray &rayInc) const { Matrix4x4 w2o_m; w2o_m.m[0][3] = -pos.x; w2o_m.m[1][3] = -pos.y; w2o_m.m[2][3] = -pos.z; Transform w2o = Transform(w2o_m); float phi; Point phit; // Transform _Ray_ to object space Ray ray; w2o(rayInc, &ray); // Compute quadratic sphere coefficients float A = ray.d.x*ray.d.x + ray.d.y*ray.d.y + ray.d.z*ray.d.z; float B = 2 * (ray.d.x*ray.o.x + ray.d.y*ray.o.y + ray.d.z*ray.o.z); float C = ray.o.x*ray.o.x + ray.o.y*ray.o.y + ray.o.z*ray.o.z - r*r; // Solve quadratic equation for _t_ values float t0, t1; if (!Quadratic(A, B, C, &t0, &t1)) return false; // Compute intersection distance along ray if (t0 > ray.maxt || t1 < ray.mint) return false; float thit = t0; if (t0 < ray.mint) { thit = t1; if (thit > ray.maxt) return false; } return true; }
bool Sphere::intersect(const Ray& ray, RaySurfIntersection& res)const{ res.shp = NULL; //Transform ray to object space const Ray rOb = w2o(ray); const Vector o = Vector(rOb.getOrigin().x, rOb.getOrigin().y, rOb.getOrigin().z); const Vector d = rOb.getDir(); const float A = d.dot(d); const float B = 2.0f * (d.dot(o)); const float C = o.dot(o) - (r * r); struct MathUtils::QuadraticEqnRes<float> slv = MathUtils::solveQuadratic<float>(A, B, C); float tHitFinal = 0.0f; //After the below code this will eventually be set to //the first hit point in front of the camera if(slv.solCount == 0){ return false; }else if(slv.solCount == 1){ tHitFinal = slv.sol1; if(tHitFinal < 0.0f){ //No solutions in front of camera return false; } }else{ //2 solutions //Find smallest t value that is > 0.0f if(slv.sol1 < 0.0f && slv.sol2 < 0.0f){ //No solutions in front of camera return false; }else{ //At least one hit in front of camera slv.sol1 = slv.sol1 < 0.0f ? Constants::MAX_FLOAT_VAL : slv.sol1; slv.sol2 = slv.sol2 < 0.0f ? Constants::MAX_FLOAT_VAL : slv.sol2; tHitFinal = std::min<float>(slv.sol1, slv.sol2); } } //Make sure hit is in front of camera Assert(tHitFinal >= 0.0f); res.tHit = tHitFinal; res.locWS = ray(res.tHit); Vector normalVecAtHit = res.locWS - o2w(Point(0.0f,0.0f,0.0f)); res.n = normalVecAtHit.getNormalized(); res.shp = this; return true; }
bool NaiadFoamParticle::Intersect(const Ray &rayInc, float *tHit, float *rayEpsilon, DifferentialGeometry *dg) const { /*const float X0 = ray.o.x; const float Y0 = ray.o.y; const float Z0 = ray.o.z; const float Xd = ray.d.x; const float Yd = ray.d.y; const float Zd = ray.d.z; const float Xc = pos.x; const float Yc = pos.y; const float Zc = pos.z; const float B = 2.0f * (Xd * (X0 - Xc) + Yd * (Y0 - Yc) + Zd * (Z0 - Zc)); const float C = (X0-Xc)*(X0-Xc) + (Y0-Yc)*(Y0-Yc) + (Z0-Zc)*(Z0-Zc) - r*r; const float discriminant = B*B - 4*C; if (discriminant < 0.0f) return false; const float t0 = (- B - sqrt(discriminant)) / 2.0f; const float t1 = (- B + sqrt(discriminant)) / 2.0f; if (t0 < 0 || t0 != t0) { return true; }*/ Matrix4x4 w2o_m; w2o_m.m[0][3] = -pos.x; w2o_m.m[1][3] = -pos.y; w2o_m.m[2][3] = -pos.z; Transform w2o = Transform(w2o_m); const float thetaMin = -M_PI; const float thetaMax = 0; const float phiMax = 2.f*M_PI; float phi; Point phit; // Transform _Ray_ to object space Ray ray; w2o(rayInc, &ray); // Compute quadratic sphere coefficients float A = ray.d.x*ray.d.x + ray.d.y*ray.d.y + ray.d.z*ray.d.z; float B = 2 * (ray.d.x*ray.o.x + ray.d.y*ray.o.y + ray.d.z*ray.o.z); float C = ray.o.x*ray.o.x + ray.o.y*ray.o.y + ray.o.z*ray.o.z - r*r; // Solve quadratic equation for _t_ values float t0, t1; if (!Quadratic(A, B, C, &t0, &t1)) return false; // Compute intersection distance along ray if (t0 > ray.maxt || t1 < ray.mint) return false; float thit = t0; if (t0 < ray.mint) { thit = t1; if (thit > ray.maxt) return false; } // Compute sphere hit position and $\phi$ phit = ray(thit); rayInc.hitFoam = true; PerspectiveCamera * cam = PerspectiveCamera::cur_cam; Transform c2w; cam->CameraToWorld.Interpolate(0.f, &c2w); Transform w2c = Inverse(c2w); Transform c2s = cam->CameraToScreen; Transform s2r = cam->ScreenToRaster; Point cPos = w2c(phit); Point rPos = s2r(c2s(cPos)); int x = (int)(rPos.x + 0.5); int y = (int)(rPos.y + 0.5); int w = cam->film->xResolution; int h = cam->film->yResolution; if (x > 0 && y > 0 && x < w && y < h) { rayInc.hitFoam = true; /*printf("%i %i %i %i\n", x, y, w ,h); std::cout << parent << std::endl; std::cout << parent->parent << std::endl; std::cout << parent->parent->foamPlane[0] << std::endl; std::cout << parent->parent->foamPlane.size() << std::endl; std::cout << x + y*w << std::endl;*/ //std::cout << NaiadFoam::cur->FoamPlane().size() << std::endl; rayInc.alphaFoam = NaiadFoam::cur->FoamPlane()[x + y*w]; } /*if (phit.x == 0.f && phit.y == 0.f) phit.x = 1e-5f * r; phi = atan2f(phit.y, phit.x); if (phi < 0.) phi += 2.f*M_PI; // Find parametric representation of sphere hit float u = phi / phiMax; float theta = acosf(Clamp(phit.z / r, -1.f, 1.f)); float v = (theta - thetaMin) / (thetaMax - thetaMin); // Compute sphere $\dpdu$ and $\dpdv$ float zradius = sqrtf(phit.x*phit.x + phit.y*phit.y); float invzradius = 1.f / zradius; float cosphi = phit.x * invzradius; float sinphi = phit.y * invzradius; Vector dpdu(-phiMax * phit.y, phiMax * phit.x, 0); Vector dpdv = (thetaMax-thetaMin) * Vector(phit.z * cosphi, phit.z * sinphi, -r * sinf(theta)); // Compute sphere $\dndu$ and $\dndv$ Vector d2Pduu = -phiMax * phiMax * Vector(phit.x, phit.y, 0); Vector d2Pduv = (thetaMax - thetaMin) * phit.z * phiMax * Vector(-sinphi, cosphi, 0.); Vector d2Pdvv = -(thetaMax - thetaMin) * (thetaMax - thetaMin) * Vector(phit.x, phit.y, phit.z); // Compute coefficients for fundamental forms float E = Dot(dpdu, dpdu); float F = Dot(dpdu, dpdv); float G = Dot(dpdv, dpdv); Vector N = Normalize(Cross(dpdu, dpdv)); float e = Dot(N, d2Pduu); float f = Dot(N, d2Pduv); float g = Dot(N, d2Pdvv); // Compute $\dndu$ and $\dndv$ from fundamental form coefficients float invEGF2 = 1.f / (E*G - F*F); Normal dndu = Normal((f*F - e*G) * invEGF2 * dpdu + (e*F - f*E) * invEGF2 * dpdv); Normal dndv = Normal((g*F - f*G) * invEGF2 * dpdu + (f*F - g*E) * invEGF2 * dpdv); //std::cout << "Got here?" << std::endl; Matrix4x4 o2w_m; o2w_m.m[0][3] = pos.x; o2w_m.m[1][3] = pos.y; o2w_m.m[2][3] = pos.z; Transform o2w = Transform(o2w_m); // Initialize _DifferentialGeometry_ from parametric information *dg = DifferentialGeometry(o2w(phit), o2w(dpdu), o2w(dpdv), o2w(dndu), o2w(dndv), u, v, parent); dg->mult = 1.f;*/ // Update _tHit_ for quadric intersection //*tHit = thit; // Compute _rayEpsilon_ for quadric intersection //*rayEpsilon = 5e-4f * *tHit; return true; }