public static Camera Create(ParamSet paramSet, AnimatedTransform cam2World, Film film, Medium medium) { // Extract common camera parameters from _ParamSet_ double shutteropen = paramSet.FindOneFloat("shutteropen", 0.0); double shutterclose = paramSet.FindOneFloat("shutterclose", 1.0); if (shutterclose < shutteropen) { //Warning("Shutter close time [%f] < shutter open [%f]. Swapping them.", // shutterclose, shutteropen); PbrtMath.Swap(ref shutterclose, ref shutteropen); } double lensradius = paramSet.FindOneFloat("lensradius", 0.0); double focaldistance = paramSet.FindOneFloat("focaldistance", 1e6); double frame = paramSet.FindOneFloat( "frameaspectratio", Convert.ToDouble(film.FullResolution.X) / Convert.ToDouble(film.FullResolution.Y)); Bounds2D screen; if (frame > 1.0) { screen = new Bounds2D(new Point2D(-frame, -1.0), new Point2D(frame, 1.0)); } else { screen = new Bounds2D(new Point2D(-1.0, -1.0 / frame), new Point2D(1.0, 1.0 / frame)); } double[] sw = paramSet.FindFloat("screenwindow"); if (sw != null) { if (sw.Length == 4) { screen = new Bounds2D(new Point2D(sw[0], sw[2]), new Point2D(sw[1], sw[3])); } else { //Error("\"screenwindow\" should have four values"); } } double fov = paramSet.FindOneFloat("fov", 90.0); double halffov = paramSet.FindOneFloat("halffov", -1.0); if (halffov > 0.0) { // hack for structure synth, which exports half of the full fov fov = 2.0 * halffov; } return(new PerspectiveCamera(cam2World, screen, shutteropen, shutterclose, lensradius, focaldistance, fov, film, medium)); }
public Matrix4x4 Inverse() { int[] indxc = new int[4]; int[] indxr = new int[4]; int[] ipiv = { 0, 0, 0, 0 }; double[,] minv = new double[4, 4]; Array.Copy(_m, minv, 4 * 4); for (int i = 0; i < 4; i++) { int irow = 0; int icol = 0; double big = 0.0; // Choose pivot for (int j = 0; j < 4; j++) { if (ipiv[j] != 1) { for (int k = 0; k < 4; k++) { if (ipiv[k] == 0) { if (Math.Abs(minv[j, k]) >= big) { big = Math.Abs(minv[j, k]); irow = j; icol = k; } } else if (ipiv[k] > 1.0) { throw new InvalidOperationException("Singular matrix in MatrixInvert"); } } } } ++ipiv[icol]; // Swap rows _irow_ and _icol_ for pivot if (irow != icol) { for (int k = 0; k < 4; ++k) { PbrtMath.Swap(ref minv[irow, k], ref minv[icol, k]); } } indxr[i] = irow; indxc[i] = icol; if (minv[icol, icol] == 0.0) { throw new InvalidOperationException("Singular matrix in MatrixInvert"); } // Set $m[icol,icol]$ to one by scaling row _icol_ appropriately double pivinv = 1.0 / minv[icol, icol]; minv[icol, icol] = 1.0; for (int j = 0; j < 4; j++) { minv[icol, j] *= pivinv; } // Subtract this row from others to zero out their columns for (int j = 0; j < 4; j++) { if (j != icol) { double save = minv[j, icol]; minv[j, icol] = 0; for (int k = 0; k < 4; k++) { minv[j, k] -= minv[icol, k] * save; } } } } // Swap columns to reflect permutation for (int j = 3; j >= 0; j--) { if (indxr[j] != indxc[j]) { for (int k = 0; k < 4; k++) { PbrtMath.Swap(ref minv[k, indxr[j]], ref minv[k, indxc[j]]); } } } return(new Matrix4x4(minv)); }