Monografias.com > Sin categoría
Descargar Imprimir Comentar Ver trabajos relacionados

Introducción a Java3D (página 3)




Enviado por goodlafa



Partes: 1, 2, 3

Algoritmo 2.1. Procedimiento
para desarrollar un programa en
Java3D.

Aunque no profundiza demasiado, este algoritmo
sí refleja el concepto
fundamental de la programación en Java3D: lo más
importante consiste en la creación de las distintas ramas
del grafo de escena.

2.5 Sistema De
Coordenadas.

Los sistemas de
coordenadas en Java3D son, por defecto, "diestros", de tal forma
que la parte positiva del eje de ordenadas es el sentido
ascendente de la gravedad, la parte positiva del eje de abscisas
es horizontal hacia la derecha y la parte positiva del eje Z
está dirigido hacia el observador.

La unidad utilizada por default son los metros.
En la Figura 2.1 se puede ver gráficamente esta distribución.

Figura 2.2. Sistema de coordenadas
Java3D.

2.5.1 Coordenadas De Alta
Resolución.

La representación de las coordenadas con valores en
punto flotante de doble precisión, de simple
precisión o incluso valores de menor precisión es
suficiente para representar y mostrar escenas en tres dimensiones
de gran calidad. Si nos
alejamos doscientos kilómetros desde el origen de
coordenadas utilizando una precisión sencilla de punto
flotante, los puntos representables aparecen de alguna forma
discretizados. Si lo que se pretende es llegar a distancias muy
pequeñas, muy cerca del origen, aparece el mismo problema.
Las coordenadas de alta resolución de Java3D constan de 3
números de 256 bits de punto fijo, uno para cada eje. El
punto fijo se encuentra en el bit 128 y el valor 1.0 se
corresponde exactamente con un metro. Este sistema de coordenadas
es suficiente para describir un universo tan
enorme como varios cientos de billones de años luz o como para
definir objetos tan pequeños como un
protón.

En la Tabla 2.2 se representan cuántos bits son
necesarios por encima o por debajo del punto fijo para
representar el rango que nos interese.

2n
metros

Unidades

87.29

Universo (20 billones de años
luz).

69.68

Galaxia (100,000 años luz).

53.07

Año luz.

43.43

Diámetro del sistema
solar.

23.60

Diámetro de la
Tierra.

10.65

Milla.

9.97

Kilómetro.

0

Metro.

– 19.93

Micra.

– 115.57

Longitud de Plank.

Tabla 2.2. Escalas de
las coordenadas de alta resolución

Los números de punto fijo de 256 bits
proporcionan también la ventaja de ser capaces de
representar directamente, de forma exacta, cualquier valor de
precisión sencilla de punto flotante.

Las coordenadas de alta resolución de Java3D se
utilizan sólo para incluir los sistemas de coordenadas
tradicionales de punto flotante en un sistema de mucha mayor
resolución. De esta forma se pueden crear universos de
cualquier tamaño imaginable sin preocuparnos de la
precisión.

Las coordenadas de alta resolución se representan
como números de 256 bits con signo en complemento a dos.
Aunque Java3D mantiene oculta la representación interna de
las coordenadas de alta resolución, el usuario debe
especificar dichas coordenadas usando matrices de
enteros de 8 elementos. Java3D trata el entero en la
posición 0 como los bits más significativos y el
situado en la posición 7 como los menos significativos de
la coordenada de alta resolución. El punto binario se
localiza en el bit 128 o entre los enteros de las posiciones 3 y
4.

La forma en que los cargadores de ficheros manejan las
coordenadas de alta resolución depende de cada cargador en
concreto, ya
que Java3D no define directamente ninguna semántica de carga de ficheros. Sin
embargo, hay ciertas consideraciones que pueden
indicarse.

Para universos pequeños (del orden de cientos de
metros), un solo Locale con coordenadas de alta resolución
ubicado en la posición (0.0, 0.0, 0.0) como el nodo
raíz es suficiente. Un cargador puede construir
automáticamente este nodo durante el proceso de
carga ya que las coordenadas de alta resolución no
necesitan tener una representación directa en el fichero
externo.

Universos virtuales de mayor tamaño se suelen
construir siguiendo la jerarquía habitual de directorios
de cualquier disco duro, es
decir, un universo virtual raíz que contiene la
mayoría de las referencias a ficheros externos que
incluyen universos virtuales. En este caso, el objeto que
contiene la referencia al fichero define la localización
de los datos que se
tienen que leer en el universo
virtual en cuestión.

El contenido de los ficheros de datos debe enlazarse al
nodo mientras se leen, heredando así las coordenadas de
alta resolución del objeto como el nuevo universo virtual
origen del grafo de escena embebido. Si ese mismo grafo de escena
contiene a su vez coordenadas de alta resolución,
tendrán que ser trasladadas en la cantidad que indiquen
esas coordenadas y entonces añadirlas al universo virtual
mayor como nuevas coordenadas de alta resolución, con todo
su contenido por debajo de las mismas.

A la hora de tratar con objetos que se mueven con gran
amplitud, hay que considerar que tendrán que cambiar
periódicamente su Locale padre de forma que se adapte
más adecuadamente a sus nuevas coordenadas. Si no
existiera ningún Locale suficientemente apropiado, la
aplicación podría crear uno nuevo.

2.6 Modos De
Renderización.

Java3D proporciona tres modos diferentes de
renderización: modo inmediato, modo retenido
y modo compilado–retenido. Están ordenados de
forma creciente según el grado de libertad para
optimizar la ejecución de la aplicación. Los dos
últimos métodos
son los más usados debido a las características de
la gran mayoría de las aplicaciones.

Modo inmediato:

