public Cone(Transform o2w, Transform w2o, bool ro, double ht, double rad, double tm) : base(o2w, w2o, ro) { radius = rad; height = ht; phiMax = Utility.Radians(Utility.Clamp(tm, 0.0d, 360.0d)); }
public static Cone CreateConeShape(Transform o2w, Transform w2o, bool reverseOrientation, ParamSet parameters) { double radius = parameters.FindOneDouble("radius", 1); double height = parameters.FindOneDouble("height", 1); double phimax = parameters.FindOneDouble("phimax", 360); return new Cone(o2w, w2o, reverseOrientation, height, radius, phimax); }
public static Hyperboloid CreateHyperboloidShape(Transform o2w, Transform w2o, bool reverseOrientation, ParamSet parameters) { Point p1 = parameters.FindOnePoint("p1", new Point(0, 0, 0)); Point p2 = parameters.FindOnePoint("p2", new Point(1, 1, 1)); double phimax = parameters.FindOneDouble("phimax", 360); return new Hyperboloid(o2w, w2o, reverseOrientation, p1, p2, phimax); }
public Hyperboloid(Transform o2w, Transform w2o, bool ro, Point point1, Point point2, double tm) : base(o2w, w2o, ro) { p1 = point1; p2 = point2; phiMax = Utility.Radians(Utility.Clamp(tm, 0.0d, 360.0d)); double radius1 = Math.Sqrt(p1.x * p1.x + p1.y * p1.y); double radius2 = Math.Sqrt(p2.x * p2.x + p2.y * p2.y); rmax = Math.Max(radius1, radius2); zmin = Math.Min(p1.z, p2.z); zmax = Math.Max(p1.z, p2.z); // Compute implicit function coefficients for hyperboloid if (p2.z == 0.0d) Utility.Swap<Point>(ref p1, ref p2); Point pp = p1; double xy1, xy2; do { pp += 2.0d * (p2 - p1); xy1 = pp.x * pp.x + pp.y * pp.y; xy2 = p2.x * p2.x + p2.y * p2.y; a = (1.0d / xy1 - (pp.z * pp.z) / (xy1 * p2.z * p2.z)) / (1 - (xy2 * pp.z * pp.z) / (xy1 * p2.z * p2.z)); c = (a * xy2 - 1) / (p2.z * p2.z); } while (Double.IsInfinity(a) || Double.IsNaN(a)); }
public static Disk CreateDiskShape(Transform o2w, Transform w2o, bool reverseOrientation, ParamSet parameters) { double height = parameters.FindOneDouble("height", 0.0d); double radius = parameters.FindOneDouble("radius", 1); double inner_radius = parameters.FindOneDouble("innerradius", 0); double phimax = parameters.FindOneDouble("phimax", 360); return new Disk(o2w, w2o, reverseOrientation, height, radius, inner_radius, phimax); }
public Shape(Transform o2w, Transform w2o, bool ro) { this.ObjectToWorld = o2w; this.WorldToObject = w2o; this.ReverseOrientation = ro; this.TransformSwapsHandedness = o2w.SwapsHandedness(); this.shapeId = nextshapeId++; }
public static Sphere CreateSphereShape(Transform o2w, Transform w2o, bool reverseOrientation, ParamSet parameters) { double radius = parameters.FindOneDouble("radius", 1.0d); double zmin = parameters.FindOneDouble("zmin", -radius); double zmax = parameters.FindOneDouble("zmax", radius); double phimax = parameters.FindOneDouble("phimax", 360.0d); return new Sphere(o2w, w2o, reverseOrientation, radius, zmin, zmax, phimax); }
public Paraboloid(Transform o2w, Transform w2o, bool ro, double rad, double z0, double z1, double tm) : base(o2w, w2o, ro) { radius = rad; zmin = Math.Min(z0, z1); zmax = Math.Max(z0, z1); phiMax = Utility.Radians(Utility.Clamp(tm, 0.0d, 360.0d)); }
public Disk(Transform o2w, Transform w2o, bool ro, double ht, double r, double ri, double tmax) : base(o2w, w2o, ro) { height = ht; radius = r; innerRadius = ri; phiMax = Utility.Radians(Utility.Clamp(tmax, 0.0d, 360.0d)); }
public static Paraboloid CreateParaboloidShape(Transform o2w, Transform w2o, bool reverseOrientation, ParamSet parameters) { double radius = parameters.FindOneDouble("radius", 1); double zmin = parameters.FindOneDouble("zmin", 0); double zmax = parameters.FindOneDouble("zmax", 1); double phimax = parameters.FindOneDouble("phimax", 360); return new Paraboloid(o2w, w2o, reverseOrientation, radius, zmin, zmax, phimax); }
public Triangle(Transform o2w, Transform w2o, bool ro, TriangleMesh m, int n) : base(o2w, w2o, ro) { mesh = m; v = new int[3]; for (int i = 0; i < 3; i++) { v[i] = mesh.vertexIndex[3 * n + i]; } }
public Sphere(Transform o2w, Transform w2o, bool ro, double rad, double z0, double z1, double pm) : base(o2w, w2o, ro) { radius = rad; zmin = Utility.Clamp(Math.Min(z0, z1), -radius, radius); zmax = Utility.Clamp(Math.Max(z0, z1), -radius, radius); thetaMin = Math.Acos(Utility.Clamp(zmin / radius, -1.0d, 1.0d)); thetaMax = Math.Acos(Utility.Clamp(zmax / radius, -1.0d, 1.0d)); phiMax = Utility.Radians(Utility.Clamp(pm, 0.0f, 360.0f)); }
public TriangleMesh(Transform o2w, Transform w2o, bool ro, int nt, int nv, int[] vi, Point[] P, Normal[] N, Vector[] S, double[] uv, Texture<double> atex) : base(o2w, w2o, ro) { alphaTexture = atex; ntris = nt; nverts = nv; vertexIndex = new int[ntris * 3]; Array.Copy(vi, 0, vertexIndex, 0, ntris * 3); // Copy _uv_, _N_, and _S_ vertex data, if present if (uv != null) { uvs = new double[2 * nverts]; Array.Copy(uv, 0, uvs, 0, 2 * nverts); } else { uvs = null; } p = new Point[nverts]; if (N != null) { n = new Normal[nverts]; Array.Copy(N, 0, n, 0, nverts); } else { n = null; } if (S != null) { s = new Vector[nverts]; Array.Copy(S, 0, s, 0, nverts); } else { s = null; } // Transform mesh vertices to world space for (int i = 0; i < nverts; ++i) { p[i] = ObjectToWorld.Apply(P[i]); } }
public Quaternion(Transform t) { Matrix4x4 m = t.M; double trace = m.m[0, 0] + m.m[1, 1] + m.m[2, 2]; if (trace > 0.0d) { // Compute w from matrix trace, then xyz // 4w^2 = m[0,0] + m[1,1] + m[2,2] + m[3,3] (but m[3,3] == 1) double s = Math.Sqrt(trace + 1.0d); w = s / 2.0d; s = 0.5f / s; v.x = (m.m[2, 1] - m.m[1, 2]) * s; v.y = (m.m[0, 2] - m.m[2, 0]) * s; v.z = (m.m[1, 0] - m.m[0, 1]) * s; } else { // Compute largest of $x$, $y$, or $z$, then remaining components int[] nxt = { 1, 2, 0 }; double[] q = new double[3]; int i = 0; if (m.m[1, 1] > m.m[0, 0]) i = 1; if (m.m[2, 2] > m.m[i, i]) i = 2; int j = nxt[i]; int k = nxt[j]; double s = Math.Sqrt((m.m[i, i] - (m.m[j, j] + m.m[k, k])) + 1.0); q[i] = s * 0.5f; if (s != 0.0d) s = 0.5f / s; w = (m.m[k, j] - m.m[j, k]) * s; q[j] = (m.m[j, i] + m.m[i, j]) * s; q[k] = (m.m[k, i] + m.m[i, k]) * s; v.x = q[0]; v.y = q[1]; v.z = q[2]; } }
public virtual void GetShadingGeometry(Transform obj2world, DifferentialGeometry dg, out DifferentialGeometry dgShading) { dgShading = dg; }
public override BSSRDF GetBSSRDF(DifferentialGeometry dg, Transform ObjectToWorld) { DifferentialGeometry dgs; shape.GetShadingGeometry(ObjectToWorld, dg, out dgs); return material.GetBSSRDF(dg, dgs); }
public override BSSRDF GetBSSRDF(DifferentialGeometry dg, Transform ObjectToWorld) { throw new NotImplementedException(); }
public override void GetShadingGeometry(Transform obj2world, DifferentialGeometry dg, out DifferentialGeometry dgShading) { if (mesh.n == null && mesh.s == null) { dgShading = dg; return; } // Initialize _Triangle_ shading geometry with _n_ and _s_ // Compute barycentric coordinates for point double[] b = new double[3]; // Initialize _A_ and _C_ matrices for barycentrics double[,] uv = new double[3, 2]; GetUVs(uv); double[,] A = { { uv[1,0] - uv[0,0], uv[2,0] - uv[0,0] }, { uv[1,1] - uv[0,1], uv[2,1] - uv[0,1] } }; double[] C = { dg.u - uv[0, 0], dg.v - uv[0, 1] }; if (!Utility.SolveLinearSystem2x2(A, C, out b[1], out b[2])) { // Handle degenerate parametric mapping b[0] = b[1] = b[2] = 1.0f / 3.0f; } else b[0] = 1.0d - b[1] - b[2]; // Use _n_ and _s_ to compute shading tangents for triangle, _ss_ and _ts_ Normal ns; Vector ss, ts; if (mesh.n != null) ns = Geometry.Normalize(obj2world.Apply(b[0] * mesh.n[v[0]] + b[1] * mesh.n[v[1]] + b[2] * mesh.n[v[2]])); else ns = dg.nn; if (mesh.s != null) ss = Geometry.Normalize(obj2world.Apply(b[0] * mesh.s[v[0]] + b[1] * mesh.s[v[1]] + b[2] * mesh.s[v[2]])); else ss = Geometry.Normalize(dg.dpdu); ts = Geometry.Cross(ss, ns); if (ts.LengthSquared() > 0.0d) { ts = Geometry.Normalize(ts); ss = Geometry.Cross(ts, ns); } else Geometry.CoordinateSystem(new Vector(ns), out ss, out ts); Normal dndu, dndv; // Compute $\dndu$ and $\dndv$ for triangle shading geometry if (mesh.n != null) { double[,] uvs = new double[3, 2]; GetUVs(uvs); // Compute deltas for triangle partial derivatives of normal double du1 = uvs[0, 0] - uvs[2, 0]; double du2 = uvs[1, 0] - uvs[2, 0]; double dv1 = uvs[0, 1] - uvs[2, 1]; double dv2 = uvs[1, 1] - uvs[2, 1]; Normal dn1 = mesh.n[v[0]] - mesh.n[v[2]]; Normal dn2 = mesh.n[v[1]] - mesh.n[v[2]]; double determinant = du1 * dv2 - dv1 * du2; if (determinant == 0.0d) dndu = dndv = new Normal(0, 0, 0); else { double invdet = 1.0d / determinant; dndu = (dv2 * dn1 - dv1 * dn2) * invdet; dndv = (-du2 * dn1 + du1 * dn2) * invdet; } } else dndu = dndv = new Normal(0, 0, 0); dgShading = new DifferentialGeometry(dg.p, ss, ts, ObjectToWorld.Apply(dndu), ObjectToWorld.Apply(dndv), dg.u, dg.v, dg.shape); dgShading.dudx = dg.dudx; dgShading.dvdx = dg.dvdx; dgShading.dudy = dg.dudy; dgShading.dvdy = dg.dvdy; dgShading.dpdx = dg.dpdx; dgShading.dpdy = dg.dpdy; }
public static TriangleMesh CreateTriangleMeshShape(Transform o2w, Transform w2o, bool reverseOrientation, ParamSet parameters, Dictionary<string, Texture<double>> floatTextures) { throw new NotImplementedException(); //int nvi, npi, nuvi, nsi, nni; //const int *vi = parameters.FindInt("indices", &nvi); //const Point *P = parameters.FindPoint("P", &npi); //const double *uvs = parameters.FindFloat("uv", &nuvi); //if (!uvs) uvs = parameters.FindFloat("st", &nuvi); //bool discardDegnerateUVs = parameters.FindOneBool("discarddegenerateUVs", false); //// XXX should complain if uvs aren't an array of 2... //if (uvs) { // if (nuvi < 2 * npi) { // Error("Not enough of \"uv\"s for triangle mesh. Expencted %d, " // "found %d. Discarding.", 2*npi, nuvi); // uvs = NULL; // } // else if (nuvi > 2 * npi) // Warning("More \"uv\"s provided than will be used for triangle " // "mesh. (%d expcted, %d found)", 2*npi, nuvi); //} //if (!vi || !P) return NULL; //const Vector *S = parameters.FindVector("S", &nsi); //if (S && nsi != npi) { // Error("Number of \"S\"s for triangle mesh must match \"P\"s"); // S = NULL; //} //const Normal *N = parameters.FindNormal("N", &nni); //if (N && nni != npi) { // Error("Number of \"N\"s for triangle mesh must match \"P\"s"); // N = NULL; //} //if (discardDegnerateUVs && uvs && N) { // // if there are normals, check for bad uv's that // // give degenerate mappings; discard them if so // const int *vp = vi; // for (int i = 0; i < nvi; i += 3, vp += 3) { // double area = .5f * Cross(P[vp[0]]-P[vp[1]], P[vp[2]]-P[vp[1]]).Length(); // if (area < 1e-7) continue; // ignore degenerate tris. // if ((uvs[2*vp[0]] == uvs[2*vp[1]] && // uvs[2*vp[0]+1] == uvs[2*vp[1]+1]) || // (uvs[2*vp[1]] == uvs[2*vp[2]] && // uvs[2*vp[1]+1] == uvs[2*vp[2]+1]) || // (uvs[2*vp[2]] == uvs[2*vp[0]] && // uvs[2*vp[2]+1] == uvs[2*vp[0]+1])) { // Warning("Degenerate uv coordinates in triangle mesh. Discarding all uvs."); // uvs = NULL; // break; // } // } //} //for (int i = 0; i < nvi; ++i) // if (vi[i] >= npi) { // Error("trianglemesh has out of-bounds vertex index %d (%d \"P\" values were given", // vi[i], npi); // return NULL; // } //Reference<Texture<double> > alphaTex = NULL; //string alphaTexName = params.FindTexture("alpha"); //if (alphaTexName != "") { // if (floatTextures->find(alphaTexName) != floatTextures->end()) // alphaTex = (*floatTextures)[alphaTexName]; // else // Error("Couldn't find double texture \"%s\" for \"alpha\" parameter", // alphaTexName.c_str()); //} //else if (params.FindOneFloat("alpha", 1.f) == 0.f) // alphaTex = new ConstantTexture<double>(0.f); //return new TriangleMesh(o2w, w2o, reverseOrientation, nvi/3, npi, vi, P, // N, S, uvs, alphaTex); }
public virtual Transform Transpose(Transform t) { return new Transform(Transpose(t.m), Transpose(t.mInv)); }
public abstract BSSRDF GetBSSRDF(DifferentialGeometry dg, Transform ObjectToWorld);
internal void Interpolate(double p, out Transform w2p) { throw new NotImplementedException(); }
public virtual Transform Inverse(Transform t) { return new Transform(t.mInv, t.m); }