capÍtulo 21

30
1 VRML 2.0 con Java CAPÍTULO 21 Particionado especial

Upload: hinago

Post on 12-Jun-2015

288 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CAPÍTULO  21

1

VRML 2.0 con Java CAPÍTULO 21

Particionado especial

Page 2: CAPÍTULO  21

2

VRML 2.0 con Java CAPÍTULO 21

Contenido 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 

Page 3: CAPÍTULO  21

3

VRML 2.0 con Java CAPÍTULO 21

¿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, 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. 

Page 4: CAPÍTULO  21

4

VRML 2.0 con Java CAPÍTULO 21

     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 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 

Page 5: CAPÍTULO  21

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. 

Page 6: CAPÍTULO  21

6

VRML 2.0 con Java CAPÍTULO 21

Cada habitación está hecha de una serie de segmentos de la pared y la puerta 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 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 

Page 7: CAPÍTULO  21

7

VRML 2.0 con Java CAPÍTULO 21

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 ) 

VÍA SC.showChildren A SW.whichChoice 

Page 8: CAPÍTULO  21

8

VRML 2.0 con Java CAPÍTULO 21

) # 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")) (         En ConstSFBool = (ConstSFBool) e.getValue ();         count + = (in.getValue ())? 1: -1;         showChildren.setValue ((cuenta> 0)? 0: -1);       )     ) 

Page 9: CAPÍTULO  21

9

VRML 2.0 con Java CAPÍTULO 21

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 

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")   ) 

Page 10: CAPÍTULO  21

10

VRML 2.0 con Java CAPÍTULO 21

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     los niños en línea (url "closet.wrl")   ) ) 

Page 11: CAPÍTULO  21

11

VRML 2.0 con Java CAPÍTULO 21

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 

VÍA Kitchen.canSee A Kitchen.seenBy 

Page 12: CAPÍTULO  21

12

VRML 2.0 con Java CAPÍTULO 21

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 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. 

Page 13: CAPÍTULO  21

13

VRML 2.0 con Java CAPÍTULO 21

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 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.

Page 14: CAPÍTULO  21

14

VRML 2.0 con Java CAPÍTULO 21

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 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. 

Page 15: CAPÍTULO  21

15

VRML 2.0 con Java CAPÍTULO 21

¿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 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 

Page 16: CAPÍTULO  21

16

VRML 2.0 con Java CAPÍTULO 21

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")    ) ) 

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")    ) 

Page 17: CAPÍTULO  21

17

VRML 2.0 con Java CAPÍTULO 21

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"      "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" 

Page 18: CAPÍTULO  21

18

VRML 2.0 con Java CAPÍTULO 21

  ]   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 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 

Page 19: CAPÍTULO  21

19

VRML 2.0 con Java CAPÍTULO 21

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    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: 

Page 20: CAPÍTULO  21

20

VRML 2.0 con Java CAPÍTULO 21

/ / 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: 

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 

Page 21: CAPÍTULO  21

21

VRML 2.0 con Java CAPÍTULO 21

            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. 

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)) 

Page 22: CAPÍTULO  21

22

VRML 2.0 con Java CAPÍTULO 21

          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; 

   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 ());    ) 

Page 23: CAPÍTULO  21

23

VRML 2.0 con Java CAPÍTULO 21

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 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 

Page 24: CAPÍTULO  21

24

VRML 2.0 con Java CAPÍTULO 21

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.