El modo inmediato no permite mucha optimización
en cuanto al grafo de escena se refiere. En este modo, el nivel
de abstracción de Java3D es bastante elevado y acelera el
renderizado inmediato de los objetos. Una aplicación debe
proporcionar un método de
dibujado con un conjunto completo de puntos, líneas o
triángulos que son posteriormente
renderizados por el generador de imágenes
de alta velocidad de
Java3D. Por supuesto, la aplicación puede construir estas
listas de puntos, líneas o triángulos en cualquier
forma que elija. Este modo de renderización permite la
mayor flexibilidad y libertad a costa de una reducción en
el rendimiento.

En este modo Java3D no dispone de información acerca de los objetos gráficos de la composición. A causa
de esto apenas se pueden realizar optimizaciones en la
aplicación del programador. Este puede utilizar o no la
estructura de
grafo de escena heredada del diseño
de Java3D; puede elegir entre dibujar la escena directamente o
definir el grafo de escena. El modo inmediato puede utilizarse
tanto de forma independiente como combinado con los otros dos
métodos existentes.

Modo Retenido:

El modo retenido requiere que la aplicación
construya un grafo de escena y que especifique qué
elementos de dicho grafo de escena pueden cambiar durante la
renderización. El grafo de escena describe los objetos del
universo virtual, la distribución de dichos objetos y
cómo la aplicación los anima. Este modo proporciona
gran parte de la flexibilidad del modo inmediato a la vez que un
incremento sustancial en la velocidad de renderización.
Todos los objetos definidos en el grafo de escena son accesibles
y manipulables, como lo es el grafo de escena en sí mismo.
El programador puede crear grafos de
escena y añadir o eliminar nodos del mismo
rápidamente y ver inmediatamente los efectos de dichos
cambios.

Este modo permite construir objetos, insertarlos en una
base de datos, componer objetos y añadir comportamientos a
los objetos. Java3D sabe que el programador ha definido objetos,
sabe cómo ha combinado dichos objetos para crear objetos
compuestos o grafos de escena y también conoce qué
comportamientos o acciones se
han añadido a los objetos.

Todo este conocimiento
permite a Java3D realizar diferentes optimizaciones; puede
construir estructuras de
datos especiales que contengan la geometría de los objetos de tal forma que
se aumente la velocidad a la que puede renderizarlo. Puede
también compilar los comportamientos de los objetos para
que se ejecuten a una mayor velocidad cuando sean
invocados.

Modo compilado–retenido:

Este modo, al igual que el retenido, requiere que
la aplicación construya un grafo de escena y que
especifique qué elementos pueden cambiar durante la
renderización. Además, la aplicación puede
compilar parte o todos los subgrafos que forman el grafo de
escena completo. Java3D compila estos grafos en un formato
interno. La representación compilada del grafo de escena
apenas se parece a la estructura de árbol original
proporcionada por la aplicación, sin embargo, es
funcionalmente equivalente. Este modo es el que proporciona el
mejor rendimiento, permite que la API de Java3D realice una serie
de complicadas optimizaciones. Un programador puede solicitar que
Java3D compile un objeto o un grafo de escena. Un objeto o un
grafo de escena compilado consiste en cualesquiera estructuras
que Java3D quiera crear para asegurar que los objetos o grafos de
escena se renderizan a la máxima velocidad posible. Como
Java3D sabe que la mayor parte de los objetos o grafos de escena
compilados no van a cambiar, puede realizar múltiples
optimizaciones como pueden ser la fusión de
múltiples objetos en un objeto conceptual, modificar un
objeto para disponer de él en una geometría
comprimida o incluso romper un objeto en diferentes partes y
reensamblarlo en nuevos "objetos conceptuales".

2.7 Paquetes de
Java3D.

Todos los programas de
Java3D se forman, al menos parcialmente, uniendo distintos
elementos de la jerarquía de clases de Java3D. Esa gran
colección de objetos describe un universo virtual, que
será posteriormente renderizado. La API define más
de cien clases incluidas en el paquete javax.media.j3d. Estas
clases son las normalmente denominadas como clases
núcleo de Java3D.

Hay cientos de campos y métodos en dichas clases,
sin embargo, un universo virtual sencillo que contenga algo de
animación se puede construir con sólo unas pocas de
ellas.

Además del paquete núcleo, a la hora de
desarrollar programas en Java3D se utilizan otros paquetes. Uno
de ellos es el paquete normalmente conocido como de utilidad
(com.sun.j3d.utils).El paquete núcleo incluye sólo
las clases de nivel más bajo necesarias para programar en
Java3D.

Las clases de utilidad son extensiones muy
prácticas y potentes. Como era de esperar, la
utilización de clases de utilidad reduce
significativamente el número de líneas de código
a la hora de programar.

Por último, también se utilizan clases del
paquete java.awt donde se
define el Abstract Windowing Toolkit (AWT) que proporciona
una ventana para visualizar la renderización y clases
javax.vecmath que define clases matemáticas de vectores para
puntos, vectores, matrices y otros objetos
matemáticos.

3. El Primer Ejemplo:
HelloJava3D.java

En este capítulo vamos a iniciar con un ejemplo
bastante sencillo que nos ofrecerá un panorama general de
las aplicaciones Java3D siguiendo el Algoritmo 2.1 (2.4.
Construcción De Un Árbol), simplemente
crearemos un cubo en un applet que estará embebido en un
Frame. El código se mostrará por partes y al
finalizar lo mostraremos completo.

3.1.
HelloJava3D.java.

El ejemplo HelloJava3D.java es una clase definida
para extender la clase Applet. La clase principal de un programa
Java3D normalmente define un método para construir la rama
de contenido gráfico. En el ejemplo HelloJava3D.java dicho
método está definido como createSceneGraph(). Los
pasos del algoritmo de la sección 2.4 se implementan en el
constructor. El paso 1, crear un objeto Canvas3D, se observa en
la línea 4 del listado 3.1. El paso 2, crear un objeto
SimpleUniverse, se hace en la línea 11. El paso 2a,
personalizar el objeto SimpleUniverse, se realiza en la
línea 15. El paso 3, construir la rama de contenido, se
encuentra en la llamada al método createSceneGraph(). El
paso 4, compilar la rama de contenido gráfico, se hace en
la línea 8. Finalmente el paso 5, insertar la rama de
contenido gráfico en el objeto Locale del SimpleUniverse,
se completa en la línea 16.

