📄 codigo_imprimible.txt
字号:
//===========================================================================package vitral.framework.visual;import java.util.Vector;import java.util.Enumeration;import vitral.toolkits.common.VECTOR;import vitral.toolkits.common.COLOR;import vitral.toolkits.entorno.RAYO;import vitral.toolkits.entorno.CAMARA;import vitral.toolkits.entorno.MATERIAL;import vitral.toolkits.entorno.LUZ;import vitral.toolkits.geom.GEOMETRIA;import vitral.toolkits.media.IMAGEN_RGB;import vitral.framework.UNIVERSO;/**Esta clase solo provee un método que encapsula un algoritmo decontrol de visualización. Su razón de ser (y por la cualNO poner ese método en la clase cliente que la utiliza) es facilitarla abstracción de la operación de visualización, lacual puede ser cambiada por otro algoritmo de visualización (i.e.zbuffer o radiosidad), pero manteniendo el mismo modelo de escena 3D.*/public class RAYTRACER_MIT { private static final float INFINITO = Float.MAX_VALUE; private static final float TINY = 0.001f; private VECTOR static_tmp; public RAYTRACER_MIT() { // Machete similar al descrito en ESFERA::intersect static_tmp = new VECTOR(); } // the point of intersection (p) // a unit-length surface normal (n) // a unit-length vector towards the ray's origin (v) public COLOR modelo_de_iluminacion(VECTOR p, VECTOR n, VECTOR v, Vector lights, Vector objects, COLOR color_de_fondo, MATERIAL m) { COLOR resultado = new COLOR(); GEOMETRIA objeto_mas_cercano; for ( Enumeration lightSources = lights.elements(); lightSources.hasMoreElements(); ) { LUZ luz = (LUZ)lightSources.nextElement(); if ( luz.tipo_de_luz == LUZ.AMBIENTE ) { resultado.r += m.ka*m.ir*luz.ir; resultado.g += m.ka*m.ig*luz.ig; resultado.b += m.ka*m.ib*luz.ib; } else { VECTOR l; if ( luz.tipo_de_luz == LUZ.PUNTUAL ) { l = new VECTOR(luz.lvec.x - p.x, luz.lvec.y - p.y, luz.lvec.z - p.z); l.normalizar(); } else { l = new VECTOR(-luz.lvec.x, -luz.lvec.y, -luz.lvec.z); } // Check if the surface point is in shadow VECTOR poffset = new VECTOR(p.x + TINY*l.x, p.y + TINY*l.y, p.z + TINY*l.z); RAYO rayo_sombra = new RAYO(poffset, l); objeto_mas_cercano = trazar_rayo_en_escena(rayo_sombra, objects); if ( objeto_mas_cercano != null ) { continue; } float lambert = n.producto_punto(l); if ( lambert > 0 ) { if ( m.kd > 0 ) { float diffuse = m.kd*lambert; resultado.r += diffuse*m.ir*luz.ir; resultado.g += diffuse*m.ig*luz.ig; resultado.b += diffuse*m.ib*luz.ib; } if ( m.ks > 0 ) { lambert *= 2; static_tmp.x = lambert*n.x - l.x; static_tmp.y = lambert*n.y - l.y; static_tmp.z = lambert*n.z - l.z; float spec = v.producto_punto(static_tmp); if ( spec > 0 ) { spec = m.ks*((float) Math.pow((double) spec, (double)m.ns)); resultado.r += spec*luz.ir; resultado.g += spec*luz.ig; resultado.b += spec*luz.ib; } } } } } // Compute illumination due to reflection if ( m.kr > 0 ) { float t = v.producto_punto(n); if ( t > 0 ) { t *= 2; VECTOR reflect = new VECTOR(t*n.x - v.x, t*n.y - v.y, t*n.z - v.z); VECTOR poffset = new VECTOR(p.x + TINY*reflect.x, p.y + TINY*reflect.y, p.z + TINY*reflect.z); RAYO rayo_reflejado = new RAYO(poffset, reflect); objeto_mas_cercano = trazar_rayo_en_escena(rayo_reflejado, objects); if ( objeto_mas_cercano != null ) { VECTOR rp = new VECTOR(); VECTOR rn = new VECTOR(); VECTOR rv = new VECTOR(); objeto_mas_cercano.informacion_extra( rayo_reflejado, rayo_reflejado.t, rp, rn); rv.x = -rayo_reflejado.direction.x; rv.y = -rayo_reflejado.direction.y; rv.z = -rayo_reflejado.direction.z; COLOR rcolor = modelo_de_iluminacion(rp, rn, rv, lights, objects, color_de_fondo, m); resultado.r += m.kr*rcolor.r; resultado.g += m.kr*rcolor.g; resultado.b += m.kr*rcolor.b; } else { resultado.r += m.kr*color_de_fondo.r; resultado.g += m.kr*color_de_fondo.g; resultado.b += m.kr*color_de_fondo.b; } } } // Add code for refraction here // <No implementado> // Clamp resultado to MAX 1.0 intensity. resultado.r = (resultado.r > 1f) ? 1f : resultado.r; resultado.g = (resultado.g > 1f) ? 1f : resultado.g; resultado.b = (resultado.b > 1f) ? 1f : resultado.b; return resultado; } /** Si el `in_rayo` se intersecta con al menos uno de los `in_arr_objetos`, se retorna una referencia al objeto mas cercano de los intersectados. De lo contrario se retorna null. */ public GEOMETRIA trazar_rayo_en_escena(RAYO in_rayo, Vector in_arr_objetos) { Enumeration i; GEOMETRIA gi; GEOMETRIA objeto_mas_cercano; in_rayo.t = INFINITO; objeto_mas_cercano = null; for ( i = in_arr_objetos.elements(); i.hasMoreElements(); ) { gi = (GEOMETRIA)i.nextElement(); if ( gi.interseccion(in_rayo) ) { objeto_mas_cercano = gi; } } return objeto_mas_cercano; } private COLOR seguimiento_rayo(RAYO rayo, Vector in_objetos, Vector in_luces, COLOR in_fondo) { COLOR c; VECTOR p = new VECTOR(); VECTOR n = new VECTOR(); VECTOR v = new VECTOR(); GEOMETRIA objeto_mas_cercano; objeto_mas_cercano = trazar_rayo_en_escena(rayo, in_objetos); if ( objeto_mas_cercano != null ) { objeto_mas_cercano.informacion_extra(rayo, rayo.t, p, n); v.x = -rayo.direction.x; v.y = -rayo.direction.y; v.z = -rayo.direction.z; c = modelo_de_iluminacion( p, n, v, in_luces, in_objetos, in_fondo, objeto_mas_cercano.material); } else { c = in_fondo; } return c; }/* // SIN MODELO DE ILUMINACION: SOLO LUZ AMBIENTE (Borrar luego de aqui, // dejar solo en el estudio paso a paso de las etapas! private COLOR seguimiento_rayo(RAYO rayo, Vector in_objetos, Vector in_luces, COLOR in_fondo) { COLOR c; GEOMETRIA objeto_mas_cercano; c = in_fondo; objeto_mas_cercano = trazar_rayo_en_escena(rayo, in_objetos); if ( objeto_mas_cercano != null ) { c.r = objeto_mas_cercano.material.ir; c.g = objeto_mas_cercano.material.ig; c.b = objeto_mas_cercano.material.ib; } return c; }*/ /** Macroalgoritmo de control para raytracing. Este método recibe el modelo de una escena 3D previamente construida en memoria y una imagen, y modifica la imagen de tal forma que contiene una visualizacion de la escena, resultado de aplicar la técnica de raytracing. PARÁMETROS: - `inout_viewport`: imagen RGB en donde el algoritmo calculará su resultado. - `in_objetos`: arreglo dinámico de GEOMETRIAs que constituyen los objetos visibles de la escena. - `in_luces`: arreglo dinámico de LUZes (luces puntuales) - `in_fondo`: especificación de un color de fondo para la escena (i.e. el color que se ve si no se ve ningún objeto!) - `in_camara`: especificación de la transformación de proyección 3D a 2D que se lleva a cabo en el proceso de visualización. PRE: - Todas las referencias estan creadas, asi sea que apunten a estructuras vacías. - La imagen `inout_viewport` esta creada, y es de el tamaño que el usuario desea para su visualización. POST: - `inout_viewport` contiene una representación visual de la escena 3D (`in_objetos`, `in_luces`, `in_fondo`), tal que corresponde a una proyección 3D a 2D controlada por la cámara virtual `in_camara`. NOTA: Este algoritmo se inicio como una modificacion del raytracer del curso 6.837 (computación gráfica) de MIT, original de Leonard McMillan y Tomas Lozano Perez, pero puede considerarse que es una re-escritura y re-estructuración completa de Oscar Chavarro / FUSM. */ public void ejecutar(IMAGEN_RGB inout_viewport, UNIVERSO in_escena) { int x, y; RAYO rayo; COLOR color; System.out.print("["); in_escena.camara.preprocesar_vista(); for ( y = 0; y < inout_viewport.ytam(); y++ ) { if ( y % 10 == 0 ) { System.out.print("."); } for ( x = 0; x < inout_viewport.xtam(); x++ ) { //- Trazado individual de un rayo -------------------------- // Es importante que la operacion generar_rayo sea inline // (i.e. "final") rayo = in_escena.camara.generar_rayo(x, y); color = seguimiento_rayo(rayo, in_escena.arr_cosas, in_escena.arr_luces, in_escena.color_de_fondo); //- Exporto el resultado de color del pixel ---------------- inout_viewport.putpixel(x, y, (byte)(255 * color.r), (byte)(255 * color.g), (byte)(255 * color.b)); } } System.out.println("]"); }}//===========================================================================//= EOF =//===========================================================================//===========================================================================package vitral.framework;// Paquetes de java utilizados para la agregacion multipleimport java.util.Vector;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import java.io.BufferedReader;import java.io.StreamTokenizer;import java.io.IOException;// Paquetes internos al sistema de raytracing / modelamientoimport vitral.toolkits.common.VECTOR;import vitral.toolkits.common.COLOR;import vitral.toolkits.entorno.CAMARA;import vitral.toolkits.entorno.LUZ;import vitral.toolkits.entorno.MATERIAL;import vitral.toolkits.geom.ESFERA;public class UNIVERSO{ // Variables especificas para la depuracion / desarrollo private static final boolean depurar = false; // El modelo del mundo public Vector arr_cosas; public Vector arr_luces; public COLOR color_de_fondo; public CAMARA camara; public UNIVERSO() { camara = new CAMARA(); color_de_fondo = new COLOR(); color_de_fondo.r = 0; color_de_fondo.g = 0; color_de_fondo.b = 0; int CHUNKSIZE = 100; // Incremento de arreglos // Arreglo de GEOMETRIAs arr_cosas = new Vector(CHUNKSIZE, CHUNKSIZE); // Arreglo de LUZes arr_luces = new Vector(CHUNKSIZE, CHUNKSIZE); } public void dispose() { // OJO: Falta ver si la destruccion de la escena esta OK... camara = null; color_de_fondo = null; arr_cosas = null; arr_luces = null; } private void imprimirMensaje(String m) { if ( depurar ) { System.out.println(m); } } private float leerNumero(StreamTokenizer st) throws IOException { if (st.nextToken() != StreamTokenizer.TT_NUMBER) { System.err.println("ERROR: number expected in line "+st.lineno()); throw new IOException(st.toString()); } return (float)st.nval; } public void leerArchivoDeEscena(InputStream is) throws IOException { Reader parsero = new BufferedReader(new InputStreamReader(is)); StreamTokenizer st = new StreamTokenizer(parsero); st.commentChar('#'); boolean fin_de_lectura = false; MATERIAL material_actual; // Material por defecto... material_actual = new MATERIAL(0.8f, 0.2f, 0.9f, 0.2f, 0.4f, 0.4f, 10.0f, 0f, 0f, 1f); while ( !fin_de_lectura ) { switch ( st.nextToken() ) { case StreamTokenizer.TT_WORD: if (st.sval.equals("sphere")) { VECTOR c = new VECTOR((float) leerNumero(st), (float) leerNumero(st), (float) leerNumero(st)); float r = (float)leerNumero(st); imprimirMensaje("sphere"); arr_cosas.addElement(new ESFERA(material_actual, c, r)); } /* else if (st.sval.equals("triangles")) { imprimirMensaje("triangles"); arr_cosas.addElement(new MESH(material_actual, st)); } */ else if (st.sval.equals("eye")) { imprimirMensaje("eye");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -