Sei sulla pagina 1di 24

1

VRML 2.0 con Java CAPÍTULO 21

Particionado especial

Contenido CAPÍTULO 21
2

VRML 2.0 con Java CAPÍTULO 21

• ¿Cómo Particionado espacial de Obras


• La creación de Nuestro Mundo
• Cajas de la envolvente
• Árboles BSP
• El proyecto del MIT Quake

¿Cómo espacial Particionado de Obras

Una de las razones principales navegadores VRML parecen ser tan lento,
especialmente para las escenas de interior, como la construcción de interiores,
3

VRML 2.0 con Java CAPÍTULO 21

es que deben hacer (en otras palabras, dibujar) todo en el mundo entero. Si el
usuario está en una pequeña habitación junto a una gran sala de conciertos, el
navegador debe sacar cada silla, cada pliegue de la cortina, todas las puertas y
el hueco de la escalera y barandilla en la sala de conciertos, aunque el usuario
no puede ver cualquiera de esos objetos. Esto debe hacerse para cada marco
el ordenador hace que, por lo que el número de fotogramas por segundo que
pueden ser generados es muy pequeño. Bajos índices de marco no sólo que el
mundo sea menos divertido de explorar, también pueden hacer casi imposible
para navegar por el medio ambiente.

El uso de LOD (Nivel de detalle) nodos puede ayudar un poco, pero funcionan
estrictamente en función de la distancia y por lo tanto son de uso limitado en
este tipo de situación. Más importante aún, son de poca utilidad en las escenas
de interior donde hay un alto nivel de complejidad de profundidad.

Idealmente, nunca quieren sacar todo lo que el usuario no puede ver. Podemos
acercarnos a este objetivo mediante el uso de una técnica conocida como
partición espacial.

Obras de compartimentación espacial teniendo un volumen de espacio y


subdividir en regiones más pequeñas y, a continuación, la informática de
región a región visibilidad de la información. En un momento dado, sólo un
subconjunto del total de medio ambiente tiene que ser visible para el usuario,
lo que reduce drásticamente la cantidad de la prestación que se debe hacer y,
por tanto, aumenta la velocidad de cuadro.

Por ejemplo, la planta se muestra en la Figura 21.1.

Figura 21.1 Una simple planta

Si el usuario está en el cuarto llamado "taller", que son capaces de ver el


garaje, el área de almacenamiento, la alcoba y la cocina. No son capaces de
ver la sala de estar, dormitorio, baño, porche delantero o, por lo que esas
zonas no tienen que ser extraído. Si el usuario se mueve en la cocina, que ya
no será capaz de ver el garaje, pero ahora podrán ver el salón y porche. Tenga
en cuenta que aunque la planta se muestra en la Figura 21.1 es de dos
dimensiones, las propias regiones son tridimensionales. Por ejemplo, ninguno
de los dormitorios en la planta superior de la casa sería visible desde la
mayoría de las habitaciones en la planta principal.

NOTA: Si esta descripción de la ordenación del territorio particionado suena


familiar, es porque es muy similar a nuestro debate sobre el uso de las
regiones para el filtrado de las actualizaciones en un entorno multiusuario en
4

VRML 2.0 con Java CAPÍTULO 21

los capítulos 18 y 19. Si el usuario no puede ver la sala del taller, entonces no
sólo no tenemos para hacerlo, también no tiene que enviar las actualizaciones
de cualquiera de las entidades en el salón.

Hay una serie de diferentes enfoques de la partición territorial. Los más


importantes son saltando cajas, quadtrees, octtrees, y la BSP árboles. BSP
árboles son el método más comúnmente usado en juegos de ordenador, tales
como Quake.

Independientemente del método que se utilice, la técnica básica es la misma.


En cada cuadro, el usuario es el punto de vista de ubicación, frente a un
conjunto de estructuras de datos con el fin de determinar que la región que se
encuentra el usuario Una vez que esta región se encuentra, el conjunto de las
regiones visible se identifica, y aquellas regiones que no son visibles se marcan
como ocultos. En VRML, el ocultamiento se logra usando un nodo Switch
whichChoice cuyo eventIn se establece en -1 para una región oculta.

Dado que toda la región a región, la visibilidad se ha calculado previamente, la


cantidad real de cálculo que ha de hacerse sobre una base por-marco es muy
pequeño, especialmente cuando se compara con el gasto de la prestación del
medio ambiente que no puede ser visto.

En este capítulo, vamos a examinar dos de las estructuras de datos que se


utilizan comúnmente: saltando cajas y árboles BSP. Vamos a mostrar cómo se
pueden aplicar en estándar VRML 2.0 y Java. Si estás interesado en saber más
acerca de otras técnicas, tales como árboles y quad octtrees, echa un vistazo a
cualquier libro de texto estándar de gráficos, tales como la infografía, los
Principios y Práctica de Foley y van Dam (Addison-Wesley, 1990).
Construyendo Nuestro Mundo

El primer paso en la utilización de cualquier esquema de particionamiento


espacial consiste en diseñar el mundo de tal manera que pueda ser eficiente
dividido en regiones. Tenga en cuenta que no todos los mundos se prestan a
este tipo de descomposición, si tu mundo es un gran desierto llano abierto,
entonces lo que estaría mejor en lugar de utilizar LD espacial particionado.

Hasta la división de habitaciones

Empezaremos nuestra planta tomando ejemplo de las anteriores y en la


construcción de cada habitación como un archivo VRML. Vamos a ponerlos
juntos en un solo mundo usando nodos en línea:

# VRML V2.0 utf8


5

VRML 2.0 con Java CAPÍTULO 21

Punto de vista de la posición (0 22 20 orientación 1 0 0 -0,7854)

Transformar la traducción (0 0 0,0


los niños en línea (url "living.wrl")
)

Transformar la traducción (-8 0 3,5


los niños en línea (url "garage.wrl")
)

Transformar la traducción (-10 0 -3,5


los niños en línea (url "storage.wrl")
)

Transformar la traducción (-6 0 -3,5


los niños en línea (url "workshop.wrl")
)

Transformar la traducción (-2 0 -5,0


los niños en línea (url "alcove.wrl")
)

Transformar la traducción (4,5 0 -5,0


los niños en línea (url "kitchen.wrl")
)

Transformar la traducción (6,5 0 -1,5


los niños en línea (url "bathroom.wrl")
)

Transformar la traducción (6,5 0 1,5


los niños en línea (url "closet.wrl")
)

Transformar la traducción (2,5 0 5,0


los niños en línea (url "porch.wrl")
)

Los nodos de transformación se usan sólo para la posición de habitaciones


individuales en la casa. Esto tiene la ventaja de que cada habitación se puede
reutilizar en otros mundos, si es necesario.

Cada habitación está hecha de una serie de segmentos de la pared y la puerta


6

VRML 2.0 con Java CAPÍTULO 21

segmentos, así como un piso. Nos aseguramos de que estos objetos son una
sola cara mediante el establecimiento de la bandera a TRUE sólidos en sus
IndexedFaceSet representación. Esto nos permite mirar en las habitaciones
desde el exterior, por ejemplo, la Figura 21.2 se muestra la sala de estar.

Figura 21.2 El salón

Figura 21-3 muestra una vista aérea de la planta principal de toda la casa.
Tenga en cuenta que no hay techo y las paredes exteriores son visibles sólo
desde el interior.

Figura 21.3 El toda la casa

Vamos a estar usando esta estructura básica de nuestra caja y la BSP ejemplos.

Cajas de la envolvente

La envolvente de cajas de la técnica más simple para la ordenación del


territorio de particionado. Se aprovechan del hecho de que es
matemáticamente sencillo para determinar si una x, y, z es la ubicación dentro
o fuera de una caja: Usted simplemente comparar cada uno de coordinar a los
valores mínimo y máximo de la caja a lo largo del eje correspondiente.

Cajas se prestan bien a los espacios interiores, tales como la planta que miró
antes, ya que la mayoría de las habitaciones son en forma de caja (cuatro
paredes y el suelo y el techo).

Hay algunas optimizaciones importante que se puede hacer en la búsqueda de


la casilla que el usuario que se encuentra la ubicación del usuario es la primera
en comparación con el mínimo de la ubicación en un eje. Si es menor que el
valor mínimo, sin necesidad de controles más que hacer en esa caja. Esta
7

VRML 2.0 con Java CAPÍTULO 21

rápida comprobación es importante, desde el interior de un complejo entorno


podría tener cientos o incluso miles de cajas.
Nodo de la Región

Vamos a aplicar nuestra caja visibilidad utilizando un algoritmo de VRML


prototipo que vamos a llamar Región.

Cada Región tendrá un seguimiento de si es visible o no mediante un simple


contador implementado en Java. El contador registra el número de otras
regiones que puede ver la región, si el contador es cero, entonces la Región
está oculto. El código de este PROTO se basa en un diseño de Mitra, del párrafo
Internacional:

# VRML V2.0 utf8

# Prototipo de una caja en forma de región

PROTO Región [# Prototipo de una caja en forma de región


campo SFVec3f bboxCenter 0 0 0
campo SFVec3f bboxSize 0 0 0
eventIn SFBool seenBy
eventOut SFBool canSee
campo MFNode niños []
](

DEF SW Switch (
whichChoice -1
Grupo de elección (
bboxCenter ES bboxCenter
bboxSize ES bboxSize
los niños son los niños
)
)

ProximitySensor (
centro bboxCenter
El tamaño es bboxSize
isActive se canSee
)

Guión (DEF SC
url "Region.class"
eventIn SFBool countThese ES seenBy
eventOut SFInt32 showChildren
8

VRML 2.0 con Java CAPÍTULO 21

VÍA SC.showChildren A SW.whichChoice

) # Fin de PROTO

La Región de caja se define utilizando la bboxCenter y bboxSize valores. Estos


deben estar familiarizados, ya que estamos acostumbrados en una serie de
nodos de VRML estándar, como grupo y ProximitySensor. El contenido de la
Región se almacenan en sus niños sobre el terreno, y la visibilidad de los
contenidos se controla mediante el nodo Switch SW.

El canSee eventOut es impulsada por el ProximitySensor. Cuando el usuario se


encuentra dentro de la Región, la Región canSee eventOut es TRUE, y cuando
están fuera de la Región, la Región canSee eventOut es FALSE. Este canSee
eventOut será encaminado a la seenBy eventIn para las regiones que puede
verse en esta Región.

El seenBy eventIn va a un nodo de secuencias de comandos, lo que mantiene


la cuenta del número de regiones que esta Región es visto por. Si el contador
es cero, la Región debe ser el contenido oculto. Si el contador es mayor que
cero, la Región es visible. Los comandos de los controles de la visibilidad de los
contenidos mediante el uso de la showChildren eventOut, que será -1 cuando
el contenido debe ser oculto y 0 cuando debería ser visible. SFInt32 una se
utiliza en lugar de un SFBool, ya que este valor se dirige directamente a la
whichChoice eventIn del nodo Switch.

El nodo de secuencias de comandos se ejecuta en Java, y que tiene este


aspecto:

importación vrml .*;


importación vrml.field .*;
importación vrml.node .*;

clase pública se extiende la región de secuencias de comandos (


SFInt32 showChildren privado;
private int count = 0;

public void inicializar () (


showChildren = (SFInt32) getEventOut ( "showChildren");
)

public void processEvent (Event e) (


if (e.getName (). es igual a ( "countThese")) (
9

VRML 2.0 con Java CAPÍTULO 21

En ConstSFBool = (ConstSFBool) e.getValue ();


count + = (in.getValue ())? 1: -1;
showChildren.setValue ((cuenta> 0)? 0: -1);
)
)

El inicializar () método lee y guarda la showChildren eventOut, ya que


estaremos utilizando más tarde. Esto se hace sólo en aras de la eficiencia.

El processEvent () método responde a la entrada de countThese eventos


mediante la adición de 1 a un contador si el evento es cierto y -1 a la contra si
el caso es FALSE. Si el contador es mayor que cero (es decir, al menos otra
región se puede ver uno), entonces la showChildren eventOut se establece en
cero, lo que hará que los niños de la Switch visibles. En caso contrario, el
showChildren eventOut se establece en -1, lo que esconden a los niños de la
Switch.

Nodo de la Región en el trabajo

Vamos a echar otro vistazo a nuestra planta ejemplo. Vamos a tratar cada una
de las habitaciones como una región, por lo que nos rodean la Región
Transformar nodos con nodos y añadir rutas a especificar de región a región
visibilidad:

# VRML V2.0 utf8

EXTERNPROTO Región [# Prototipo de una caja en forma de región


SFVec3f bboxCenter campo
SFVec3f bboxSize campo
eventIn SFBool seenBy
eventOut SFBool canSee
campo MFNode niños []
] "Region.wrl"

Punto de vista de la posición (0 1,5 0)

DirectionalLight (dirección 1 -1 1)
DirectionalLight (dirección -1 -1 -1)

# Defina las distintas regiones


10

VRML 2.0 con Java CAPÍTULO 21

DEF Almacenamiento Región (


bboxSize 4 3 7 bboxCenter -10 0 -3,5
los niños de transformación (
traducción -10 0 -3,5
los niños en línea (url "storage.wrl")
)
)

Taller Región (DEF


bboxSize 4 3 7 bboxCenter -6 0 -3,5
los niños de transformación (
traducción -6 0 -3,5
los niños en línea (url "workshop.wrl")
)
)

Región (DEF Alcoba


bboxSize 4 3 4 bboxCenter -2 0 -5,0
los niños de transformación (
traducción -2 0 -5,0
los niños en línea (url "alcove.wrl")
)
)

Cocina Región (DEF


bboxSize 9 3 4 bboxCenter 4,5 0 -5,0
los niños de transformación (
traducción 4,5 0 -5,0
los niños en línea (url "kitchen.wrl")
)
)

Cuarto de baño Región (DEF


bboxSize 5 3 3 bboxCenter 6,5 0 -1,5
los niños de transformación (
traducción 6,5 0 -1,5
los niños en línea (url "bathroom.wrl")
)
)

DEF closet Región (


bboxSize 5 3 3 bboxCenter 6,5 0 1,5
los niños de transformación (
traducción 6,5 0 1,5
11

VRML 2.0 con Java CAPÍTULO 21

los niños en línea (url "closet.wrl")


)
)

DEF LivingRoom Región (


bboxSize 8 3 6 bboxCenter 0 0 0,5
los niños de transformación (
traducción 0 0 0,0
los niños en línea (url "living.wrl")
)
)

Garaje Región (DEF


bboxSize 8 3 7 bboxCenter -8 0 3,5
los niños de transformación (
traducción -8 0 3,5
los niños en línea (url "garage.wrl")
)
)

DEF Porche Región (


bboxSize 13 3 4 bboxCenter 2,5 0 5,0
los niños de transformación (
traducción 2,5 0 5,0
los niños en línea (url "porch.wrl")
)
)

# Ahora especificar la región a región visibilidad de la información

VÍA Storage.canSee A Storage.seenBy


VÍA Storage.canSee A Workshop.seenBy
VÍA Storage.canSee A Alcove.seenBy

VÍA Workshop.canSee A Workshop.seenBy


VÍA Workshop.canSee A Storage.seenBy
VÍA Workshop.canSee A Garage.seenBy
VÍA Workshop.canSee A Alcove.seenBy
VÍA Workshop.canSee A Kitchen.seenBy

VÍA Alcove.canSee A Alcove.seenBy


VÍA Alcove.canSee A Workshop.seenBy
VÍA Alcove.canSee A Storage.seenBy
VÍA Alcove.canSee A Kitchen.seenBy
12

VRML 2.0 con Java CAPÍTULO 21

VÍA Kitchen.canSee A Kitchen.seenBy


VÍA Kitchen.canSee A Alcove.seenBy
VÍA Kitchen.canSee A Workshop.seenBy
VÍA Kitchen.canSee A LivingRoom.seenBy
VÍA Kitchen.canSee A Porch.seenBy

VÍA Bathroom.canSee A Bathroom.seenBy


VÍA Bathroom.canSee A LivingRoom.seenBy

VÍA Closet.canSee A Closet.seenBy


VÍA Closet.canSee A LivingRoom.seenBy

VÍA LivingRoom.canSee A LivingRoom.seenBy


VÍA LivingRoom.canSee A Closet.seenBy
VÍA LivingRoom.canSee A Bathroom.seenBy
VÍA LivingRoom.canSee A Kitchen.seenBy
VÍA LivingRoom.canSee A Porch.seenBy

VÍA Porch.canSee A Porch.seenBy


VÍA Porch.canSee A LivingRoom.seenBy
VÍA Porch.canSee A Garage.seenBy

VÍA Garage.canSee A Garage.seenBy


VÍA Garage.canSee A Porch.seenBy
VÍA Garage.canSee A Workshop.seenBy

Tenga en cuenta que cada región tiene su canSee eventOut dirigida a su propia
seenBy eventIn. Esto se debe a que un usuario de pie en una región casi
siempre podremos ver el contenido de esa Región. Podríamos haber duro esta
en nuestro código de Java script bastante fácilmente, pero este enfoque nos da
más flexibilidad, ya que el mundo autor puede decidir hacer la actual Región
ocultos sin modificar la clase Java.
Limitaciones de la envolvente Recuadros

A pesar de su simplicidad, saltando cajas tienen varias desventajas. Ellos no


están bien adaptadas a los espacios que han particionado paredes en ángulo.
También es más costoso que otras estructuras de datos cuando el número de
regiones es grande.

También hay veces cuando se quiere una habitación en una subdivisión de las
regiones más pequeñas. Por ejemplo, en la Figura 21.1, la cocina y la alcoba
son visibles sólo a determinadas partes del taller y zona de almacenamiento, y
el cuarto de baño es visible sólo a determinadas partes de la cocina. Nos podría
13

VRML 2.0 con Java CAPÍTULO 21

poner un muro invisible a lo largo de una diagonal de una de nuestras


habitaciones, como se muestra en la Figura 21.4, para limitar aún más la
visibilidad y mejorar el rendimiento.

Figura 21.4 Una pared en diagonal


Árboles BSP

Binary Space Partitioning (BSP), los árboles son generalmente superiores a las
cajas de la envolvente. Nos dan una tremenda flexibilidad espacial en nuestra
separación y que es computacionalmente más eficiente que limitan cajas. Son
más complejos de un punto de vista de autor, pero es posible crear
herramientas que construir automáticamente BSP árboles a partir de un
conjunto de datos de entrada.
Árboles BSP cómo el trabajo

BSP árboles son relativamente simples, pero son a veces difíciles de visualizar.
La idea básica es tomar el volumen de espacio tridimensional y la partición en
dos piezas mediante un plano matemático. El binario de parte de la Oficina de
Planificación Estratégica nombre viene del hecho de que el resultado de dos
piezas de cada partición.

Un matemático es como un plano infinitamente grande, pero infinitamente


delgada pared. Cada punto que se encuentra en el avión, el avión cumple la
ecuación:

Ax + by + Cz + D = 0

donde A, B, C y D son cuatro de punto flotante valores que caracterizan a ese


singular avión.

Si conecta la x, y, z y las coordenadas de un punto en el avión en el plano de la


ecuación, el resultado será cero. Todos los puntos en un lado del avión a un
resultado que es inferior a cero, mientras que todos los puntos en el otro lado
produce un resultado que es mayor que cero. Mediante la sustitución de un
determinado x, y y z en el plano de ubicación de la ecuación, se puede
determinar qué parte del avión está en el punto.

Otra forma de ver la ecuación anterior es que A, B y C son los componentes de


un vector de tres dimensiones que es perpendicular al plano, y D es la
14

VRML 2.0 con Java CAPÍTULO 21

distancia del plano desde el origen del sistema de coordenadas.

Un avión va a dividir el mundo entero en dos partes. Una o ambas de las partes
se puede dividir por otros aviones, lo que resulta en nuevas particiones. Cada
una de las partes puede subdividirse, y así sucesivamente. Cada partición
convexa produce dos nuevos volúmenes de espacio.

Podemos seguir la pista de nuestro particiones utilizando un árbol binario, en la


que cada nodo de la hoja correspondiente a una de las particiones y convexo
nonleaf cada nodo correspondiente a un avión. Cada avión está representado
por sus cuatro coeficientes: A, B, C y D.

Por ejemplo, echemos otro vistazo a nuestra planta. Vamos a añadir la partición
de los aviones que en las regiones, y vamos a asignar un número a cada uno
de esos aviones, como se muestra en la Figura 21.5.

Figura 21.5 La planta con el particionado aviones añadido

Hemos mantenido las cosas simples por aquí particionado en sólo dos
dimensiones en lugar de tres. También hemos mantenido todos nuestros
aviones alineados con los ejes del mundo. Eso es de ninguna manera una
obligación, el avión puede convertirse en cualquier ángulo.

El árbol binario correspondiente a esta partición se muestra en la Figura 21.6.

Figura 21.6 El árbol de la Oficina de Planificación Estratégica para la casa

En general, queremos tratar de equilibrar el árbol con el fin de minimizar su


profundidad. La más profunda que tenemos que entrar en el árbol con el fin de
15

VRML 2.0 con Java CAPÍTULO 21

averiguar qué región (es decir, la hoja de nodo), el usuario se encuentra en el


cálculo más generales vamos a incurrir cada vez que el usuario se mueve.
Debemos realmente han comenzado a traducirse en el interior de la casa, con
el fin de lograr un mejor equilibrio.

Sin embargo, hay un trade-off en juego. Dado que estamos construyendo estas
particiones a mano, hemos optado por mantener el árbol fácilmente extensible.
Podemos añadir las casas de los vecinos por los cuatro lados, sin tener que
modificar la mayor parte de la estructura de árbol que hemos construido, ya
que cada vecino corresponde a un nodo hoja. Si nos dividido el interior de la
casa primero, luego cada vecino mucho que se han dividido por uno de los
primeros aviones, y nos se vean obligados a vivir con ello dividir más adelante.
Por supuesto, podríamos haber convertido toda la casa existente en una hoja
en un árbol más grande, a fin de evitar el problema.
¿Cómo se utilizan los árboles BSP

En muchos juegos de ordenador, un árbol BSP se utiliza para determinar el


orden correcto dibujo de las caras. Al atravesar el árbol y hacer siempre el lado
más alejado de cada partición en primer lugar, el correcto orden de dibujo se
obtiene. Esto evita la necesidad de pruebas de Z-buffer, que es una operación
por píxel. El Z-buffer está aún escrito en los rostros como se prestan, a fin de
que las entidades en movimiento (que no son parte del árbol BSP) pueden ser
prestados en el Z-buffer.

El juego Quake, de id Software, utiliza un refinamiento de ese enfoque. De


región a región, la visibilidad de información precomputed, y cada nodo hoja
tiene una serie de bits que indican que son visibles en otras regiones. Cualquier
caras que pertenecen sólo a las regiones nonvisible se saltan a hacer tiempo,
lo que resulta en grandes mejoras en el rendimiento general.

Lamentablemente, VRML aún no nos dan un control suficiente de la pipeline de


renderizado para poder hacer esto inteligente transversal. Sin embargo,
podemos hacer algo casi tan bueno por el mantenimiento de un árbol de la
Oficina de Planificación Estratégica para el mundo y el uso de nodos Switch
para ocultar las regiones que no son visibles de la región que el usuario que se
encuentra Todavía cerrar tener que comprobar el Z-buffer (desde no hay forma
de decirle al navegador de VRML no), pero al menos no estamos haciendo las
cosas que el usuario no puede ver.
Árboles BSP utilizando en VRML

Con el fin de utilizar los árboles BSP en VRML, necesitamos tener alguna
manera de controlar la visibilidad de cada nodo hoja por separado. Vamos a
hacer esto por envolver cada uno de los nodos de transformación de nuestro
mundo interior original de un nodo Switch. El Switch nodos tendrán su campo
16

VRML 2.0 con Java CAPÍTULO 21

whichChoice inicialmente fijado en -1, de manera que su contenido no es


visible.

También tenemos alguna manera de codificar el plano de las ecuaciones y de


región a región visibilidad información. Nosotros haremos esto usando MFString
campos en VRML. Aunque no es muy compacto, el uso de la cadenas de texto
de lectura fácil hace autoría.

Por último, tenemos que tener un nodo de secuencias de comandos que


maneja el propio árbol de la Oficina de Planificación Estratégica y controla la
visibilidad de las regiones. De secuencias de comandos que se necesitan tener
acceso a la ubicación del usuario, lo que vamos a obtener de un
ProximitySensor.

Vamos a tener nuestra planta mundo, incluido el árbol BSP hemos construido
para que antes, y expresarlo en VRML. El resultado se parece a esto:

# VRML V2.0 utf8


Punto de vista de la posición (0 1,5 0)
Punto de vista de la posición (0 22 0 orientación 1 0 0 -1,5708)

DEF R0 Switch (whichChoice -1 elección


Transformar la traducción (0 0 0,0
los niños en línea (url "living.wrl")
)
)

DEF R1 Switch (whichChoice -1 elección


Transformar la traducción (-8 0 3,5
los niños en línea (url "garage.wrl")
)
)
DEF R2 Switch (whichChoice -1 elección
Transformar la traducción (-10 0 -3,5
los niños en línea (url "storage.wrl")
)
)

DEF R3 Switch (whichChoice -1 elección


Transformar la traducción (-6 0 -3,5
los niños en línea (url "workshop.wrl")
)
)
17

VRML 2.0 con Java CAPÍTULO 21

DEF R4 Switch (whichChoice -1 elección


Transformar la traducción (-2 0 -5,0
los niños en línea (url "alcove.wrl")
)
)

DEF R5 Switch (whichChoice -1 elección


Transformar la traducción (4,5 0 -5,0
los niños en línea (url "kitchen.wrl")
)
)

DEF R6 Switch (whichChoice -1 elección


Transformar la traducción (6,5 0 -1,5
los niños en línea (url "bathroom.wrl")
)
)

DEF R7 Switch (whichChoice -1 elección


Transformar la traducción (6,5 0 1,5
los niños en línea (url "closet.wrl")
)
)

DEF R8 Switch (whichChoice -1 elección


Transformar la traducción (2,5 0 5,0
los niños en línea (url "porch.wrl")
)
)

DEF PS ProximitySensor (tamaño 1e30 1e30 1e30)

Guión (DEF SC
url "BSPTree.class"
MFString bspNodes campo [
"0 0 1 -7 1 -10"
"1 0 0 -9 2 -13"
"1 0 0 12 -12 3"
"0 0 1 7 -11 4"
"1 0 0 4 5 7"
"0 0 1 0 6 -2"
"1 0 0 8 -3 -4"
"0 0 1 3 8 9"
"1 0 0 0 -5 -6"
18

VRML 2.0 con Java CAPÍTULO 21

"0 0 1 -3 10 -9"
"1 0 0 -4 -1 11"
"0 0 1 0 -7 -8"
]
MFString bspLeaves campo [
"5 6 7 8",
"3 8",
"3 4"
"1 2 4 5"
"0 2 3 5 6"
"0 3 4 6 7 8"
"0 4 5"
"0 5"
"0 1 5"
]
eventIn SFVec3f ubicación
campo MFNode niños [
R0 USO USO R1 USO R2 USO R3 USO R4 USO R5 USO R6 USO R7 USO R8
]
)

VÍA PS.position_changed A SC.location

BspNodes el ámbito de la secuencia de comandos nodo almacena la


información para la nonleaf nodos. La codificación es muy simple: Se compone
de los cuatro coeficientes (A, B, C y D), expresada en números de punto
flotante, seguido por un par de enlaces a otros nodos. El primer enlace apunta
a que el nodo en el "frente" de la aeronave, el segundo apunta a que el nodo
en el "regreso" de la aeronave.

Si un enlace de valor es positivo, se apunta a un nodo nonleaf, es decir, es el


índice en el conjunto de bspNodes el próximo nodo. Si un vínculo es negativo,
apunta a un nodo hoja. Para encontrar el índice bspLeaves en la matriz, el
vínculo se niega y decrementa, por ejemplo, -3 se remite a bspLeaves [2]. Esto
se debe a que los números de nodo por encima de cero y se utilizan para
nonleaf nodos, de modo que la primera hoja nodo es -1, el segundo es -2, y así
sucesivamente.

Las hojas son aún más simple: cada hoja tiene una lista de los índices en
bspLeaves de los nodos hoja (es decir, las regiones) que son visibles desde la
19

VRML 2.0 con Java CAPÍTULO 21

hoja.

En nuestro ejemplo anterior, la primera entrada en bspNodes es 0 0 1 -7 1 -10.


El avión coeficientes son 0, 0, 1 y -7, es decir, la ecuación es plano

0x 0Y 1z -7 = 0

Tenga en cuenta que nuestro A, B, C y coeficientes serán 0s y 1s, ya que todos


nuestros aviones resultan ser alineados a lo largo de los ejes de coordenadas.
En la práctica, los valores serán completamente diferentes de aviones en
ángulo en direcciones arbitrarias.

Los valores de 1 y -10 al final de este primer nodo nonleaf significa que la
izquierda comienza con subtree nodo bspNodes [1], y el derecho subtree es un
nodo hoja bspLeaves encontrar en [9].

La ubicación del usuario se dirige desde el ProximitySensor PS a la ubicación en


la secuencia de comandos eventIn nodo. El nodo de secuencias de comandos
también tiene un campo de niños, que utiliza las distintas regiones, a fin de
que los comandos de la región pueden acceder a los nodos para modificar el
valor de sus whichChoice campos.
El Árbol de la Oficina de Planificación Estratégica de Código en Java

El árbol de código de la Oficina de Planificación Estratégica es un poco difícil.


Empezamos por conseguir el arreglo de los niños, y luego ir a través de él y
obtener las referencias a la whichChoice de campo de cada uno de los nodos
Switch:

/ / Un árbol de la Oficina de Planificación Estratégica para la ordenación del


territorio de particionado en VRML

/ / Escrito por Bernie Roehl, enero de 1997

paquete espacial;

importación java.util .*;


importación vrml .*;
importación vrml.field .*;
importación vrml.node .*;

clase pública se extiende BSPTree Guión (


BSPNode [] bspNodes / / no la hoja de nodos
BSPLeaf [] bspLeaves / / nodos de la hoja
int oldleaf = -1; / / la hoja que se la última vez
20

VRML 2.0 con Java CAPÍTULO 21

int nchildren; / / número de nodos secundarios


SFInt32 [] conmutadores / / el interruptor campos

public void inicializar () (


/ / Encontrar el whichChoice para todos los campos de los nodos
secundarios
MFNode niños = (MFNode) getField ( "niños");
nchildren = children.getSize ();
Nodo [] nodos = new Nodo [nchildren];
children.getValue (nodos);
interruptores = new SFInt32 [nchildren];
for (int i = 0; i <nchildren; i)
conmutadores [i] = (SFInt32)
nodos [i]. getExposedField ( "whichChoice");

El siguiente paso es leer la serie de nodos y nonleaf construir una serie de


objetos BSPNode. Vamos a definir la clase BSPNode más tarde:

/ / Ahora no carga la hoja de árbol de nodos BSP


int n;
MFString nodestring = (MFString)
getField ( "bspNodes");
n = nodestring.getSize ();
bspNodes = new BSPNode [n];
String [] node_strings = new String [n];
nodestring.getValue (node_strings);
for (int i = 0; i <n; i)
bspNodes [i] = new BSPNode (node_strings [i]);

Del mismo modo, podemos construir una matriz de objetos BSPLeaf:

/ / Ahora carga los nodos hoja


MFString leafstring = (MFString)
getField ( "bspLeaves");
n = leafstring.getSize ();
bspLeaves = new BSPLeaf [n];
String [] leaf_strings = new String [n];
leafstring.getValue (leaf_strings);
for (int i = 0; i <n; i)
bspLeaves [i] = new BSPLeaf (leaf_strings [i]);
)

Que la inicialización de todos los que tenemos que hacer. Todo lo demás que
ocurre como resultado de la ubicación del usuario cambiando:
21

VRML 2.0 con Java CAPÍTULO 21

public void processEvent (Event e) (


if (e.getName (). es igual a (la "ubicación")) (/ / usuario se ha movido
/ / Obtener su ubicación y saber lo que está en la hoja
ConstSFVec3f loc = (ConstSFVec3f) e.getValue ();
int = whichLeaf hoja (loc.getX (), loc.getY (), loc.getZ ());
if (hoja! = oldleaf) (/ / entró en una nueva hoja
/ / Ocultar las hojas viejas
for (int i = 0; i <nchildren; i)
conmutadores [i]. SetValue (-1);
/ / Hacer que el nodo hoja que estamos en el visible
interruptores [hoja]. SetValue (0);
/ / Pie de la lista de las hojas visibles desde este
Enumeración en bspLeaves = [hoja]. GetVislist (). Elementos ();
while (en.hasMoreElements ()) (
/ / Encontrar la hoja de valor entero
el int = ((Integer) en.nextElement ()). intValue ();
/ / Marca como visibles (whichChoice es igual a cero)
conmutadores [el]. SetValue (0);
)
/ / Hacer un seguimiento de la hoja que se encontraban en
oldleaf = hoja;
)
)
)

Después de la comprobación inicial para asegurarse de que se trata de un


eventIn ubicación, la ubicación del usuario se recupera a partir de la entrada
de evento y pasó a la whichLeaf () método. Método que desciende el árbol BSP
y devuelve el índice de la hoja se especifica que el nodo x, y, z ubicación que
se encuentra

En aras de la eficiencia, hacemos un seguimiento de la hoja que el usuario


previamente y comprobar para ver si están todavía en el mismo. Si es así, nada
más hay que hacer, desde el mismo conjunto de las regiones seguirán siendo
visibles. Esta resulta ser una muy importante optimización. Observe que la
variable se inicializa oldleaf a -1, que es un valor no válido de hoja. Que las
fuerzas de la visibilidad que se computan a través de la primera vez después
de la inicialización.

Suponiendo que el usuario ha entrado en una nueva hoja, que ocultar todas las
regiones que antes eran visibles por la fijación de sus valores whichChoice a -1.
Hacemos la región que el usuario es visible en whichChoice por su valor a 0.
22

VRML 2.0 con Java CAPÍTULO 21

Por último, el paso a través de la lista de las hojas visibles desde la hoja y
hacer visible cada uno de ellos mediante el establecimiento de whichChoice su
valor a 0. Estamos poniendo al día la final oldleaf valor.

El whichLeaf () el método es muy sencillo. Es nonrecursive, ya que sólo


necesita hacer un descenso lineal del árbol para averiguar que la hoja de nodo
es el sitio en:

/ / Método para encontrar la hoja de nodo que estamos en


int whichLeaf (float x, float y, float z) (
int nodo = 0;
/ / Bajar del árbol (no recurrentes)
while (nodo> = 0) (
BSPNode thisnode = bspNodes [nodo];
if (thisnode.inFront (x, y, z))
thisnode.getLeft = nodo ();
algo más
thisnode.getRight = nodo ();
)
return-nodo - 1 / / nodos hoja contar -1, -2, -3 ...
)

El descenso comienza con el primer nodo (nodo = 0). Mientras el nodo índice
es no negativa, estamos atravesando nonleaf nodos. Esperamos hasta el nodo
en cuestión en el bspNodes [] array, comprobar para ver qué lado del plano
correspondiente se encuentra en la ubicación mediante el uso de la frente () el
método de nodo, y seleccione el subárbol izquierda o derecha, según
corresponda.

Cuando un número de nodo negativo se encuentra, la convertimos en un índice


en el bspLeaves [] matriz y devolverlo.
La clase BSPNode

BSPNode la clase es muy sencillo:

paquete espacial;

importación java.util .*;

clase pública BSPNode (


protegidas flotar a, b, c, d;
protegidas int izquierda, derecha;
23

VRML 2.0 con Java CAPÍTULO 21

público int getLeft () (return izquierda;)


GetRight público int () (return derecho;)

público frente booleano (float x, float y, float z) (


volver x * y * a * b z c> d;
)
público BSPNode (String str) (
StringTokenizer tok = new StringTokenizer (str);
a = Float.valueOf (tok.nextToken ()). floatValue ();
b = Float.valueOf (tok.nextToken ()). floatValue ();
c = Float.valueOf (tok.nextToken ()). floatValue ();
d = Float.valueOf (tok.nextToken ()). floatValue ();
izquierda = Integer.parseInt (tok.nextToken ());
derecho = Integer.parseInt (tok.nextToken ());
)
)

El constructor sólo analiza la cadena desde el archivo VRML, y el frente () el


método de sustitución dado x, y, z en el plano de ubicación de la ecuación y
devuelve true si el resultado es superior a cero.
La clase BSPLeaf

El BSPLeaf clase es aún más simple:

paquete espacial;

importación java.util .*;

clase pública BSPLeaf (


protegidos de vectores visibles = new Vector ();
público BSPLeaf (String str) (
StringTokenizer tok = new StringTokenizer (str);
while (tok.hasMoreTokens ())
visible.addElement (nuevo Integer (tok.nextToken ()));
)

público de vectores getVislist () (return visible;)


)

Algunas Reflexiones sobre la optimización

Por el momento, que apague todos los interruptores cada vez que el usuario
entra en una nueva región y, a continuación, a su vez algunos de ellos de
nuevo. Podría ser más eficaz para comparar la visibilidad de las listas de las
24

VRML 2.0 con Java CAPÍTULO 21

viejas y nuevas regiones, y sólo cambiar la visibilidad de las regiones que lo


requieran.
Resumen

El uso de particionamiento espacial no sólo puede dar lugar a mejoras


dramáticas en el rendimiento, también puede ser la base para el filtrado de
cambios en un entorno multiusuario.

Aún más mejoras de rendimiento se puede obtener si los navegadores de VRML


tienen el apoyo a la Oficina de Planificación Estratégica árboles. Por el
momento, sólo un browser does: Newfire del calor. Los resultados son
impresionantes: El calor no se ejecuta en un Pentium-acelerado actualmente
supera una máquina SGI 02 en el mismo archivo VRML. Ver
http://www.newfire.com/ para obtener más información acerca de "calor".
Quake proyecto del MIT

Dos estudiantes del MIT, Pat McCormick y Anthony Accardi, han completado
una impresionante pieza de trabajo denominado bsp2wrl. Básicamente se trata
de un convertidor que toma la Oficina de Planificación Estratégica de archivos
utilizado por Quake y los convierte en VRML, que codifica la información en la
Oficina de Planificación Estratégica árbol un archivo binario que se lee y
procesa en tiempo de ejecución de un script de Java con técnicas similares a
las presentadas en este capítulo.

Como este libro va a la imprenta, bsp2wrl es una obra en progreso, pero es


definitivamente vale la pena mantener un ojo en. Echa un vistazo a su sitio
Web (http://web.mit.edu/pmccormi/www/bsp2wrl/) para el estado actual del
proyecto.

Podemos esperar para ver otros navegadores añadir soporte para el


particionado espacial con el fin de lograr un mayor rendimiento. También
podemos esperar que un modelo de pronto emerge de particionamiento para la
ordenación del territorio en VRML, momento en el que la mayoría de los
navegadores será capaz de sacar provecho de esta poderosa tecnología.

Potrebbero piacerti anche