1. public class HelloJava3D extends Applet {

2. public HelloJava3D() {

3. setLayout(new BorderLayout());

4. Canvas3D canvas3D = new Canvas3D(null);

5. add("Center", canvas3D);

6.

7. BranchGroup scene = createSceneGraph();

8. scene.compile();

9.

10. // SimpleUniverse es una clase Convenience
Utility

11. SimpleUniverse simpleU = new
SimpleUniverse(canvas3D);

12.

13. // Mueve ViewPlatform atrás un bit,
así el objeto de 14. //la escena podrá ser visto
.

15.
simpleU.getViewingPlatform().setNominalViewingTransform();

16.

17. simpleU.addBranchGraph(scene);

18. } // Fin de HelloJava3D (constructor)

Listado 3.1. Fragmento de
HelloJava3D.java.

El paso 3 del algoritmo es crear la rama de contenido
gráfico. Esta rama se crea en el Listado 3.2.
Probablemente sea la rama de contenido gráfico más
sencilla posible. Contiene un objeto gráfico
estático, un ColorCube. Éste está localizado
en el origen del sistema de coordenadas del universo virtual. Con
la localización y orientación dadas de la dirección de la vista del cubo, el cubo
aparece como un rectángulo cuando es renderizado (ver
más adelante).

1. public BranchGroup createSceneGraph() {

2. // Crea la raíz del grafo branch

3. BranchGroup objRoot = new BranchGroup();

4. // Crea un nodo hoja de forma simple,
añadiéndolo al grafo de escena

6. // ColorCube es una clase Convenience
Utility

7. objRoot.addChild(new ColorCube(0.4));

8.

9. return objRoot;

10. } // Fin del método createSceneGraph de
HelloJava3D

Listado 3.2. Método
createSceneGraph de la clase HelloJava3D.

La clase HelloJava3D está derivada de Applet pero
el programa puede ejecutarse como una aplicación con el
uso de la clase MainFrame. Applet se usa como clase base para
hacer más fácil la escritura de
un programa Java3D que se ejecuta en una ventana.

MainFrame proporciona un marco AWT (ventana) para un
applet permitiendo que se ejecute como una aplicación. El
tamaño de la ventana resultante se especifica en la
construcción de la clase MainFrame. El
Listado 3.3 muestra el uso de
MainFrame.

MainFrame crea un applet en una aplicación. Una
clase derivada de Applet podría tener un método
main() que llame al constructor MainFrame. Éste extiende
java.awt.Frame e implementa java.lang.Runnable,
java.applet.AppletStub, y java.applet.AppletContext.

MainFrame(java.applet.Applet applet, int width, int
height) crea un objeto MainFrame que ejecuta un applet como una
aplicación. Sus parámetros son los
siguientes:

  • applet: El constructor de una clase derivada de
    Applet. MainFrame proporciona un marco AWT para este
    applet.
  • width: La anchura de la ventana en
    pixeles.
  • height: La altura de la ventana en
    pixeles.

1. // Permite que el programa sea ejecutado tanto como
una aplicación o como si

2. // fuera un applet

3.

4. public static void main(String[] args) {

5. Frame frame = new MainFrame(new HelloJava3D(),
256, 256);

6. } // Fin de main

7.

8.} // Fin de la clase HelloJava3D

Listado 3.3. Programa principal
para HelloJava3D.

Los tres listados de código anteriores (3.1, 3.2,
y 3.3) forman un programa Java3D completo cuando se usan las
sentencias import adecuadas, en el Listado 3.4 podemos ver las
necesarias para compilar la clase HelloJava3D. Las clases
más comúnmente usadas en Java3D se encuentran en
los paquetes javax.media.j3d, o javax.vecmath. En este ejemplo,
sólo la clase de utilidad ColorCube se encuentra en el
paquete com.sun.j3d.utils.geometry.

Consecuentemente, la mayoría de los programas
Java3D tienen las sentencias import del Listado 3.4 con la
excepción de ColorCube.

1. import java.applet.Applet;

2. import java.awt.BorderLayout;

3. import java.awt.Frame;

4. import java.awt.event.*;

5. import com.sun.j3d.utils.applet.MainFrame;

6. import com.sun.j3d.utils.universe.*;

7. import
com.sun.j3d.utils.geometry.ColorCube;

8. import javax.media.j3d.*;

9. import javax.vecmath.*;

Listado 3.4. Sentencias Import
para HelloJava3D.

En el programa de ejemplo HelloJava3D.java, sólo
se situó un objeto gráfico en una única
localización. En la Figura 3.1 podemos ver el escenario
gráfico resultante.

Figura 3.1. Escenario
gráfico de HelloJava3D.

Compilando y ejecutando el programa obtenemos la
imagen de la
Figura 3.2.

Figura 3.2. El programa
HelloJava3D.java.

La siguiente sección presenta cada una de las
clases usadas en el programa.

3.2 Clases Java3D Usadas
en HelloJava3D.

Para añadir un poco de entendimiento del API
Java3D y el ejemplo HelloJava3D aquí presentamos una
sinopsis de las clases usadas en el programa de
ejemplo.

Clase BranchGroup:

Los objetos de este tipo se usan para formar escenarios
gráficos, son la raíz de los subgráficos,
son los únicos que pueden ser hijos de los objetos Locale,
pueden tener varios hijos, sus hijos pueden ser otros objetos
Group o Leaf. El constructor por defecto es BranchGroup(), estos
ejemplares de BranchGroup sirven como raíz para las ramas
del escenario gráfico; y son los únicos que pueden
insertarse en un conjunto de objetos Locale.

