void project_to_isosurface(Vec3f& point, const float target_value, const Array3f& grid, const Vec3f& origin, const float dx) { float tol = 0.01f*dx; //some fraction of a grid cell; int max_iter = 5; int iter = 0; Vec3f normal; float phi = interpolate_normal(normal, point, grid, origin, dx); while(fabs(phi - target_value) > tol && iter++ < max_iter) { point -= (phi - target_value) * normal; phi = interpolate_normal(normal, point, grid, origin, dx); } }
void render_quarter(int n) { int i, j; GLfloat step = 1.0/((GLfloat)n-1); GLfloat x[2]; GLfloat y[2]; GLfloat normal[2][2][3]; for(i = 0 ; i < n-1 ; i++) { for(j = 0 ; j < n-1 ; j++) { x[0] = step*((GLfloat)i); x[1] = step*((GLfloat)(i+1)); y[0] = step*((GLfloat)j); y[1] = step*((GLfloat)(j+1)); interpolate_normal(x[0],y[0],normal[0][0]); interpolate_normal(x[0],y[1],normal[0][1]); interpolate_normal(x[1],y[0],normal[1][0]); interpolate_normal(x[1],y[1],normal[1][1]); #define SET_VERT(ix,iy) \ glNormal3fv(normal[ix][iy]); \ glVertex3f(x[ix],y[iy],0); #define SCALE .2 if(flag & FLAG_NORMAL) { glDisable(GL_LIGHTING); glColor3f(1,1,1); glBegin(GL_LINES); glVertex3f(x[0],y[0],0); glVertex3f(x[0]+SCALE*normal[0][0][0], y[0]+SCALE*normal[0][0][1], SCALE*normal[0][0][2]); glVertex3f(x[0],y[1],0); glVertex3f(x[0]+SCALE*normal[0][1][0], y[1]+SCALE*normal[0][1][1], SCALE*normal[0][1][2]); glVertex3f(x[1],y[0],0); glVertex3f(x[1]+SCALE*normal[1][0][0], y[0]+SCALE*normal[1][0][1], SCALE*normal[1][0][2]); glVertex3f(x[1],y[1],0); glVertex3f(x[1]+SCALE*normal[1][1][0], y[1]+SCALE*normal[1][1][1], SCALE*normal[1][1][2]); glEnd(); glEnable(GL_LIGHTING); } glBegin(GL_QUADS); SET_VERT(0,0); SET_VERT(1,0); SET_VERT(1,1); SET_VERT(0,1); glEnd(); } } }
bool SmoothUVMeshTriangle::hit(const Ray& ray, double& tmin, ShadeRec& sr) const { Point3D v0(mesh_ptr->vertices[index0]); Point3D v1(mesh_ptr->vertices[index1]); Point3D v2(mesh_ptr->vertices[index2]); double a = v0.x - v1.x, b = v0.x - v2.x, c = ray.d.x, d = v0.x - ray.o.x; double e = v0.y - v1.y, f = v0.y - v2.y, g = ray.d.y, h = v0.y - ray.o.y; double i = v0.z - v1.z, j = v0.z - v2.z, k = ray.d.z, l = v0.z - ray.o.z; double m = f * k - g * j, n = h * k - g * l, p = f * l - h * j; double q = g * i - e * k, s = e * j - f * i; double inv_denom = 1.0 / (a * m + b * q + c * s); double e1 = d * m - b * n - c * p; double beta = e1 * inv_denom; if (beta < 0.0) return (false); double r = e * l - h * i; double e2 = a * n + d * q + c * r; double gamma = e2 * inv_denom; if (gamma < 0.0) return (false); if (beta + gamma > 1.0) return (false); double e3 = a * p - b * r + d * s; double t = e3 * inv_denom; if (t < kEpsilon) return (false); tmin = t; sr.normal = interpolate_normal(beta, gamma); // for smooth shading //sr.local_hit_point = ray.o + t * ray.d; sr.u = interpolate_u(beta, gamma); sr.v = interpolate_v(beta, gamma); return (true); }
void surface_fractal_terrain::generate_mesh(const std::vector<std::vector<double> > &height, int size, double sidelen) { double scale = sidelen / size, delta = 1.0 / size; std::vector<point3D> vertices; #define __id(i, j) ((i) * (size + 1) + (j)) for (int i = 0; i <= size; ++i) { for (int j = 0; j <= size; ++j) { vertices.push_back(point3D(i * scale, j * scale, height[i][j])); } } setup_vertex(vertices); for (int i = 0; i < size; ++i) { for (int j = 0; j < size; ++j) { double u = i * delta, v = j * delta; add_surface(__id(i, j), __id(i + 1, j), __id(i, j + 1)).set_UV(point2D(u, v), point2D(u + delta, v), point2D(u, v + delta)); add_surface(__id(i + 1, j), __id(i + 1, j + 1), __id(i, j + 1)).set_UV(point2D(u + delta, v), point2D(u + delta, v + delta), point2D(u, v + delta)); } } #undef __id setup_tree(); interpolate_normal(); }