bool VolumetricSphere::hit(const Ray& ray, float& t, float& tmin, ShadeRec& sr) const { // TODO: I believe this will only calculate first intersection // ok for sphere, not for transparent things if (bbox.hit(ray)) { Normal normal = Normal(); Point3D hit_pt = ray.o; // + t * ray.d; float dist = 0.0, t=0.1; for (int i=0; i < 1000; i++) { dist = evaluate(hit_pt); hit_pt = ray.o + t * ray.d; t += stepsize; if (dist < 0.01) break; } if (dist < 0.01) { // calculate normal normal.x += hit_pt.x + 0.2*stepsize; normal.x += hit_pt.x - 0.2 * stepsize; normal.y += hit_pt.y + 0.2 * stepsize; normal.y += hit_pt.y - 0.2 * stepsize; normal.z += hit_pt.z + 0.2 * stepsize; normal.z += hit_pt.z - 0.2 * stepsize; normal.normalize(); sr.ph = hit_pt; sr.local_ph = hit_pt; sr.nh = normal; tmin = t; return true; } return false; } return false; }
void Grid::compute_mesh_normals(void) { mesh_ptr->normals.reserve(mesh_ptr->num_vertices); for (int index = 0; index < mesh_ptr->num_vertices; index++) { // for each vertex Normal normal; // is zero at this point for (int j = 0; j < mesh_ptr->vertex_faces[index].size(); j++) normal += objects[mesh_ptr->vertex_faces[index][j]]->get_normal(); // The following code attempts to avoid (nan, nan, nan) normalised normals when all components = 0 if (normal.x == 0.0 && normal.y == 0.0 && normal.z == 0.0) normal.y = 1.0; else normal.normalize(); mesh_ptr->normals.push_back(normal); } // erase the vertex_faces arrays because we have now finished with them for (int index = 0; index < mesh_ptr->num_vertices; index++) for (int j = 0; j < mesh_ptr->vertex_faces[index].size(); j++) mesh_ptr->vertex_faces[index].erase (mesh_ptr->vertex_faces[index].begin(), mesh_ptr->vertex_faces[index].end()); mesh_ptr->vertex_faces.erase (mesh_ptr->vertex_faces.begin(), mesh_ptr->vertex_faces.end()); cout << "finished constructing normals" << endl; }
//Always returns a normalized vector Normal Normal::operator-(Normal n) { Normal result; result.x = x - n.x; result.y = y - n.y; result.z = z - n.z; result = result.normalize(); return result; }
//Always returns a normalized Vector Normal Normal::operator+(Normal n) { Normal result; result.x = x + n.x; result.y = y + n.y; result.z = z + n.z; result = result.normalize(); return result; }
Normal<> Mesh::calculateTriangleNormal(Point3D<> &p0, Point3D<> &p1, Point3D<> &p2){ Normal<> normal; Point3D<> v1 = p1 - p0; Point3D<> v2 = p2 - p1; normal[0] = v1[1] * v2[2] - v1[2] * v2[1]; normal[1] = v1[2] * v2[0] - v1[0] * v2[2]; normal[2] = v1[0] * v2[1] - v1[1] * v2[0]; normal.normalize(); return normal; }
Normal Torus::compute_normal(const Point3D& p) const { Normal normal; double param_squared = a * a + b * b; double x = p.x; double y = p.y; double z = p.z; double sum_squared = x * x + y * y + z * z; normal.x = 4.0 * x * (sum_squared - param_squared); normal.y = 4.0 * y * (sum_squared - param_squared + 2.0 * a * a); normal.z = 4.0 * z * (sum_squared - param_squared); normal.normalize(); return normal; }