Clase Canvas3D:

La clase Canvas3D deriva de la clase Canvas del AWT. Al
menos un objeto Canvas3D debe ser referenciado en la rama de
vista gráfica del escenario gráfico. Su constructor
es Canvas3D(GraphicsConfiguration graphicsconfiguration),
éste construye e inicializa un nuevo objeto Canvas3D que
el Java3D puede renderizar dando un objeto GraphicsConfiguration
válido.

Clase Transform3D:

Los objetos Transform3D representan transformaciones de
geometrías 3D como una traslación o una
rotación. Normalmente sólo se usan en la
creación de un objeto TransformGroup. Primero, se
construye el objeto Transform3D, posiblemente desde una
combinación de objetos Transform3D. Luego se construye el
objeto TransformGroup usando el objeto Transform3D. Un objeto de
transformación generalizado se representa internamente
como una matriz de 4×4
de punto flotante. La representación matemática
es la mejor forma. Un objeto Transform3D no se usa en un
escenario gráfico. Se usa para especificar la
transformación de un objeto TransformGroup.

El constructor por defecto es Transform3D() el cual
construye un objeto Transform3D que representa la matriz de
identidad (no
la transformación). Cuando se especifica una
rotación, el ángulo se expresa en radianes. Una
rotación completa es 2p
radianes. Una forma de especificar ángulos es usar la
constante Math.PI. Otra forma es especificar los valores
directamente. Algunas aproximaciones son: 45º es 0.785,
90º es 1.57, y 180º es 3.14.

Lista Parcial de Métodos de
Transform3D:

Transform3D es una de las pocas clases que no se usan
directamente en un escenario gráfico. Las transformaciones
representadas por objetos de esta clase se usan para crear
objetos TransformGroup que si se usan en escenarios
gráficos. Algunos de sus métodos son los
siguientes:

  • void rotX(double angle): Selecciona el valor
    de esta transformación a una rotación en contra
    del sentido del reloj sobre el eje X. El ángulo se
    especifica en radianes.
  • void rotY(double angle): Selecciona el valor
    de esta transformación a una rotación en contra
    del sentido del reloj sobre el eje Y. El ángulo se
    especifica en radianes.
  • void rotZ(double angle): Selecciona el valor
    de esta transformación a una rotación en contra
    del sentido del reloj sobre el eje Z. El ángulo se
    especifica en radianes.

Clase TransformGroup:

Como una subclase de la clase Group, los ejemplares de
TransformGroup se usan en la creación de escenarios
gráficos y tienen una colección de objetos nodos
como hijos. Los objetos TransformGroup contienen transformaciones
geométricas como traslaciones y rotaciones. La
transformación normalmente se crea en un objeto
Transform3D, que no es un objeto del escenario gráfico.
Sus constructores son los siguientes:

  • TransformGroup(): Construye e inicializa un
    TransformGroup usando una identidad de
    transformación.
  • TransformGroup(Transform3D t1): Construye e
    inicializa un TransformGroup desde un objeto Transform3D pasado
    como argumento.

La transformación contenida en un objeto
Transform3D se copia a un objeto TransformGroup o cuando se crea
el TransformGroup, o usando el método
setTransform().

El Método void setTransform(Transform3D t1) de
TransformGroup selecciona el componente de transformación
de este TransformGroup al valor de la transformación t1
pasada como argumento.

Clase Vector3f:

Es una clase matemática que se encuentra en el
paquete javax.vecmath para especificar un vector usando tres
valores de punto flotante. Los objetos Vector se usan
frecuentemente para especificar traslaciones de
geometrías. Los objetos Vector3f no se usan directamente
en la construcción de un escenario gráfico. Se usan
para especificar las traslaciones, superficies normales, u otras
cosas. Sus constructores son los siguientes:

  • Vector3f(): Construye e inicializa un Vector3f
    a (0,0,0).
  • Vector3f(float x, float y, float z): Construye
    e inicializa un Vector3f desde las coordenadas X, Y, Z
    especificadas.

Clase ColorCube:

ColorCube es una clase de utilidad que se encuentra en
el paquete com.sun.j3d.utils.geometry que define la
geometría y colores de un
cubo centrado en el origen y con diferentes colores en cada cara.
El objeto ColorCube es un cubo que tiene 2 metros de arista. Si
un cubo sin rotar se sitúa en el origen (como en
HelloJava3D), se verá la cara roja desde la
localización de visión nominal. Los otros colores
son azules, magenta, amarillos, verdes y cian. Sus constructores
los mencionamos en seguida:

  • ColorCube(): Construye un cubo de color y
    tamaño por defecto. En este caso, una esquina
    está situada a un metro de cada uno de los ejes desde el
    origen, resultando un cubo que está centrado en el
    sistema de coordenadas y tiene 2 metros de alto, de ancho y de
    profundo.
  • ColorCube(double scale): Construye un cubo de
    color escalado por el valor especificado. El tamaño por
    defecto es 2 metros de lado. El ColorCube resultante tiene
    esquinas en (scale, scale, scale) y (-scale, -scale,
    -scale).

3.3. Listado Completo de
HelloJava3D.

