/* Raytracer.java * * Copyright (c) 2001, Ted Nelson and Tuomas Lukka * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README * file for more details. * */ /* * Written by Tero Mäyränen */ package org.gzigzag.module.raytrace; import org.gzigzag.*; import java.awt.*; import java.util.*; /** * This is the "main" class of the raytracer system. */ public class Raytracer { public static final String rcsid = "$Id: Raytracer.java,v 1.1 2002/10/07 12:37:35 tuukkah Exp $"; private static final int SUPERSAMPLESIZE = 2; private static final int SUPERSAMPLESIZE2 = SUPERSAMPLESIZE*SUPERSAMPLESIZE; private int pixels[]; private double deltax, deltay; private Ray rayx, rayy; private int width; private Model model = new Model(); private Vector primitives; private Vector lights; public Raytracer() { primitives = model.getPrimitives(); lights = model.getLights(); } public void prepare(int wid, int height, ZZCell modelCell) { model.restart(); /* * This call should build the primitives and lights -vectors according to the * model data in the structure. */ model.readModel(modelCell); width = wid; pixels = new int[width]; deltax = -2.0/(width*SUPERSAMPLESIZE); deltay = -2.0/(height*SUPERSAMPLESIZE); rayx = new Ray(); rayy = new Ray(0, 0, 0, 1, 1, 1.5); } public int[] nextLine() { rayx.set(rayy); double ddata[] = rayx.getd().getdata(); int supr, supg, supb, supc; for (int x=0; x> 16) & 0xff, r2 = (color2 >> 16) & 0xff, g1 = (color1 >> 8) & 0xff, g2 = (color2 >> 8) & 0xff, b1 = color1 & 0xff, b2 = color2 & 0xff; r1 = (r1 * r2) >> 8; g1 = (g1 * g2) >> 8; b1 = (b1 * b2) >> 8; return (r1 << 16) | (g1 << 8) | b1; } private int trace(Ray ray, int iteration) { if (iteration == 0) return 0; Primitive p; Primitive near = null; for (int i=0; i> 16) & 0xff; int refG = (refr >> 8) & 0xff; int refB = refr & 0xff; // Make up some kind of rays for the refraction :-) nd = reflection.getd().getdata(); ndx = nd[0]; ndy = nd[1]; ndz = nd[2]; nd[0] = dx; nd[1] = dy; nd[2] = dz; reflection.normalize(); vdx = nd[0]; vdy = nd[1]; vdz = nd[2]; if (refR != 0) { nd[0] = vdx + 0.4 * ndx; nd[1] = vdy + 0.4 * ndy; nd[2] = vdz + 0.4 * ndz; refr = ((refR * (trace(reflection, iteration - 1) & 0xff0000)) >> 8) & 0xff0000; } if (refG != 0) { nd[0] = vdx + 0.35 * ndx; nd[1] = vdy + 0.35 * ndy; nd[2] = vdz + 0.35 * ndz; refr |= ((refG * (trace(reflection, iteration - 1) & 0xff00)) >> 8) & 0xff00; } if (refB != 0) { nd[0] = vdx + 0.3 * ndx; nd[1] = vdy + 0.3 * ndy; nd[2] = vdz + 0.3 * ndz; refr |= ((refR * (trace(reflection, iteration - 1) & 0xff)) >> 8) & 0xff; } int glow = near.getGlow(); int r = (glow & 0xff0000) + (refl & 0xff0000) + (refr & 0xff0000) + (shadow << 16); if (r > 0xff0000) r = 0xff0000; int g = (glow & 0xff00) + (refl & 0xff00) + (refr & 0xff00) + (shadow << 8); if (g > 0xff00) g = 0xff00; int b = (glow & 0xff) + (refl & 0xff) + (refr & 0xff) + shadow; if (b > 0xff) b = 0xff; return r | g | b; } private Ray pong = new Ray(0, 0, 0); private int lightAttenuation(Ray view, Ray light) { double ld[] = light.getd().getdata(); double vd[] = view.getd().getdata(); double pd[] = pong.getd().getdata(); pd[0] = ld[0] - vd[0]; pd[1] = ld[1] - vd[1]; pd[2] = ld[2] - vd[2]; return (int)(255.0 / (1 + (pong.length()*4))) & 0xff; } }