public bool HasScale() { float la2 = new Vector(1, 0, 0).SquaredMagnitude; float lb2 = new Vector(0, 1, 0).SquaredMagnitude; float lc2 = new Vector(0, 0, 1).SquaredMagnitude; return ((la2 < 0.999f || la2 > 1.001f) || (lb2 < 0.999f || lb2 > 1.001f) || (lc2 < 0.999f || lc2 > 1.001f)); }
public static Vector UniformSampleCone(float u1, float u2, float costhetamax, Vector x, Vector y, Vector z) { float costheta = MathHelper.Lerp(u1, costhetamax, 1.0f); float sintheta = MathHelper.Sqrt(1.0f - costheta * costheta); float phi = u2 * 2.0f * MathHelper.PI; return MathHelper.Cos(phi) * sintheta * x + MathHelper.Sin(phi) * sintheta * y + costheta * z; }
public override bool Intersect(Ray r, Pointer<float> tHit, Pointer<float> rayEpsilon, Pointer<DifferentialGeometry> dg) { Ray ray = (WorldToObject)[r]; if (MathHelper.Abs(ray.Direction.Z) < 1e-7) return false; float thit = (Height - ray.Origin.Z) / ray.Direction.Z; if (thit < ray.MinT || thit > ray.MaxT) return false; Point phit = ray[thit]; float dist2 = phit.X * phit.X + phit.Y * phit.Y; if (dist2 > Radius * Radius || dist2 < InnerRadius * InnerRadius) return false; float phi = MathHelper.Atan2(phit.Y, phit.X); if (phi < 0) phi += 2.0f * MathHelper.PI; if (phi > PhiMax) return false; float u = phi / PhiMax; float oneMinusV = ((MathHelper.Sqrt(dist2) - InnerRadius) / (Radius - InnerRadius)); float invOneMinusV = (oneMinusV > 0.0f) ? (1.0f / oneMinusV) : 0.0f; float v = 1.0f - oneMinusV; Vector dpdu = new Vector(-PhiMax * phit.Y, PhiMax * phit.X, 0); Vector dpdv = new Vector(-phit.X * invOneMinusV, -phit.Y * invOneMinusV, 0); dpdu *= PhiMax * MathHelper.InvTwoPI; dpdv *= (Radius - InnerRadius) / Radius; Normal dndu = new Normal(0, 0, 0), dndv = new Normal(0, 0, 0); Transform o2w = ObjectToWorld; dg[0] = new DifferentialGeometry(o2w[phit], o2w[dpdu], o2w[dpdv], o2w[dndu], o2w[dndv], u, v, this); tHit[0] = thit; rayEpsilon[0] = 5e-4f * ~tHit; return true; }
public void ScaleDifferentials(float s) { RXOrigin = Origin + (RXOrigin - Origin) * s; RYOrigin = Origin + (RYOrigin - Origin) * s; RXDirection = Direction + (Vector)(RXDirection - Origin) * s; RYDirection = Direction + (Vector)(RYDirection - Origin) * s; }
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 Ray(Point orig, Vector dir, float start, float end = float.MaxValue, float t = 0, int d = 0) { Origin = orig; Direction = dir; MinT = start; MaxT = end; Time = t; Depth = d; }
public Ray(Point orig, Vector dir, Ray parent, float start, float end = float.MaxValue) { Origin = orig; Direction = dir; MinT = start; MaxT = end; Time = parent.Time; Depth = parent.Depth + 1; }
public override bool Intersect(Ray r, Pointer<float> tHit, Pointer<float> rayEpsilon, Pointer<DifferentialGeometry> dg) { float phi; Point phit; Ray ray = (WorldToObject)[r]; float A = ray.Direction.X * ray.Direction.X + ray.Direction.Y * ray.Direction.Y; float B = 2 * (ray.Direction.X * ray.Origin.X + ray.Direction.Y * ray.Origin.Y); float C = ray.Origin.X * ray.Origin.X + ray.Origin.Y * ray.Origin.Y - Radius * Radius; float t0 = 0, t1 = 0; if (!MathHelper.Quadratic(A, B, C, ref t0, ref t1)) return false; if (t0 > ray.MaxT || t1 < ray.MinT) return false; float thit = t0; if (t0 < ray.MinT) { thit = t1; if (thit > ray.MaxT) return false; } phit = ray[thit]; phi = MathHelper.Atan2(phit.Y, phit.X); if (phi < 0) phi += 2.0f * MathHelper.PI; if (phit.Z < ZMin || phit.Z > ZMax || phi > PhiMax) { if (thit == t1) return false; thit = t1; if (t1 > ray.MaxT) return false; phit = ray[thit]; phi = MathHelper.Atan2(phit.Y, phit.X); if (phi < 0) phi += 2.0f * MathHelper.PI; if (phit.Z < ZMin || phit.Z > ZMax || phi > PhiMax) return false; } float u = phi / PhiMax; float v = (phit.Z - ZMin) / (ZMax - ZMin); Vector dpdu = new Vector(-PhiMax * phit.Y, PhiMax * phit.X, 0); Vector dpdv = new Vector(0, 0, ZMax - ZMin); Vector d2Pduu = -PhiMax * PhiMax * new Vector(phit.X, phit.Y, 0); Vector d2Pduv = new Vector(0, 0, 0), d2Pdvv = new Vector(0, 0, 0); float E = Vector.Dot(dpdu, dpdu); float F = Vector.Dot(dpdu, dpdv); float G = Vector.Dot(dpdv, dpdv); Vector N = Vector.Normalize(Vector.Cross(dpdu, dpdv)); float e = Vector.Dot(N, d2Pduu); float f = Vector.Dot(N, d2Pduv); float g = Vector.Dot(N, d2Pdvv); float invEGF2 = 1.0f / (E * G - F * F); Normal dndu = new Normal((f * F - e * G) * invEGF2 * dpdu + (e * F - f * E) * invEGF2 * dpdv); Normal dndv = new Normal((g * F - f * G) * invEGF2 * dpdu + (f * F - g * E) * invEGF2 * dpdv); Transform o2w = ObjectToWorld; dg[0] = new DifferentialGeometry(o2w[phit], o2w[dpdu], o2w[dpdv], o2w[dndu], o2w[dndv], u, v, this); tHit[0] = thit; rayEpsilon[0] = 5e-4f * ~tHit; return true; }
public virtual float Pdf(Point p, Vector wi) { Pointer<DifferentialGeometry> dgLight = new Pointer<DifferentialGeometry>(new DifferentialGeometry()); Ray ray = new Ray(p, wi, 1e-3f); ray.Depth = -1; Pointer<float> thit = (Pointer<float>)0, rayEpsilon = (Pointer<float>)0; if (!Intersect(ray, thit, rayEpsilon, dgLight)) return 0.0f; float pdf = (Point.DistanceSquared(p, ray[thit])) / (Vector.AbsDot((Vector)(~dgLight).nn, -1.0f * wi) * Area); if (float.IsInfinity(pdf)) pdf = 0.0f; return pdf; }
public static void CoordinateSystem(Vector v1, out Vector v2, out Vector v3) { if (MathHelper.Abs(v1.X) > MathHelper.Abs(v1.Y)) { float invLen = 1.0f / MathHelper.Sqrt(v1.X * v1.X + v1.Z * v1.Z); v2 = new Vector(-v1.Z * invLen, 0.0f, v1.X * invLen); } else { float invLen = 1.0f / MathHelper.Sqrt(v1.Y * v1.Y + v1.Z * v1.Z); v2 = new Vector(0.0f, v1.Z * invLen, -v1.Y * invLen); } v3 = Vector.Cross(v1, v2); }
public static Transform Translate(Vector delta) { Matrix4x4 m = new Matrix4x4(new float[4, 4]{ {1,0,0,delta.X}, {0,1,0,delta.Y}, {0,0,1,delta.Z}, {0,0,0,1}}); Matrix4x4 minv = new Matrix4x4(new float[4, 4]{ {1,0,0,-delta.X}, {0,1,0,-delta.Y}, {0,0,1,-delta.Z}, {0,0,0,1}}); return new Transform(m, minv); }
public static float Dot(Vector vector1, Vector vector2) { return vector1.Dot(vector2); }
public override bool Intersect(Ray r, Pointer<float> tHit, Pointer<float> rayEpsilon, Pointer<DifferentialGeometry> dg) { float phi, v; Point phit; Ray ray = (WorldToObject)[r]; float A = a * ray.Direction.X * ray.Direction.X + a * ray.Direction.Y * ray.Direction.Y - c * ray.Direction.Z * ray.Direction.Z; float B = 2.0f * (a * ray.Direction.X * ray.Origin.X + a * ray.Direction.Y * ray.Origin.Y - c * ray.Direction.Z * ray.Origin.Z); float C = a * ray.Origin.X * ray.Origin.X + a * ray.Origin.Y * ray.Origin.Y - c * ray.Origin.Z * ray.Origin.Z - 1; float t0 = 0, t1 = 0; if (!MathHelper.Quadratic(A, B, C, ref t0, ref t1)) return false; if (t0 > ray.MaxT || t1 < ray.MinT) return false; float thit = t0; if (t0 < ray.MinT) { thit = t1; if (thit > ray.MaxT) return false; } phit = ray[thit]; v = (phit.Z - p1.Z) / (p2.Z - p1.Z); Point pr = (1.0f - v) * p1 + v * p2; phi = MathHelper.Atan2(pr.X * phit.Y - phit.X * pr.Y, phit.X * pr.X + phit.Y * pr.Y); if (phi < 0) phi += 2 * MathHelper.PI; if (phit.Z < zmin || phit.Z > zmax || phi > phiMax) { if (thit == t1) return false; thit = t1; if (t1 > ray.MaxT) return false; phit = ray[thit]; v = (phit.Z - p1.Z) / (p2.Z - p1.Z); Point pr2 = (1.0f - v) * p1 + v * p2; phi = MathHelper.Atan2(pr2.X * phit.Y - phit.X * pr2.Y, phit.X * pr2.X + phit.Y * pr2.Y); if (phi < 0) phi += 2 * MathHelper.PI; if (phit.Z < zmin || phit.Z > zmax || phi > phiMax) return false; } float u = phi / phiMax; float cosphi = MathHelper.Cos(phi), sinphi = MathHelper.Sin(phi); Vector dpdu = new Vector(-phiMax * phit.Y, phiMax * phit.X, 0); Vector dpdv = new Vector((p2.X - p1.X) * cosphi - (p2.Y - p1.Y) * sinphi, (p2.X - p1.X) * sinphi + (p2.Y - p1.Y) * cosphi, p2.Z - p1.Z); Vector d2Pduu = -phiMax * phiMax * new Vector(phit.X, phit.Y, 0); Vector d2Pduv = phiMax * new Vector(-dpdv.Y, dpdv.X, 0); Vector d2Pdvv = new Vector(0, 0, 0); float E = Vector.Dot(dpdu, dpdu); float F = Vector.Dot(dpdu, dpdv); float G = Vector.Dot(dpdv, dpdv); Vector N = Vector.Normalize(Vector.Cross(dpdu, dpdv)); float e = Vector.Dot(N, d2Pduu); float f = Vector.Dot(N, d2Pduv); float g = Vector.Dot(N, d2Pdvv); float invEGF2 = 1.0f / (E * G - F * F); Normal dndu = new Normal((f * F - e * G) * invEGF2 * dpdu + (e * F - f * E) * invEGF2 * dpdv); Normal dndv = new Normal((g * F - f * G) * invEGF2 * dpdu + (f * F - g * E) * invEGF2 * dpdv); Transform o2w = ObjectToWorld; dg[0] = new DifferentialGeometry(o2w[phit], o2w[dpdu], o2w[dpdv], o2w[dndu], o2w[dndv], u, v, this); tHit[0] = thit; rayEpsilon[0] = 5e-4f * tHit; return true; }
public static float Distance(Vector v1, Vector v2) { return (v2 - v1).Magnitude; }
public RayDifferential(Point orig, Vector dir, Ray parent, float start, float end = float.MaxValue) : base(orig, dir, start, end, parent.Time, parent.Depth + 1) { HasDifferentials = false; }
public RayDifferential(Point orig, Vector dir, float start, float end = float.MaxValue, float t = 0.0f, int d = 0) : base(orig, dir, start, end, t, d) { HasDifferentials = false; }
public static float DistanceSquared(Vector v1, Vector v2) { return (v2 - v1).SquaredMagnitude; }
public void Setdpdv(Vector dpdv) { this.dpdv = dpdv; }
public void Setdpdy(Vector dpdv) { this.dpdy = dpdv; }
public void ComputeDifferentials(RayDifferential ray) { if (ray.HasDifferentials) { float d = -Vector.Dot((Vector)nn, new Vector(p.X, p.Y, p.Z)); Vector rxv = new Vector(ray.RXOrigin.X, ray.RXOrigin.Y, ray.RXOrigin.Z); float tx = -(Vector.Dot((Vector)nn, rxv) + d) / Vector.Dot((Vector)nn, ray.RXDirection); if (float.IsNaN(tx)) { dudx = dvdx = 0.0f; dudy = dvdy = 0.0f; dpdx = dpdy = new Vector(0, 0, 0); goto end; } Point px = ray.RXOrigin + tx * ray.RXDirection; Vector ryv = new Vector(ray.RYOrigin.X, ray.RYOrigin.Y, ray.RYOrigin.Z); float ty = -(Vector.Dot((Vector)nn, ryv) + d) / Vector.Dot((Vector)nn, ray.RYDirection); if (float.IsNaN(ty)) { dudx = dvdx = 0.0f; dudy = dvdy = 0.0f; dpdx = dpdy = new Vector(0, 0, 0); goto end; } Point py = ray.RYOrigin + ty * ray.RYDirection; dpdx = px - p; dpdy = py - p; float[][] A = new float[2][]; float[] Bx = new float[2]; float[] By = new float[2]; int[] axes = new int[2]; if (MathHelper.Abs(nn.X) > MathHelper.Abs(nn.Y) && MathHelper.Abs(nn.X) > MathHelper.Abs(nn.Z)) { axes[0] = 1; axes[1] = 2; } else if (MathHelper.Abs(nn.Y) > MathHelper.Abs(nn.Z)) { axes[0] = 0; axes[1] = 2; } else { axes[0] = 0; axes[1] = 1; } A[0][0] = dpdu[axes[0]]; A[0][1] = dpdv[axes[0]]; A[1][0] = dpdu[axes[1]]; A[1][1] = dpdv[axes[1]]; Bx[0] = px[axes[0]] - p[axes[0]]; Bx[1] = px[axes[1]] - p[axes[1]]; By[0] = py[axes[0]] - p[axes[0]]; By[1] = py[axes[1]] - p[axes[1]]; float a = 0, b = 0, c = 0, f = 0; if (!Transform.SolveLinearSystem2x2(A, Bx, ref a, ref b)) { dudx = 0.0f; dvdx = 0.0f; } else { dudx = a; dvdx = b; } if (!Transform.SolveLinearSystem2x2(A, By, ref c, ref f)) { dudy = 0.0f; dvdy = 0.0f; } else { dudy = c; dvdy = f; } end: float j = 0; } else { dudx = dvdx = 0.0f; dudy = dvdy = 0.0f; dpdx = dpdy = new Vector(0, 0, 0); } }
public Vector Cross(Vector vector) { return new Vector(Y * vector.Z - Z * vector.Y, Z * vector.X - X * vector.Z, X * vector.Y - Y * vector.X); }
public static float AbsDot(Vector v1, Vector v2) { return MathHelper.Abs(Dot(v1, v2)); }
public float AbsDot(Vector v) { return MathHelper.Abs(Dot(v)); }
public float Dot(Vector v) { return X * v.X + Y * v.Y + Z * v.Z; }
public void Setdpdu(Vector dpdu) { this.dpdu = dpdu; }
public static Vector Cross(Vector v1, Normal v2) { return v2.Cross(v1); }
public void Setdpdx(Vector dpdu) { this.dpdx = dpdu; }
public static Vector Cross(Normal v1, Vector v2) { return v1.Cross(v2); }
public DifferentialGeometry(Point P, Vector DPDU, Vector DPDV, Normal DNDU, Normal DNDV, float uu, float vv, Shape sh) { p = (P); dpdu = (DPDU); dpdv = (DPDV); dndu = (DNDU); dndv = (DNDV); nn = new Normal(Vector.Normalize(Vector.Cross(dpdu, dpdv))); u = uu; v = vv; shape = sh; dudx = dvdx = dudy = dvdy = 0; dpdx = dpdy = new Vector(); if (shape != null && (shape.ReverseOrientation ^ shape.TransformSwapsHandedness)) nn *= -1.0f; }
public static Vector Invert(Vector vector) { vector.Invert(); return vector; }