Para finalizar, simplemente listamos el código
completo.

  1. import java.applet.Applet;
  2. import java.awt.BorderLayout;
  3. import java.awt.Frame;
  4. import java.awt.event.*;
  5. import java.awt.GraphicsConfiguration;
  6. import
    com.sun.j3d.utils.applet.MainFrame;
  7. import com.sun.j3d.utils.universe.*;
  8. import
    com.sun.j3d.utils.geometry.ColorCube;
  9. import javax.media.j3d.*;
  10. import javax.vecmath.*;
  11. // HelloJava3D dibuja un único cubo que
    rota.
  12. public class HelloJava3D extends Applet {
  13. public HelloJava3D() {
  14. setLayout(new BorderLayout());
  15. GraphicsConfiguration config =
    SimpleUniverse.getPreferredConfiguration();
  16. Canvas3D canvas3D = new Canvas3D(config);
  17. add("Center", canvas3D);
  18. BranchGroup scene = createSceneGraph();
  19. // SimpleUniverse es una clase Convenience
    Utility
  20. SimpleUniverse simpleU = new
    SimpleUniverse(canvas3D);
  21. // Mueve ViewPlatform atrás un bit, así
    el objeto de la escena podrá ser visto
  22. simpleU.getViewingPlatform().setNominalViewingTransform();
  23. simpleU.addBranchGraph(scene);
  24. } // Fin de HelloJava3D (constructor)
  25. public BranchGroup createSceneGraph() {
  26. // Crea la raíz del grafo branch
  27. BranchGroup objRoot = new BranchGroup();
  28. objRoot.addChild(new ColorCube(0.4));
  29. return objRoot;
  30. } // Fin del método CreateSceneGraph de
    HelloJava3D
  31. // Permite que el programa sea ejecutado tanto como
    aplicación como un applet
  32. public static void main(String[] args) {
  33. Frame frame = new MainFrame(new HelloJava3D(), 256,
    256);
  34. } // Fin de main (método de
    HelloJava3D)
  35. } // Fin de la clase HelloJava3D

Listado 3.5. Código
completo de HelloJava3D.

4. Transformaciones.

En el capítulo anterior creamos un cubo, pero
cuando lo ejecutamos parecía simplemente un cuadrado rojo,
si necesitáramos algo así no tendría caso
usar Java3D y bastaría con recurrir a Java2D. En el
capítulo presente vamos a usar unos cuantos métodos
de transformaciones que harán que ese cubo parezca un
verdadero cubo, para ello, modificaremos el código que se
presentó en el Listado 3.5.

4.1. Rotación
Simple: HelloJava3Da.java.

La simple rotación de un cubo puede ser hecha
para mostrar varias de sus caras. El primer paso es crear la
transformación deseada usando un objeto del tipo
Transform3D.

El listado 4.1 incorpora un objeto TransformGroup en el
escenario gráfico para rotar el cubo sobre el eje X. La
transformación de rotado es creada en la línea 6.
La rotación se especifica usando el método rotX()
en la línea 8. El objeto TransformGroup es creado en la
línea 10 en base al objeto de rotado que queremos y que se
creó en la línea 6.

Dos parámetros especifican la rotación: El
eje de rotado y el ángulo de rotación. El eje es
seleccionado usando el método apropiado (rotX, rotY,
rotZ). El valor del ángulo es dado en el método
empleado. Nosotros estamos rotando 45 grados.

El objeto objRotate genera el ColorCube como su hijo
(línea 11). Finalmente, el objRoot hace a objRotate su
hijo (línea 12).

1. public BranchGroup createSceneGraph() {

2. //Crea la raíz del grafo branch

3. BranchGroup objRoot = new BranchGroup();

5. // Objeto para rotar

6. Transform3D rotate = new Transform3D();

7.

8. rotate.rotX(Math.PI/4.0d);

9.

10. TransformGroup objRotate = new
TransformGroup(rotate);

11. objRotate.addChild(new ColorCube(0.4));

12. objRoot.addChild(objRotate);

13. return objRoot;

14. } // Fin createSceneGraph

Listado 4.1. Rotación
simple de un cubo.

El grafo resultante del Listado 4.1 puede verse en la
Figura 4.1, en ella es más notoria la
transformación, tenemos el nodo raíz de nuestro
escenario BG, en ese nodo aplicamos el grupo de
transformaciones TG, el cual tiene un nodo hijo, ColorCube, que,
por tanto, tendrá los mismos cambios que su padre, en
nuestro caso una simple rotación de 45º.

Sustituyendo el método createSceneGraph() del
Listado 4.1 en HelloJava3D.java, y cambiando el nombre de la
clase y del archivo a
HelloJava3Da.java obtenemos el resultado de la Figura 4.2
después de compilar y ejecutar, en él ya notamos la
cara superior del objeto.


4.2. Combinando Transformaciones:
HelloJava3Db.java.

Ahora vamos a aplicar dos transformaciones sobre el cubo
de HelloJava3Da, a este ejemplo le llamamos HelloJava3Db,
nuevamente debemos modificar el método createSceneGraph().
Para este caso hay dos transformaciones diferentes las cuales
pueden ser combinadas en una sola.

Dos rotaciones son combinadas en el Listado 4.2. Hacer
estas dos operaciones
simultáneas requiere mezclar dos objetos Transform3D de
rotación. En el ejemplo se rota el cubo en torno a los ejes
X y Y. Los objetos Transform3D, uno para cada rotación,
son creados en las líneas 6 y 7. Las rotaciones
individuales son especificadas por dos objetos TransformGroup
(líneas 9 y 10). Entonces, las rotaciones son combinadas
usando el método mul() en la línea 11. Por
último, la combinación es colocada en el objeto
TransformGroup (línea 12).

El resultado de estas transformaciones lo vemos en la
Figura 4.3. Cabe decir que este es un ejemplo muy sencillo donde
damos a conocer un poco de transformaciones, sin embargo, hay
muchas otras que también se pueden combinar y que es
imposible presentar aquí, éstas incluyen
trasladado, escalado, etc.

