Real raySphereIntersectionTime(Ray3 const & ray, Vector3 const & center, Real radius) { Vector3 pmc = ray.getOrigin() - center; double s[3]; s[2] = ray.getDirection().squaredLength(); s[1] = 2 * pmc.dot(ray.getDirection()); s[0] = pmc.squaredLength() - radius * radius; double roots[2]; int num_roots = Math::solveQuadratic(s[0], s[1], s[2], roots); double min_root = -1; for (int i = 0; i < num_roots; ++i) if (roots[i] >= 0 && (min_root < 0 || roots[i] < min_root)) min_root = roots[i]; #if 0 if (min_root >= 0) qDebug() << "min_root =" << min_root; #endif return (Real)min_root; }
Color rayTraceRecursive(Object &scene, Ray3& ray, int maxReflect, DirectionalLight light) { IntersectResult result = scene.intersect(ray); //cout<<result.getGeometry()->material->getReflectiveness()<<endl; if(result.getGeometry()) { Color color = Color::black; Vec3 lightSample = light.sample(scene, result.getPosition()); //cout<<lightSample.getx()<< " " << lightSample.gety() << " "<<lightSample.getz()<<endl; float reflectiveness = result.getGeometry()->material->getReflectiveness(); // just the float to int. it is rediculous color = result.getGeometry()->material->sample(ray,result.getPosition(),result.getNormal()); color = color.multiply(1-reflectiveness); // cout << reflectiveness <<endl; if(reflectiveness>0 && maxReflect > 0) { // cout << reflectiveness <<endl; Vec3 r = result.getNormal().multiply(-2*result.getNormal().dot(ray.getDirection())).add(ray.getDirection()); ray = Ray3(result.getPosition(),r); Color reflectedColor = rayTraceRecursive(scene, ray, maxReflect-1, light); color = color.add(reflectedColor.multiply(reflectiveness)); if(fabs(lightSample.getx())> 1e-4 || fabs(lightSample.gety())> 1e-4 || fabs(lightSample.getz()>1e-4)) { }else{ color = color.modulate(Color(0.3,0.3,0.3)); } } //cout<<"abc"<<endl; return color; }else{ return Color::black; } }
Real rayTorusIntersectionTime(Ray3 const & ray, Real torus_radius, Real torus_width) { double r2pw2 = torus_radius * torus_radius + torus_width * torus_width; double r2mw2 = r2pw2 - 2 * torus_width * torus_width; Vector3 p2 = ray.getOrigin() * ray.getOrigin(); Vector3 pu = ray.getOrigin() * ray.getDirection(); Vector3 u2 = ray.getDirection() * ray.getDirection(); double s[5]; s[4] = u2[0] * (u2[0] + 2 * u2[1]) + u2[1] * (u2[1] + 2 * u2[2]) + u2[2] * (u2[2] + 2 * u2[0]); s[3] = 4 * (pu[0] + pu[1] + pu[2]) * (u2[0] + u2[1] + u2[2]); s[2] = 2 * (r2mw2 * u2[2] - r2pw2 * (u2[0] + u2[1])) + 8 * (pu[0] * pu[1] + pu[1] * pu[2] + pu[2] * pu[0]) + 6 * (pu[0] * pu[0] + pu[1] * pu[1] + pu[2] * pu[2]) + 2 * (p2[0] * (u2[1] + u2[2]) + p2[1] * (u2[2] + u2[0]) + p2[2] * (u2[0] + u2[1])); s[1] = 4 * (r2mw2 * pu[2] - r2pw2 * (pu[0] + pu[1]) + (p2[0] + p2[1] + p2[2]) * (pu[0] + pu[1] + pu[2])); s[0] = 2 * (r2mw2 * p2[2] - r2pw2 * (p2[0] + p2[1]) + p2[0] * p2[1] + p2[1] * p2[2] + p2[2] * p2[0]) + p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2] + r2mw2 * r2mw2; double roots[4]; int num_roots = Math::solveQuartic(s[0], s[1], s[2], s[3], s[4], roots); double min_root = -1; for (int i = 0; i < num_roots; ++i) if (roots[i] >= 0 && (min_root < 0 || roots[i] < min_root)) min_root = roots[i]; #if 0 if (min_root >= 0) qDebug() << "min_root =" << min_root; #endif return (Real)min_root; }
Color PhongMaterial::sample(const Ray3& ray, const Vec3& position, const Vec3& normal) { // i don't know why global will lead to ld error //Vec3 lightDir = Vec3(1,1,1).normalize(); //Color lightColor = Color::white; // Vec3 lightDir = Vec3(1,1,1).normalize(); DirectionalLight lightDir(Vec3(-1,-1,-1)); Color lightColor = Color::white; float NdotL = normal.dot(lightDir.L); //cout << "NdotL: " << NdotL << endl; Vec3 H = lightDir.L.substract(ray.getDirection()).normalize(); float NdotH = normal.dot(H); //cout << "NdotH: " << NdotH << endl; Color diffuseTerm = diffuse.multiply(fmax(NdotL,0)); Color specularTerm = specular.multiply( pow( fmax(NdotH,0), shininess)); // cout << "diffTerm: " << diffuseTerm.getR() << " "<<diffuseTerm.getG() << " " << diffuseTerm.getB() << endl; // cout << "specTerm: " << specularTerm.getR() << " " << specularTerm.getG() << " " << specularTerm.getB() << endl; Color ret = lightColor.modulate(diffuseTerm.add(specularTerm)); if(ret.getR()>1) // it is possible that the color is overflow { ret.setR(1); } if(ret.getB()>1) { ret.setB(1); } if(ret.getG()>1) { ret.setG(1); } Color add = diffuseTerm.add(specularTerm); Color modulate = lightColor.modulate((add)); //cout << "add: " << add.getR() << " " << add.getG() << " " << add.getB() << endl; //cout << "modulate: " << modulate.getR() << " " << modulate.getG() << " " << modulate.getB() << endl; //cout << "lightColor: " << lightColor.getR() << " " << lightColor.getG() << " " << lightColor.getB() << endl; //cout << "ret: " << ret.getR() << " " << ret.getG() << " " << ret.getB() << endl; return ret; }
Real closestPtRayTriangle(Ray3 const & ray, Vector3 const & v0, Vector3 const & edge01, Vector3 const & edge02, Real & s, Vector3 & c1, Vector3 & c2) { Real sqdist = closestPtLineTriangle(Line3::fromPointAndDirection(ray.getOrigin(), ray.getDirection()), v0, edge01, edge02, s, c1, c2); if (s >= 0) return sqdist; // Not the most efficient way but the most convenient LocalTriangle3 tri(v0, v0 + edge01, v0 + edge02); s = 0; c1 = ray.getOrigin(); c2 = tri.closestPoint(c1); return (c1 - c2).squaredLength(); }