// Object Creation Function Definitions std::vector<std::shared_ptr<Shape>> MakeShapes(const std::string &name, const Transform *object2world, const Transform *world2object, bool reverseOrientation, const ParamSet ¶mSet) { std::vector<std::shared_ptr<Shape>> shapes; std::shared_ptr<Shape> s; if (name == "sphere") s = CreateSphereShape(object2world, world2object, reverseOrientation, paramSet); // Create remaining single _Shape_ types else if (name == "cylinder") s = CreateCylinderShape(object2world, world2object, reverseOrientation, paramSet); else if (name == "disk") s = CreateDiskShape(object2world, world2object, reverseOrientation, paramSet); else if (name == "cone") s = CreateConeShape(object2world, world2object, reverseOrientation, paramSet); else if (name == "paraboloid") s = CreateParaboloidShape(object2world, world2object, reverseOrientation, paramSet); else if (name == "hyperboloid") s = CreateHyperboloidShape(object2world, world2object, reverseOrientation, paramSet); if (s != nullptr) shapes.push_back(s); // Create multiple-_Shape_ types else if (name == "curve") shapes = CreateCurveShape(object2world, world2object, reverseOrientation, paramSet); else if (name == "trianglemesh") shapes = CreateTriangleMeshShape(object2world, world2object, reverseOrientation, paramSet, &graphicsState.floatTextures); else if (name == "plymesh") shapes = CreatePLYMesh(object2world, world2object, reverseOrientation, paramSet, &graphicsState.floatTextures); else if (name == "heightfield") shapes = CreateHeightfield(object2world, world2object, reverseOrientation, paramSet); else if (name == "loopsubdiv") shapes = CreateLoopSubdiv(object2world, world2object, reverseOrientation, paramSet); else if (name == "nurbs") shapes = CreateNURBS(object2world, world2object, reverseOrientation, paramSet); else Warning("Shape \"%s\" unknown.", name.c_str()); paramSet.ReportUnused(); return shapes; }
void Heightfield::Refine(vector<Reference<Shape> > &refined) const { int ntris = 2*(nx-1)*(ny-1); refined.reserve(ntris); int *verts = new int[3*ntris]; Point *P = new Point[nx*ny]; float *uvs = new float[2*nx*ny]; int nverts = nx*ny; int x, y; // Compute heightfield vertex positions int pos = 0; for (y = 0; y < ny; ++y) { for (x = 0; x < nx; ++x) { P[pos].x = uvs[2*pos] = (float)x / (float)(nx-1); P[pos].y = uvs[2*pos+1] = (float)y / (float)(ny-1); P[pos].z = z[pos]; ++pos; } } // Fill in heightfield vertex offset array int *vp = verts; for (y = 0; y < ny-1; ++y) { for (x = 0; x < nx-1; ++x) { #define VERT(x,y) ((x)+(y)*nx) *vp++ = VERT(x, y); *vp++ = VERT(x+1, y); *vp++ = VERT(x+1, y+1); *vp++ = VERT(x, y); *vp++ = VERT(x+1, y+1); *vp++ = VERT(x, y+1); } #undef VERT } ParamSet paramSet; paramSet.AddInt("indices", verts, 3*ntris); paramSet.AddFloat("uv", uvs, 2 * nverts); paramSet.AddPoint("P", P, nverts); refined.push_back(CreateTriangleMeshShape(ObjectToWorld, WorldToObject, ReverseOrientation, paramSet)); delete[] P; delete[] uvs; delete[] verts; }