1. public BranchGroup createSceneGraph() {

2. //Crea la raíz del grafo branch

3. BranchGroup objRoot = new BranchGroup();

4.

5. // Objetos para combinar

6. Transform3D rotate = new Transform3D();

7. Transform3D tempRotate = new
Transform3D();

8.

9. rotate.rotX(Math.PI/4.0d);

10. tempRotate.rotY(Math.PI/5.0d);

11. rotate.mul(tempRotate);

12. TransformGroup objRotate = new
TransformGroup(rotate);

13.

14. objRotate.addChild(new ColorCube(0.4));

15. objRoot.addChild(objRotate);

16. return objRoot;

17.}//Fin del método.

Listado 4.2. Combinando dos
rotaciones.

Figura 4.3. Combinando
transformaciones.

5. Animación: Behavior.

En Java3D, Behavior es una clase para especificar
animaciones o interacción con objetos visuales. El
comportamiento
puede cambiar virtualmente cualquier atributo de un objeto. Un
comportamiento es especificado por un objeto visual, Java3D
actualiza la posición, orientación, color u otros
atributos.

La diferencia entre animación e
interacción es que la primera responde a ciertos
eventos con el
transcurso del tiempo, en
cambio, la
segunda responde a las actividades del usuario.

Cada objeto visual en el universo virtual puede tener su
propio comportamiento definido. De hecho, pueden tener varios
comportamientos. Para especificar un comportamiento de un objeto
visual, el programador deberá crear los objetos que
especifiquen el comportamiento, agregar el objeto visual al
escenario gráfico y hacer las referencias apropiadas entre
los objetos del escenario y los objetos de
comportamientos.

Un interpolador es un número predefinido
de clases y subclases Behavior en el paquete de Java3D. Basado en
una función de
tiempo, el objeto interpolador manipula los parámetros de
los objetos en el escenario gráfico. Por ejemplo, la clase
RotationInterpolator, manipula la rotación especificada
por un TransformGroup para generar la rotación de los
objetos visuales.

Al igual que hicimos en el capítulo 2, damos el
Algoritmo 5.1 para guiarnos en la construcción de
animaciones con Java3D, sus detalles se aclararán con un
ejemplo más adelante:

1. Crear una instancia de TransformGroup.

a. Establecer la capacidad
ALLOW_TRANSFORM_WRITE.

2. Crear un objeto Alpha.

a. Especificar los parámetros de tiempo para
Alpha.

3. Crear el objeto interpolador.

a. Teniendo una referencia a los objetos Alpha y
TransformGroup, optimizar los parámetros de
comportamientos.

4. Especificar la región de
planeación

a. Establecer la región de planeación
para el comportamiento.

5. Hacer al comportamiento un hijo del
TransformGroup.

Algoritmo 5.1. Construcción
de animaciones en Java3D.

5.1. Especificando El
Comportamiento.

Una acción
de comportamiento puede ser un cambio en la posición
(PositionInterpolator), orientación
(RotationInterpolator), tamaño (ScaleInterpolator), color
(ColorInterpolator), o transparencia (TransparencyInterpolator)
de un objeto visual. Como se mencionó anteriormente, los
interpoladores son clases de comportamientos predefinidas. Todo
tipo de comportamientos pueden generarse sin interpoladores
usando la animación clásica de Java, sin embargo,
los interpoladores hacen estas tareas mucho más
fáciles. Las clases de interpolación existen para
proporcionar otras acciones, incluyendo combinaciones de ellas.
La clase RotationInterpolator es usada más adelante como
ejemplo.

Clase RotationInterpolator:

Esta clase es usada para especificar una rotación
como comportamiento. Un objeto RotationIterpolator cambia un
TransformGroup para especificar la rotación en respuesta
al valor de un objeto Alpha. Dicho valor puede cambiar con el
transcurso del tiempo. Un RotationInterpolator es flexible en su
especificación la cual consiste en definir el eje de
rotación y los ángulos inicial y final.

5.2. Variaciones de Tiempo
Y Región de Planeación.

Para mapear una acción a cierto intervalo de
tiempo debemos usar un objeto de la clase Alpha. La
especificación de este objeto puede ser compleja,
aquí presentamos la información básica para
poder
hacerlo.

Clase Alpha:

Los objetos de la clase Alpha son usados para crear una
función de variación en el tiempo. Esta clase
produce un valor entre cero y uno que depende del tiempo y los
parámetros del objeto Alpha. Los objetos de esta clase son
usados frecuentemente con interpoladores para completar
animaciones.

En el paso cuatro del Algoritmo 5.1, se menciona que
debemos especificar la región de planeación,
esto se hace, en términos prácticos, para mejorar
el rendimiento de nuestra animación y no haya demasiados
problemas si
contamos con una PC poco poderosa. Para conseguir esto nos
valemos del método setSchedulingBounds de la clase
Behavior.

Hay varias formas de definir una región de
planeación, una de ellas es crear un objeto
BoundingSphere.

Esta región de planeación nos sirve para
que sólo cuando un objeto sea visible pueda mostrar el
comportamiento que le fue asignado, no tendría caso gastar
tiempo de CPU procesando
objetos que el usuario no ve. De esta forma es como Java3D logra
mejorar el rendimiento.

5.3. Ejemplo De
Animación: HelloJava3Dc.

Nuevamente vamos a trabajar sobre el programa
HelloJava3D en su método createSceneGraph(), le llamaremos
HelloJava3Dc.java.

El Listado 5.1 muestra un ejemplo del uso de las clases
de interpolación para crear una animación.
Simplemente se realiza una rotación completa continua
durante cuatro segundos. Obsérvese que éste
código corresponde al Algoritmo 5.1 dado al inicio del
capítulo.

El paso 1 del algoritmo es crear un objeto
TransformGroup con la capacidad ALLOW_TRANSFORM_WRITE habilitada.
El objeto TransformGroup es llamado objSpin y se crea en la
línea 7. La capacidad de objSpin es establecida en la
línea 8.

