public override void setCenter(Vec c) { this.c = c; }
public Surface() { color = new Vec(1, 0, 0); kd = 1.0; ks = 0.0; shine = 0.0; kt = 0.0; ior = 1.0; }
/** * Adds vector such as: * this+=sB * @param: s The multiplier * @param: b The vector to be added */ public void adds(double s, Vec b) { x += s * b.x; y += s * b.y; z += s * b.z; }
public View(Vec from, Vec at, Vec up, double dist, double angle, double aspect) { this.from = from; this.at = at; this.up = up; this.dist = dist; this.angle = angle; this.aspect = aspect; }
public static double dot(Vec a, Vec b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
/** * Substracs two vectors */ public static Vec sub(Vec a, Vec b) { return new Vec(a.x - b.x, a.y - b.y, a.z - b.z); }
public void render(Interval interval) { // Screen variables int[] row = new int[interval.width * (interval.yto - interval.yfrom)]; int pixCounter = 0; //iterator // Rendering variables int x, y, red, green, blue; double xlen, ylen; Vec viewVec; viewVec = Vec.sub(view.at, view.from); viewVec.normalize(); Vec tmpVec = new Vec(viewVec); tmpVec.scale(Vec.dot(view.up, viewVec)); Vec upVec = Vec.sub(view.up, tmpVec); upVec.normalize(); Vec leftVec = Vec.cross(view.up, viewVec); leftVec.normalize(); double frustrumwidth = view.dist * Math.Tan(view.angle); upVec.scale(-frustrumwidth); leftVec.scale(view.aspect * frustrumwidth); Ray r = new Ray(view.from, voidVec); Vec col = new Vec(); // Header for .ppm file // System.out.println("P3"); // System.out.println(width + " " + height); // System.out.println("255"); // All loops are reversed for 'speedup' (cf. thinking in java p331) // For each line for (y = interval.yfrom; y < interval.yto; y++) { ylen = (double)(2.0 * y) / (double)interval.width - 1.0; // System.out.println("Doing line " + y); // For each pixel of the line for (x = 0; x < interval.width; x++) { xlen = (double)(2.0 * x) / (double)interval.width - 1.0; r.D = Vec.comb(xlen, leftVec, ylen, upVec); r.D.add(viewVec); r.D.normalize(); col = trace(0, 1.0, r); // computes the color of the ray red = (int)(col.x * 255.0); if (red > 255) red = 255; green = (int)(col.y * 255.0); if (green > 255) green = 255; blue = (int)(col.z * 255.0); if (blue > 255) blue = 255; checksum += red; checksum += green; checksum += blue; // RGB values for .ppm file // System.out.println(red + " " + green + " " + blue); // Sets the pixels row[pixCounter++] = alpha | (red << 16) | (green << 8) | (blue); } // end for (x) } // end for (y) }
public static Vec comb(double a, Vec A, double b, Vec B) { return new Vec(a * A.x + b * B.x, a * A.y + b * B.y, a * A.z + b * B.z); }
public Ray(Vec pnt, Vec dir) { P = new Vec(pnt.x, pnt.y, pnt.z); D = new Vec(dir.x, dir.y, dir.z); D.normalize(); }
public Ray() { P = new Vec(); D = new Vec(); }
public abstract void setCenter(Vec c);
public abstract Vec normal(Vec pnt);
public Light(double x, double y, double z, double brightness) { this.pos = new Vec(x, y, z); this.brightness = brightness; }
/** * Copy constructor */ public Vec(Vec a) { x = a.x; y = a.y; z = a.z; }
/** * Returns the shaded color * @return The color in Vec form (rgb) */ Vec shade(int level, double weight, Vec P, Vec N, Vec I, Isect hit) { double n1, n2, eta, c1, cs2; Vec r; Vec tcol; Vec R; double t, diff, spec; Surface surf; Vec col; int l; col = new Vec(); surf = hit.surf; R = new Vec(); if (surf.shine > 1e-6) { R = SpecularDirection(I, N); } // Computes the effectof each light for (l = 0; l < lights.Length; l++) { L.sub2(lights[l].pos, P); if (Vec.dot(N, L) >= 0.0) { t = L.normalize(); tRay.P = P; tRay.D = L; // Checks if there is a shadow if (Shadow(tRay, t) > 0) { diff = Vec.dot(N, L) * surf.kd * lights[l].brightness; col.adds(diff, surf.color); if (surf.shine > 1e-6) { spec = Vec.dot(R, L); if (spec > 1e-6) { spec = Math.Pow(spec, surf.shine); col.x += spec; col.y += spec; col.z += spec; } } } } // if } // for tRay.P = P; if (surf.ks * weight > 1e-3) { tRay.D = SpecularDirection(I, N); tcol = trace(level + 1, surf.ks * weight, tRay); col.adds(surf.ks, tcol); } if (surf.kt * weight > 1e-3) { if (hit.enter > 0) tRay.D = TransDir(null, surf, I, N); else tRay.D = TransDir(surf, null, I, N); tcol = trace(level + 1, surf.kt * weight, tRay); col.adds(surf.kt, tcol); } // garbaging... tcol = null; surf = null; return col; }
/** * adds: Returns a new vector such as * new = sA + B */ public static Vec adds(double s, Vec a, Vec b) { return new Vec(s * a.x + b.x, s * a.y + b.y, s * a.z + b.z); }
/** * Return the Vector's reflection direction * @return The specular direction */ Vec SpecularDirection(Vec I, Vec N) { Vec r; r = Vec.comb(1.0 / Math.Abs(Vec.dot(I, N)), I, 2.0, N); r.normalize(); return r; }
public static Vec cross(Vec a, Vec b) { return new Vec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); }
/** * Return the Vector's transmission direction */ Vec TransDir(Surface m1, Surface m2, Vec I, Vec N) { double n1, n2, eta, c1, cs2; Vec r; n1 = m1 == null ? 1.0 : m1.ior; n2 = m2 == null ? 1.0 : m2.ior; eta = n1 / n2; c1 = -Vec.dot(I, N); cs2 = 1.0 - eta * eta * (1.0 - c1 * c1); if (cs2 < 0.0) return null; r = Vec.comb(eta, I, eta * c1 - Math.Sqrt(cs2), N); r.normalize(); return r; }
public static Vec mult(Vec a, Vec b) { return new Vec(a.x * b.x, a.y * b.y, a.z * b.z); }
Vec v, b; // temporary vecs used to minimize the memory load #endregion Fields #region Constructors public Sphere(Vec center, double radius) { c = center; r = radius; r2 = r * r; v = new Vec(); b = new Vec(); }
/** * Add a vector to the current vector * @param: a The vector to be added */ public void add(Vec a) { x += a.x; y += a.y; z += a.z; }
public override Vec normal(Vec p) { Vec r; r = Vec.sub(p, c); r.normalize(); return r; }
public void comb2(double a, Vec A, double b, Vec B) { x = a * A.x + b * B.x; y = a * A.y + b * B.y; z = a * A.z + b * B.z; }
/** * Substracts two vects and places the results in the current vector * Used for speedup with local variables -there were too much Vec to be gc'ed * Consumes about 10 units, whether sub consumes nearly 999 units!! * cf thinking in java p. 831,832 */ public void sub2(Vec a, Vec b) { this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; }