void test03_trimesh_3() { /* Shading normals & UV coords, but with an explicit parameterization */ ref<TriMesh> trimesh = new TriMesh("", 1, 3, true, true); Triangle &tri = trimesh->getTriangles()[0]; tri.idx[0] = 0; tri.idx[1] = 1; tri.idx[2] = 2; Point *vertices = trimesh->getVertexPositions(); Normal *normals = trimesh->getVertexNormals(); Point2 *uv = trimesh->getVertexTexcoords(); vertices[0] = Point(0, 0, 0); vertices[1] = Point(1, 0, 0); vertices[2] = Point(0, 1, 0); normals[0] = Normal(-0.3f, 0, 1); normals[1] = Normal(0.3f, 0, 1); normals[2] = Normal(0, 0.3f, 1); uv[0] = Point2(0.0f, 0.0f); uv[1] = Point2(0.0f, 1.0f); uv[2] = Point2(1.0f, 0.0f); trimesh->configure(); trimesh->computeUVTangents(); ref<ShapeKDTree> kdtree = new ShapeKDTree(); kdtree->addShape(trimesh); kdtree->build(); Intersection its; Ray ray(Point(0.1f, 0.2f, -1.0f), Vector(0, 0, 1), 123.0f); assertTrue(kdtree->rayIntersect(ray, its)); assertEquals(its.p, Point(0.1f, 0.2f, 0.0f)); assertEqualsEpsilon(its.uv, Point2(0.2f, 0.1f), Epsilon); assertEquals(its.geoFrame.n, Normal(0, 0, 1)); assertEqualsEpsilon(its.shFrame.n, normalize(normals[0]*.7f + normals[1]*.1f + normals[2]*.2f), Epsilon); assertEqualsEpsilon(its.shFrame.s, normalize(its.dpdu - its.shFrame.n * dot(its.dpdu, its.shFrame.n)), Epsilon); its.shFrame.s = normalize(its.dpdu - its.shFrame.n * dot(its.shFrame.n, its.dpdu)); assertEquals(its.dpdu, vertices[2]-vertices[0]); assertEquals(its.dpdv, vertices[1]-vertices[0]); assertEquals(its.time, 123.0f); Vector dndu, dndv; its.shape->getNormalDerivative(its, dndu, dndv, false); assertEquals(dndu, Vector(0.0f)); assertEquals(dndv, Vector(0.0f)); its.shape->getNormalDerivative(its, dndu, dndv, true); // From mathematica assertEqualsEpsilon(dndu, Vector(0.288596f, 0.29679f, 0.0341399f), 1e-4f); assertEqualsEpsilon(dndv, Vector(0.571048f, 0.00614519f, 0.10242f), 1e-4f); }
void test03_nD_02() { NDIntegrator quad(2, 3, 1000000, 0, 1e-5f); size_t evals; Float min[3] = { -1, -1, -1 } , max[3] = { 1, 1, 1 }, result[2], err[2]; assertTrue(quad.integrateVectorized(boost::bind( &TestQuadrature::testF3, this, _1, _2, _3), min, max, result, err, &evals) == NDIntegrator::ESuccess); Log(EInfo, "test02_nD_02(): used " SIZE_T_FMT " function evaluations, " "error=[%f, %f]", evals, err[0], err[1]); assertEqualsEpsilon(result[0], 1.0f, 1e-5f); assertEqualsEpsilon(result[1], 1.0f, 1e-5f); }
void test01_smoothTransmittance() { /* Smooth diffuse transmittance - compare polynomial approximations to ground truth */ for (int i=0; i<=10; ++i) { Float eta = 1 + i/10.0f; Float f1 = fresnelDiffuseReflectance(eta, false); Float f2 = fresnelDiffuseReflectance(eta, true); Float f3 = fresnelDiffuseReflectance(1/eta, false); Float f4 = fresnelDiffuseReflectance(1/eta, true); assertEqualsEpsilon(std::abs(f1-f2), (Float) 0, 1e-3f); assertEqualsEpsilon(std::abs(f3-f4), (Float) 0, 1e-3f); } }
void test01_shRotation() { /* Generate a random SH expansion, rotate it and spot-check 100 times against the original evaluated at appropriately rotated positions */ ref<Random> random = new Random(); int bands = 8; SHVector vec1(bands); for (int l=0; l<bands; ++l) for (int m=-l; m<=l; ++m) vec1(l, m) = random->nextFloat(); Vector axis(squareToSphere(Point2(random->nextFloat(), random->nextFloat()))); Transform trafo = Transform::rotate(axis, random->nextFloat()*360); Transform inv = trafo.inverse(); SHRotation rot(vec1.getBands()); SHVector::rotation(trafo, rot); SHVector vec2(bands); rot(vec1, vec2); for (int i=0; i<100; ++i) { Vector dir1(squareToSphere(Point2(random->nextFloat(), random->nextFloat()))), dir2; trafo(dir1, dir2); Float value1 = vec1.eval(dir2); Float value2 = vec2.eval(dir1); assertEqualsEpsilon(value1, value2, Epsilon); } }
void assertEquals(const double & expected, const double & result, const char * file, int line) { const double fuzzyEpsilon=0.000001; assertEqualsEpsilon(expected, result, fuzzyEpsilon, file, line); }
void test07_gaussLobatto_odd() { Float nodes[5], weights[5]; gaussLobatto(5, nodes, weights); assertEqualsEpsilon(nodes[0], -1.0f, 1e-8f); assertEqualsEpsilon(nodes[1], (Float) -(std::sqrt(21.0)/7.0), 1e-8f); assertEqualsEpsilon(nodes[2], 0.0f, 1e-8f); assertEqualsEpsilon(nodes[3], (Float) (std::sqrt(21.0)/7.0), 1e-8f); assertEqualsEpsilon(nodes[4], 1.0f, 1e-8f); assertEqualsEpsilon(weights[0], (Float) (1.0/10.0), 1e-8f); assertEqualsEpsilon(weights[1], (Float) (49.0/90.0), 1e-8f); assertEqualsEpsilon(weights[2], (Float) (32.0/45.0), 1e-8f); assertEqualsEpsilon(weights[3], (Float) (49.0/90.0), 1e-8f); assertEqualsEpsilon(weights[4], (Float) (1.0/10.0), 1e-8f); }
void test05_gaussLegendre_odd() { Float nodes[5], weights[5]; gaussLegendre(5, nodes, weights); assertEqualsEpsilon(nodes[0], (Float) (-1/21.0 * std::sqrt(245+14*std::sqrt(70.0))), 1e-8f); assertEqualsEpsilon(nodes[1], (Float) (-1/21.0 * std::sqrt(245-14*std::sqrt(70.0))), 1e-8f); assertEqualsEpsilon(nodes[2], 0.0, 1e-8f); assertEqualsEpsilon(nodes[3], (Float) ( 1/21.0 * std::sqrt(245-14*std::sqrt(70.0))), 1e-8f); assertEqualsEpsilon(nodes[4], (Float) ( 1/21.0 * std::sqrt(245+14*std::sqrt(70.0))), 1e-8f); assertEqualsEpsilon(weights[0], (Float) (1.0/900.0 * (322-13*std::sqrt(70.0))), 1e-8f); assertEqualsEpsilon(weights[1], (Float) (1.0/900.0 * (322+13*std::sqrt(70.0))), 1e-8f); assertEqualsEpsilon(weights[2], (Float) 128.0/225.0, 1e-8f); assertEqualsEpsilon(weights[3], (Float) (1.0/900.0 * (322+13*std::sqrt(70.0))), 1e-8f); assertEqualsEpsilon(weights[4], (Float) (1.0/900.0 * (322-13*std::sqrt(70.0))), 1e-8f); }
void test01_quad() { GaussLobattoIntegrator quad(1024, 0, 1e-5f); size_t evals; Float result = quad.integrate(boost::bind( &TestQuadrature::testF, this, _1), 0, 10, &evals); Float ref = 2 * std::pow(std::sin((Float) 5.0f), (Float) 2.0f); Log(EInfo, "test01_quad(): used " SIZE_T_FMT " function evaluations", evals); assertEqualsEpsilon(result, ref, 1e-5f); }
void test02_nD_01() { NDIntegrator quad(1, 1, 1024, 0, 1e-5f); Float min = 0, max = 10, result, err; size_t evals; assertTrue(quad.integrate(boost::bind( &TestQuadrature::testF2, this, _1, _2), &min, &max, &result, &err, &evals) == NDIntegrator::ESuccess); Float ref = 2 * std::pow(std::sin(5.0f), 2.0f); Log(EInfo, "test02_nD_01(): used " SIZE_T_FMT " function evaluations, " "error=%f", evals, err); assertEqualsEpsilon(result, ref, 1e-5f); }
void test04_gaussLegendre_even() { Float nodes[4], weights[4]; gaussLegendre(4, nodes, weights); assertEqualsEpsilon(nodes[0], (Float) (-1/35.0 * std::sqrt(525+70*std::sqrt(30.0))), 1e-8f); assertEqualsEpsilon(nodes[1], (Float) (-1/35.0 * std::sqrt(525-70*std::sqrt(30.0))), 1e-8f); assertEqualsEpsilon(nodes[2], (Float) ( 1/35.0 * std::sqrt(525-70*std::sqrt(30.0))), 1e-8f); assertEqualsEpsilon(nodes[3], (Float) ( 1/35.0 * std::sqrt(525+70*std::sqrt(30.0))), 1e-8f); assertEqualsEpsilon(weights[0], (Float) (1.0/36.0 * (18-std::sqrt(30.0))), 1e-8f); assertEqualsEpsilon(weights[1], (Float) (1.0/36.0 * (18+std::sqrt(30.0))), 1e-8f); assertEqualsEpsilon(weights[2], (Float) (1.0/36.0 * (18+std::sqrt(30.0))), 1e-8f); assertEqualsEpsilon(weights[3], (Float) (1.0/36.0 * (18-std::sqrt(30.0))), 1e-8f); }
void test04_sphere() { Properties props("sphere"); Float radius = 2.0f; props.setFloat("radius", radius); props.setPoint("center", Point(0.0f)); ref<Shape> sphere = static_cast<Shape *>(PluginManager::getInstance()->createObject(props)); sphere->configure(); ref<ShapeKDTree> kdtree = new ShapeKDTree(); kdtree->addShape(sphere); kdtree->build(); Ray ray(Point(3, 3, 3), normalize(Vector(-1, -1, -1)), 123.0f); Intersection its; assertTrue(kdtree->rayIntersect(ray, its)); assertEquals(its.time, 123.0f); assertEqualsEpsilon(its.p, Point(ray.d*-2.0f), Epsilon); assertEqualsEpsilon(its.wi, Vector(0, 0, 1), Epsilon); assertEqualsEpsilon(its.shFrame.n, -ray.d, Epsilon); assertTrue(its.shFrame == its.geoFrame); Point2 sc = toSphericalCoordinates(Vector(its.p)); std::swap(sc.x, sc.y); sc.x *= INV_TWOPI; sc.y *= INV_PI; assertEqualsEpsilon(its.uv, sc, Epsilon); // from mathematica assertEqualsEpsilon(its.dpdu, Vector(-3.6276f, 3.6276f, 0.0f)*radius, 1e-4f); assertEqualsEpsilon(its.dpdv, Vector(1.28255f, 1.28255f, -2.5651f)*radius, 1e-4f); Vector dndu, dndv; its.shape->getNormalDerivative(its, dndu, dndv, false); assertEqualsEpsilon(dndu, Vector(-3.6276f, 3.6276f, 0.0f), 1e-4f); assertEqualsEpsilon(dndv, Vector(1.28255f, 1.28255f, -2.5651f), 1e-4f); Float H, K; its.shape->getCurvature(its, H, K); assertEquals(K, 1.0f / (radius*radius)); assertEquals(H, -1.0f / radius); }
void test05_cylinder() { Properties props("cylinder"); Float radius = 2.0f; props.setFloat("radius", radius); props.setPoint("p0", Point(0.0f, 0.0f, -3.0f)); props.setPoint("p1", Point(0.0f, 0.0f, 3.0f)); ref<Shape> sphere = static_cast<Shape *>( PluginManager::getInstance()->createObject(props)); sphere->configure(); ref<ShapeKDTree> kdtree = new ShapeKDTree(); kdtree->addShape(sphere); kdtree->build(); Ray ray(Point(3.0f, 3.0f, 3.0f), normalize(Vector(-1, -1, -1)), 123.0f); Intersection its; assertTrue(kdtree->rayIntersect(ray, its)); Float t = 3*std::sqrt(3.0f)-std::sqrt(6.0f); assertEquals(its.time, 123.0f); assertEqualsEpsilon(its.p, ray(t), 1e-4f); assertEqualsEpsilon(its.t, t, 1e-4f); assertEqualsEpsilon(its.shFrame.n, normalize(Normal(1, 1, 0)), Epsilon); assertTrue(its.shFrame == its.geoFrame); assertEqualsEpsilon(its.uv.x, 1.0f / 8.0f, Epsilon); assertEqualsEpsilon(its.uv.y, (its.p.z+3)/6, Epsilon); // from mathematica assertEqualsEpsilon(its.dpdu, Vector(-8.88577, 8.88577, 0), 1e-4f); assertEqualsEpsilon(its.dpdv, Vector(0, 0, 6), 1e-4f); Vector dndu, dndv; its.shape->getNormalDerivative(its, dndu, dndv, false); assertEqualsEpsilon(dndu, Vector(-4.44288f, 4.44288f, 0.0f), 1e-4f); assertEqualsEpsilon(dndv, Vector(0.0f), 1e-4f); Float H, K; its.shape->getCurvature(its, H, K); assertEqualsEpsilon(K, 0.0f, Epsilon); assertEqualsEpsilon(H, -1.0f / (2*radius), Epsilon); }
void test06_gaussLobatto_even() { Float nodes[6], weights[6]; gaussLobatto(6, nodes, weights); assertEqualsEpsilon(nodes[0], -1.0f, 1e-8f); assertEqualsEpsilon(nodes[1], (Float) -std::sqrt(1/21.0 * (7+2*std::sqrt(7.0))), 1e-8f); assertEqualsEpsilon(nodes[2], (Float) -std::sqrt(1/21.0 * (7-2*std::sqrt(7.0))), 1e-8f); assertEqualsEpsilon(nodes[3], (Float) std::sqrt(1/21.0 * (7-2*std::sqrt(7.0))), 1e-8f); assertEqualsEpsilon(nodes[4], (Float) std::sqrt(1/21.0 * (7+2*std::sqrt(7.0))), 1e-8f); assertEqualsEpsilon(nodes[5], 1.0f, 1e-8f); assertEqualsEpsilon(weights[0], (Float) (1.0/15.0), 1e-8f); assertEqualsEpsilon(weights[1], (Float) ((14 - std::sqrt(7.0))/30.0), 1e-8f); assertEqualsEpsilon(weights[2], (Float) ((14 + std::sqrt(7.0))/30.0), 1e-8f); assertEqualsEpsilon(weights[3], (Float) ((14 + std::sqrt(7.0))/30.0), 1e-8f); assertEqualsEpsilon(weights[4], (Float) ((14 - std::sqrt(7.0))/30.0), 1e-8f); assertEqualsEpsilon(weights[5], (Float) (1.0/15.0), 1e-8f); }