public Cone(Transform o2w, Transform w2o, bool ro, float height, float rad, float tm) : base(o2w, w2o, ro) { Radius = rad; Height = height; PhiMax = MathHelper.ToRadians(MathHelper.Clamp(tm, 0, 360.0f)); }
public Quaternion(Transform t) { Matrix4x4 m = t.Matrix; float trace = m[0, 0] + m[1, 1] + m[2, 2]; if (trace > 0.0f) { float s = MathHelper.Sqrt(trace + 1.0f); _w = s / 2.0f; s = 0.5f / s; _x = (m[2, 1] - m[1, 2]) * s; _y = (m[0, 2] - m[2, 0]) * s; _z = (m[1, 0] - m[0, 1]) * s; } else { int[] nxt = { 1, 2, 0 }; float[] q = new float[3]; int i = 0; if (m[1, 1] > m[0, 0]) i = 1; if (m[2, 2] > m[i, i]) i = 2; int j = nxt[i]; int k = nxt[j]; float s = MathHelper.Sqrt((m[i, i] - (m[j, j] + m[k, k])) + 1.0f); q[i] = s * 0.5f; if (s != 0.0f) s = 0.5f / s; _w = (m[k, j] - m[j, k]) * s; q[j] = (m[j, i] + m[i, j]) * s; q[k] = (m[k, i] + m[i, k]) * s; _x = q[0]; _y = q[1]; _z = q[2]; } }
public TriangleMesh(Transform o2w, Transform w2o, bool ro, int nt, int nv, int[] vi, Point[] P, Normal[] N, Vector[] S, float[] uv, Texture<float> atex) : base(o2w, w2o, ro) { alphaTexture = atex; ntris = nt; nverts = nv; MathHelper.Copy<int>(ref vertexIndex, ref vi); if (uv != null) { MathHelper.Copy<float>(ref uvs, ref uv); } else uvs = null; if (N != null) { MathHelper.Copy<Normal>(ref n, ref N); } else n = null; if (S != null) { MathHelper.Copy<Vector>(ref s, ref S); } else s = null; for (int i = 0; i < nverts; ++i) p[i] = (ObjectToWorld)[P[i]]; }
public Paraboloid(Transform o2w, Transform w2o, bool ro, float rad, float z0, float z1, float tm) : base(o2w, w2o, ro) { Radius = rad; ZMin = z0; ZMax = z1; PhiMax = MathHelper.ToRadians(MathHelper.Clamp(tm, 0, 360)); }
public Shape(Transform o2w, Transform w2o, bool ro) { otw = o2w; wto = w2o; RO = ro; tsh = o2w.SwitchHandedness(); shapeId = NextShapeId++; }
public Disk(Transform o2w, Transform w2o, bool ro, float ht, float r, float ri, float tmax) : base(o2w, w2o, ro) { Height = ht; InnerRadius = ri; Radius = r; PhiMax = MathHelper.ToRadians(MathHelper.Clamp(tmax, 0, 360f)); }
public Cylinder(Transform o2w, Transform w2o, bool ro, float rad, float z0, float z1, float pm) : base(o2w, w2o, ro) { Radius = rad; ZMin = MathHelper.Min(z0, z1); ZMax = MathHelper.Max(z0, z1); PhiMax = MathHelper.ToRadians(MathHelper.Clamp(pm, 0.0f, 360.0f)); }
public Triangle(Transform o2w, Transform w2o, bool ro, TriangleMesh m, int n) : base(o2w, w2o, ro) { mesh = m; int i = 3 * n; v[0] = mesh.vertexIndex[i]; v[1] = mesh.vertexIndex[i+1]; v[2] = mesh.vertexIndex[i+2]; }
public Sphere(Transform o2w, Transform w2o, bool ro, float rad, float z0, float z1, float pm) : base(o2w, w2o, ro) { Radius = rad; zmin = MathHelper.Clamp(MathHelper.Min(z0, z1), -Radius, Radius); zmax = MathHelper.Clamp(MathHelper.Max(z0, z1), -Radius, Radius); thetaMin = MathHelper.Acos(MathHelper.Clamp(zmin / Radius, -1.0f, 1.0f)); thetaMax = MathHelper.Acos(MathHelper.Clamp(zmax / Radius, -1.0f, 1.0f)); phiMax = MathHelper.ToRadians(MathHelper.Clamp(pm, 0.0f, 360.0f)); }
public Hyperboloid(Transform o2w, Transform w2o, bool ro, Point point1, Point point2, float tm) : base(o2w, w2o, ro) { p1 = point1; p2 = point2; phiMax = MathHelper.ToRadians(MathHelper.Clamp(tm, 0.0f, 360.0f)); float radius1 = MathHelper.Sqrt(p1.X * p1.X + p1.Y * p1.Y); float radius2 = MathHelper.Sqrt(p2.X * p2.X + p2.Y * p2.Y); rmax = MathHelper.Max(radius1, radius2); zmin = MathHelper.Min(p1.Z, p2.Z); zmax = MathHelper.Max(p1.Z, p2.Z); if (p2.Z == 0) MathHelper.Swap<Point>(ref p1, ref p2); Point pp = p1; float xy1, xy2; do { pp += 2.0f * (p2 - p1); xy1 = pp.X * pp.X + pp.Y * pp.Y; xy2 = p2.X * p2.X + p2.Y * p2.Y; a = (1.0f / 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 (float.IsInfinity(a) || float.IsNaN(a)); }
public static Transform Transpose(Transform t) { t.Transpose(); return t; }
public static Transform Inverse(Transform t) { t.Inverse(); return t; }
public Vector this[float time, Vector v] { get { if (!actuallyAnimated || time <= startTime) return (startTransform)[v]; else if (time >= endTime) return (endTransform)[v]; Transform t = new Transform(); Interpolate(time, t); return t[v]; } }
public Point this[float time, Point p] { get { if (!actuallyAnimated || time <= startTime) return (startTransform)[p]; else if (time >= endTime) return (endTransform)[p]; Transform t = new Transform(); Interpolate(time, t); return t[p]; } }
public LoopSubDiv(Transform o2w, Transform w2o, bool ro, int nfaces, int nvertices, int[] vi, Point[] P, int nl) : base(o2w, w2o, ro) { nLevels = nl; int i; Pointer<SDVertex> verts = Pointer<SDVertex>.Allocate(nvertices); for (i = 0; i < nvertices; ++i) { verts[i] = new SDVertex(P[i]); vertices.Add((verts + i)); } Pointer<SDFace> fs = Pointer<SDFace>.Allocate(nfaces); for (i = 0; i < nfaces; ++i) { faces.Add((fs + i)); } int c = 0; for (i = 0; i < nfaces; ++i) { Pointer<SDFace> f = faces[i]; for (int j = 0; j < 3; j++) { Pointer<SDVertex> v = vertices[vi[c + j]]; f[0].v[j] = v; v[0].SetStartFace(f); } c += 3; } List<SDEdge> edges = new List<SDEdge>(); for (i = 0; i < nfaces; ++i) { Pointer<SDFace> f = faces[i]; for (int edgeNum = 0; edgeNum < 3; ++edgeNum) { int v0 = edgeNum, v1 = NEXT(edgeNum); SDEdge e = new SDEdge(f[0].v[v0], f[0].v[v1]); if (edges.IndexOf(e) == edges.Count - 1) { e.f[0] = f; e.f0edgeNum = edgeNum; edges.Add(e); } else { e = edges[edges.IndexOf(e)]; e.f[0][0].f[e.f0edgeNum] = f; f[0].f[edgeNum] = e.f[0]; edges.Remove(e); } } } }
public BBox MotionBounds(BBox b, bool useInverse) { if (!actuallyAnimated) return Transform.Inverse(startTransform)[b]; BBox ret = new BBox(); int nSteps = 128; for (int i = 0; i < nSteps; ++i) { Transform t = new Transform(); float time = MathHelper.Lerp(((float)i) / ((float)nSteps - 1), startTime, endTime); Interpolate(time, t); if (useInverse) t = Transform.Inverse(t); ret = BBox.Union(ret, t[b]); } return ret; }
public AnimatedTransform(Transform t1, float time1, Transform t2, float time2) { startTime = time1; endTime = time2; startTransform = t1; endTransform = t2; actuallyAnimated = t1 != t2; Decompose(startTransform.Matrix, out T[0], out R[0], out S[0]); Decompose(startTransform.Matrix, out T[1], out R[1], out S[1]); }
public virtual void GetShadingGeometry(Transform obj2world, DifferentialGeometry dg, Pointer<DifferentialGeometry> dgShading) { dgShading[0] = dg; }
public RayDifferential this[RayDifferential r] { get { RayDifferential tr = new RayDifferential(); if (!actuallyAnimated || r.Time <= startTime) tr = (startTransform)[r]; else if (r.Time >= endTime) tr = (endTransform)[r]; else { Transform t = new Transform(); Interpolate(r.Time, t); tr = t[r]; } tr.Time = r.Time; return tr; } }
public void Interpolate(float time, Transform t) { if (!actuallyAnimated || time <= startTime) { t = startTransform; return; } if (time >= endTime) { t = endTransform; return; } float dt = (time - startTime) / (endTime - startTime); Vector trans = (1.0f - dt) * T[0] + dt * T[1]; Quaternion rotate = Quaternion.Slerp(dt, R[0], R[1]); Matrix4x4 scale = new Matrix4x4(); for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) scale[i, j] = MathHelper.Lerp(dt, S[0][i, j], S[1][i, j]); t = Transform.Translate(trans) * rotate.ToTransform() * new Transform(scale); }
public override void GetShadingGeometry(Transform obj2world, DifferentialGeometry dg, Pointer<DifferentialGeometry> dgShading) { if (mesh.n == null && mesh.s == null) { dgShading[0] = dg; return; } float[] b = new float[3]; float[][] uv = new float[3][]; uv[0] = new float[2]; uv[1] = new float[2]; uv[2] = new float[2]; GetUVs(uv); float[][] A = { new float[2] { uv[1][0] - uv[0][0], uv[2][0] - uv[0][0] }, new float[2] { uv[1][1] - uv[0][1], uv[2][1] - uv[0][1] } }; float[] C = { dg.u - uv[0][0], dg.v - uv[0][1] }; if (!Transform.SolveLinearSystem2x2(A, C, ref b[1], ref b[2])) { b[0] = b[1] = b[2] = 1.0f / 3.0f; } else b[0] = 1.0f - b[1] - b[2]; Normal ns; Vector ss, ts; if (mesh.n != null) ns = Normal.Normalize(obj2world[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 = Vector.Normalize(obj2world[b[0] * mesh.s[v[0]] + b[1] * mesh.s[v[1]] + b[2] * mesh.s[v[2]]]); else ss = Vector.Normalize(dg.dpdu); ts = Vector.Cross(ss, ns); if (ts.SquaredMagnitude > 0.0f) { ts = Vector.Normalize(ts); ss = Vector.Cross(ts, ns); } else Extensions.CoordinateSystem((Vector)ns, out ss, out ts); Normal dndu, dndv; if (mesh.n != null) { float[][] uvs = new float[3][]; uvs[0] = new float[2]; uvs[1] = new float[2]; uvs[2] = new float[2]; GetUVs(uvs); float du1 = uvs[0][0] - uvs[2][0]; float du2 = uvs[1][0] - uvs[2][0]; float dv1 = uvs[0][1] - uvs[2][1]; float 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]]; float determinant = du1 * dv2 - dv1 * du2; if (determinant == 0.0f) dndu = dndv = new Normal(0, 0, 0); else { float invdet = 1.0f / determinant; dndu = ((dv2 * dn1 - dv1 * dn2) * invdet); dndv = ((-du2 * dn1 + du1 * dn2) * invdet); } } else dndu = dndv = new Normal(0, 0, 0); dgShading[0] = new DifferentialGeometry(dg.p, ss, ts, (ObjectToWorld)[dndu], (ObjectToWorld)[dndv], dg.u, dg.v, dg.shape); dgShading[0].Setdudx(dg.dudx); dgShading[0].Setdvdx(dg.dvdx); dgShading[0].Setdudy(dg.dudy); dgShading[0].Setdvdy(dg.dvdy); dgShading[0].Setdpdx(dg.dpdx); dgShading[0].Setdpdy(dg.dpdy); }