1. public BranchGroup createSceneGraph() {

2. // Crea la raíz del grafo

3. BranchGroup objRoot = new BranchGroup();

4.

5. // Crea e inicializa el grupo de
transformación,

6. // lo agrega a el subgrafo

7. TransformGroup objSpin = new
TransformGroup();

8.
objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

9. objRoot.addChild(objSpin);

10.

11. // Crea una hoja y la agrega al escenario

12. // ColorCube es una clase de utilidad
Convenience

13. objSpin.addChild(new ColorCube(0.4));

14.

15. // Crea una funcion de variación en el
tiempo

16. Alpha rotationAlpha = new Alpha(-1,
4000);

17.

18. // Crea un Nuevo comportamiento

19. // se especifican la operación y el grupo de
transformación

20.

21. RotationInterpolator rotator =

22. new RotationInterpolator(rotationAlpha,
objSpin);

23.

24. //Se especifica la región de
planeación

25. BoundingSphere bounds = new
BoundingSphere();

26. rotator.setSchedulingBounds(bounds);

27. objSpin.addChild(rotator);

28.

29. return objRoot;

30. } // fin del método
createSceneGraph

Listado 5.1.
Hellojava3Dc.

El paso 2 nos dice que debemos crear un objeto Alpha
para manejar el interpolador, en el ejemplo, rotationAlpha es
usado para especificar una rotación continua, los
parámetros se dan en la línea 16, el primero es el
número de iteraciones (- 1 para
un ciclo continuo), el segundo para el tiempo de cada ciclo (4000
milisegundos = 4 segundos).

El paso 3 indica la creación del interpolador. El
objeto RotationInterpolator para rotar se genera en las
líneas 21 y 22. The interpolator must have references to
the target transform and alpha objects. Los parámetros de
su constructor deben ser el objeto Alpha y el grupo de
transformación creados con anterioridad. En este ejemplo
se usa el comportamiento predefinido de RotationInterpolator el
cual genera una rotación completa alrededor del eje
Y.

Especificar la región de planeación se
lleva a cabo en el paso 4 del algoritmo, en nuestro código
corresponde a las línea 25 y 26. Un objeto BoundingSphere
es empleado para este propósito con su constructor por
defecto.

El quinto y último paso hace al comportamiento
hijo del grupo de transformación, en el Listado 5.1 esto
se observa en la línea 27.

HelloJava3Dc crea el grafo de escena mostrado en la
Figura 5.1. Por su parte, la Figura 5.2 muestra varias vistas de
la animación hecha.

Figura 5.1. Grafo de
HelloJava3Dc.

 

Figura 5.2. HelloJava3Dc
ejecutándose.

5.4. Combinación de
Transformaciones y Comportamientos:
HelloJava3Dd.

Similar a lo que hicimos antes, podemos generar una
combinación de transformaciones y comportamientos. En
HelloJava3Dd.java veremos cómo. En los ejemplos anteriores
utilizamos los objetos objRotate (HelloJava3Db, Listado 4.2) y
objSpin (HelloJava3Dc, Listado 5.1), la diferencia entre ellos es
que el primero se utiliza para realizar una rotación
estática, mientras que el segundo para una
rotación continua. El Listado 5.2 muestra el código
modificado de createSceneGraph() para hacer una
combinación de transformaciones y comportamientos usando
los objetos mencionados.

El proceso a seguir es bastante fácil, primero
hacemos lo mismo que en el Listado 4.2, combinar las
transformaciones para ver varias caras del cubo (líneas 6
a 13), y posteriormente indicamos la rotación continua
igual que en el Listado 5.1 (líneas 19 a 43).

Nótese que simplemente fue agregar al Listado 4.2
el código del Listado 5.1.

En la Figura 5.3 se muestra el grafo resultante, y en la
Figura 5.4 una serie de imágenes que representan algunos
movimientos del cubo (obsérvese la diferencia con la
Figura 5.2).

1. public BranchGroup createSceneGraph() {

2. // Crea la raíz del grafo

3. BranchGroup objRoot = new BranchGroup();

4.

5. // Objetos a combinar

6. Transform3D rotate = new Transform3D();

7. Transform3D tempRotate = new
Transform3D();

8.

9. rotate.rotX(Math.PI/4.0d);

10. tempRotate.rotY(Math.PI/5.0d);

11. rotate.mul(tempRotate);

12.

13. TransformGroup objRotate = new
TransformGroup(rotate);

14.

15. // Crea e inicializa el grupo de
transformación,

16.

17. // lo agrega a el subgrafo

18.

19. TransformGroup objSpin = new
TransformGroup();

20.
objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

21.

22. objRoot.addChild(objRotate);

23. objRotate.addChild(objSpin);

24.

25. // Crea una hoja y la agrega al escenario

26. // ColorCube es una clase de utilidad
Convenience

27. objSpin.addChild(new ColorCube(0.4));

28.

29. // Crea un Nuevo comportamiento

20.

31. // se especifican la operación y el grupo de
transformación

32.

33. Alpha rotationAlpha = new Alpha(-1,
4000);

34.

35. RotationInterpolator rotator = new

36. RotationInterpolator(rotationAlpha,
objSpin);

37.

38.

39. //Se especifica la región de
planeación

40.

41. BoundingSphere bounds = new
BoundingSphere();

42. rotator.setSchedulingBounds(bounds);

43. objSpin.addChild(rotator);

44.

45. return objRoot;

46. } // Fin de createSceneGraph

Listado 5.2. Código para
combinar transformaciones.

Figura 5.3. Grafo para
HelloJava3Dd.

 

Figura 5.4. HelloJava3Dd
ejecutándose.

Bibliografía.

  1. Advanced Animation and Rendering Techniques.
    Theory and Practices.
    Alan Watt and Mark Watt.
    New York, Addison Wesley Pub Company.
  2. Interactive Control for
    Physically – Based Animation, in Computer Graphics
    Proceedings.
    Joseph Laszlo, Michiel van de Panne, Eugene
    Fiume. Annual Conference Series, 2000.
  3. Inbetweening for Computer Animation Utilizing
    Moving Point Constaints.
    Reeves, W. T. SIGGRAPH 81,
    263-269.
  4. Adapting Simulated Behaviors For New Characters,
    en Computer Graphics.
    Jessica K. Hodgins and Nancy S.
    Pollard. (SIGGRAPH 97 roceedings), pp. 153-162, Addison Wesley,
    Agosto de 1997.
  5. Computer Graphics Principles and Practice,
    Second Edition. J. D. Foley, A. van Dam, S.K. Feiner and J.F.
    Hughes. Addison Wesley Pub Company, 1990.
  6. Bubblesort-Animation. Barbu, A., Dromowicz,
    M., Gao, X., Koester, M., and Wolf, C. 1998. Disponible
    en http://www-cg-hci.informatik.unioldenburg.de/˜da/fpsort/Animation.html.
  7. G. Collection of ANIMAL Animations.
    R¨oßling, 1999. Disponible en .
  8. Approaches for Generating Animations for
    Lectures.
    R¨oßling, G., and Freisleben, B.
    Proceedings of the 11th International Conference of
    the Society for Information Technology and Teacher Education
    (SITE 2000) (2000), 809–814.
  9. Experiences In Using Animations in Introductory
    Computer Science Lectures.
    R¨oßling, G., and
    Freisleben, B. SIGCSE 2000 Proceedings (2000). To
    Appear.
  10. Using Student-built Algorithm Animations as
    Learning Aids.
    Stasko, J. SIGCSE Session Proceedings
    (February 1997), 25–29.
  11. Introducción a la Graficación por
    Computador.
    Foley, Dam, Feiner, Hughes,
    Philips. Addisson Wesley Iberoamericana, 1996.
  12. Graficas por Computadora. Hearn/Baker. Printice Hall,
    1995.
  13. 3D Computer Graphics, Tercera edición. Alan Watt. Addison Wesley,
    2000.
  14. 3D Computer Animation. J. Vince. Addison
    Wesley, 1992.
  15. The Animator's Workbook. Editorial
    Watson-Guptill Publication.
  16. Animation cartoon. Preston Blair. Editorial
    Icara.
  17. Digital Texturing & Lightning. Owen
    Demers. Editorial New Riders.
  18. Generación electrónica de imágenes.
    Levitan, Eli L. Ediciones Bellatera S.A. Barcelona.
  19. Wikipedia entry about Animation,
    www.wikipedia.org/wiki/Animation
  20. The Aardman Book of 3D−Animation.
    ISBN 0500018812 o ISBN 0810919966.
  21. Gimp Animation Tutorial. www.jimmac.musichall.cz/tutor.php3.
  22. Gimp Tutorials. www.gimp.org/tutorials/
  23. Brickfilms. www.brickfilms.com
    (dedicado a películas de detenimiento de movimiento
    con ladrillos y figuras Lego.
  24. Gráficos con Java 2D. Juan Antonio
    Palos. http://java.programacion.com/
    Versión Original en Ingles en http://java.sun.com
  25. Java Swing Draw. Alfredo Casado
    Bernardez. http://creativecommons.org
  26. Java Programming Language Guide.
    Bloch, J. Effective, 2001.
  27. Documentación completa y descarga de Java y
    Java3D.
    http://java.sun.com/docs/
  28. Thinking in Java. Bruce Eckel. http://www.planetpdf.com/,
    http://www.codecuts.com/,
    http://www.pdfforum.com/,
    http://www.pdfstore.com/.
    Prentice Hall, 2000.
  29. Aprenda Java como si estuviera en primero.
    Javier García de Jalón. Campus Tecnológico
    de la Universidad
    de Navarra. 2000. www.tecnum.es
  30. Java desde Cero. www.cybercursos.net
  31. TutorJava Nivel Básico.
    Juan Antonio Palos. http://java.programacion.com/
    Versión Original en Ingles en http://java.sun.com
  32. Getting Started with the Java3D™
    API.
    Dennis J Bouvier. www.sun.org
  33. Visualization of object-oriented design
    models
    . Master’s thesis. Sunita Asija. Depaul
    University, Chicago, USA, December 1999.
  34. Visualizing object-oriented software in
    virtual reality
    . Jonathan I. Maletic. 2001.
  35. The Java3D API Specification. Henry Sowizral.
    Addison Wesley, second edition, 2000.

 

Luis Antonio Fernández Aldana

Parte del Proyecto de
Servicio
Social:

Evaluación de las Herramientas
para el Desarrollo de
Software Multimedia.

México.

Enero 2007.

Acerca del Autor: Luis Antonio Fernández
Aldana egresó de la Facultad de Ciencias de la
Computación de la Benemérita
Universidad Autónoma de Puebla, México, en
2006, se ha dedicado en su formación a el área de
multimedia, diseño y programación Web, le gusta
compartir sus conocimientos lo cual se ve reflejado en los
diversos trabajos que ha publicado gratuitamente en Internet.

Contacto: Sugerencias, comentarios y solicitud de
la edición original de este y otros trabajos similares
a
y http://lamar.cs.buap.mx/~lafa

Nota: El software y otros elementos que
aquí se describen o mencionan están protegidos por
las correspondientes leyes de derechos de
autor. Este manual es de
libre distribución y se ha hecho como parte del proyecto
de servicio social "Evaluación
de las herramientas para la realización de software
multimedia" de la Facultad de Ciencias de la Computación,
Benemérita Universidad Autónoma de Puebla,
México. Este trabajo se
terminó de elaborar el 31 de Enero del 2007.

Partes: 1, 2, 3
 Página anterior Volver al principio del trabajoPágina siguiente 

Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

Categorias
Newsletter