Archive for the ‘General’ Category

Un PlaneSensor que gira

En QuiXo3D estoy intentando crear un editor de X3D que se base en objetos del propio X3D para manipular objetos tridimensionales. Para poder mover los objetos directamente, sobre ellos hay que colocar alguna especie de sensor que permita detectar cuando el usuario elige un objeto y lo mueve.

Dado que trabajaremos en una proyección en dos dimensiones, moviendo un ratón por la pantalla podremos alterar la posición del objeto en dos dimensiones, o sea, en un plano. Para detectar movimientos en un plano X3D dispone del nodo PlaneSensor, que se dedica precisamente a eso.

Pero PlaneSensor presenta un problema: por defecto, sólo traduce los movimientos del ratón en un plano paralelo al plano Z=0, por lo que sólo permite movimientos en X e Y. ¿Cómo podemos hacer que los movimientos se detectaran y tradujeran en un plano distinto, por ejemplo el XZ? La solución es algún mecanismo que nos permita rotar el sensor.

Las versiones recientes de la especificación X3D incluyen para el nodo PlaneSensor un campo llamado AxisRotation, que permite girar el sensor en el espacio y llevar a cabo movimientos en cualquier dimensión. No obstante, las versiones más recientes de Xj3D todavía no lo implementan, por lo que haremos uso de la solución que ha sido clásica hasta ahora: envolver el PlaneSensor en un nodo Transform con la rotación deseada para girarlo, y los posibles hijos que pudiera tener el PlaneSensor envolverlos en otro nodo Transform con la rotación inversa a la anterior, para que recuperen su posición original.

Todo este mecanismo, envuelto en un prototipo, está disponible en el archivo AxisRotationPlaneSensor.x3d del SVN del proyecto. Un ejemplo de uso, que aplica este sensor a un cubo y a un cono es AxisRotationPlaneSensorTest.x3d.

Más adelante veremos cómo usar estos objetos para construir nuestro envoltorio autodesplazable y escalable…

El cubo que quería moverse en tantas direcciones que se paró (o el motivo del parón)

Hacía mucho que no actualizaba este blog. El motivo es que cada vez parecía haber menos motivo; después de un comienzo de año más bien movidito, lleno de proyectos para los que no hay tiempo, lo que no avanza aunque sea un poco, se detiene del todo.

Algo así le sucedió a este proyecto. Justo después de las últimas modificaciones subidas a la forja, con un pequeño cubo de demostración capaz de moverse en varias direcciones, comencé a plantearme el tema de la rotación. Resultó entonces que el esquema y modo de manejo que me había propuesto implementar no funcionaba a la hora de rotar. Después de varios cambios de planteamiento (algunos de ellos bastante radicales), pruebas, peleas con los mecanismos de cálculo de traslación y rotación de X3D, más pruebas… Simplemente no ví salida.

Así que, como si de un laberinto se tratase, regreso hoy a donde hace ya algún tiempo empecé: un cubo que se mueve, pero que no gira. ¿Cómo vamos a hacerlo girar? Algo se nos tendrá que ocurrir…

El cubo que se mueve a sí mismo en una sola dirección

Hasta ahora, nuestro cubo se movía en tres planos distintos: XY, XY e YZ. Dentro de cada plano era posible el movimiento simultáneo en cualquiera de las dos direcciones del plano; como este sistema puede hacer complicados los ajustes manuales en una dimensión sin alterar la otra (requiere una gran precisión), la siguiente mejora ha consistido en añadir un mecanismo de control para que, habilitando un campo (que en el ejemplo está conectado a la tecla Control), el desplazamiento del cubo sólo sea posible en una dirección (X en el plano frontal, Y en el lateral, y Z en el superior, visto desde frente). El código, que usa para la implementación un keySensor y los campos minPosition y maxPosition de los PlaneSensor, se puede encontrar en la forja.

El cubo que se mueve a sí mismo

Ya está aquí, ya llegó, creo que es él…

Por fin, después de muchas probaturas, ajustes y cabreos, llega “el cubo que se mueve a sí mismo”. Se trata, simplemente, de un cubo tal que, en cada una de sus caras, tiene un sensor que permite moverlo en el plano paralelo a dicha cara. Si lo cojo por delante, podré moverlo hacia arriba y abajo y a los lados (pero no adelante y atrás); si lo cojo por un lateral, lo podré mover arriba, abajo, delante y detrás (pero no de lado)…

En fin, que lo mejor es probarlo uno mismo. En el repositorio de SVN, dentro de la zona de mundos de prueba, se puede encontrar este pequeñuelo que tantos problemas ha dado, junto con otras probaturas que he ido haciendo a lo largo del proyecto.

Qué alivio cuando las cosas por fin salen…

A vueltas con el wrapper…

O a rotaciones y traslaciones, para ser más exacto. La función principal del envoltorio será “abrigar” al objeto que se está modificando y permitir cambios en su posición, tamaño y orientación. Diseñar un objeto envolvente que permita realizar toda esa variedad de operaciones tridimensionales usando como medio principal un dispositivo 2D como el ratón se ha revelado como todo un reto…

Es necesario determinar cómo los movimientos del ratón se van a traducir en desplazamientos en cualesquiera de los tres ejes y en rotaciones alrededor de ellos. Para ello hay varias tácticas posibles, de las cuales ninguna hasta el momento me ha parecido totalmente satisfactoria. Próximamente publicaré algunas de las pruebas que he venido haciendo…

De vuelta

Después de una cierta ausencia (más larga de lo esperado), vuelvo de nuevo a adentrarme en este mundo lleno de polígonos, tags y otras formas varias de tormento… Y esta vez procuraré utilizar el blog como bloc de notas, donde ir dejando constancia de todo lo que sucede. Aunque sólo sea por si luego me toca ir recorriendo hacia atrás el camino marcado por las miguitas de pan… 😉

Final del I Concurso Universitario de Software Libre de Castilla-La Mancha

El jueves pasado tuvo lugar la final de la fase local del II Concurso Universitario de Software Libre, que en el caso de Castilla-La Mancha celebra su primera edición. Desde aquí mi felicitación a la organización, por el esfuerzo que supone siempre arrancar una iniciativa como ésta, y especialmente a los proyectos premiados:

QuiXo3D obtuvo una mención especial, junto con el proyecto psicodélico y divertido de Funny Box.

Muchas gracias a todos por dar este pequeño empujón al Software Libre.

X3D: X de eXtensible

X3D no sólo es extensible porque exista una implementación libre y abierta de referencia que puede ser fácilmente modificada y adaptada por cualquiera. El propio lenguaje X3D también brinda herramientas para crear nuevos nodos a partir de los existentes mediante el mecanismo de los protos.

Básicamente, se trata de crear la definición de un nuevo nodo (el prototipo), con todos los campos que necesitamos en una cabecera, y luego un cuerpo que contiene los elementos X3D (nodos, rutas, etc) que forman su implementación. Una vez declarado, incluyéndolo en cualquier escena lo podremos utilizar como si de un nodo más se tratara.

Empecé a prestar atención a este mecanismo cuando, escribiendo una clase en Java para implementar mi envoltorio de objetos en la escena (el wrapper), me dí cuenta de que estaba construyendo un sistema de paso de mensajes que duplicaba el mecanismo de eventos de que ya dispone X3D: se podría acceder cómodamente a toda esa funcionalidad ya definida usando un nodo proto de X3D que encapsulara toda la funcionalidad que necesito de un wrapper. El resultado es que el wrapper se pasa a implementar mediante un proto como éste:

Sigue leyendo

Marchando un Wrapper

No se trata de la hamburguesa de ningún menú, sino más bien de un objeto ayudante para que la vista editable de ChefX3D que estoy creando (Editable3DView) pueda posicionar los objetos en la escena tridimensional, e implementar así el primero de los casos de uso que consideraré: el posicionamiento de los nuevos objetos. El wrapper es un objeto que envuelve físicamente a la nueva forma que queremos añadir a la escena, y se encarga de desplazarla por la misma siguiendo el movimiento que indica el usuario y de notificarle a la vista cuándo el usuario ha elegido la posición definitiva para la nueva forma, o si se ha cancelado la operación.

De momento el wrapper no tiene representación gráfica, pero en futuras versiones quizá sea una caja semitransparente alrededor del nuevo objeto, quizá indicando datos como el tamaño de la forma o mostrando guías para su posicionamiento. Para facilitar esas futuras extensiones, se ha definido un interfaz común para todos los posibles wrapper, y ahora estoy creando una implementación de la versión más sencilla (SimpleWrapper), para ir ampliándola después.

Wrappers

Casos de uso

En principio, el diagrama de casos de uso de este editor podría ser igual al de cualquier otro editor: las operaciones básicas son las de creación, modificación y borrado de objetos. No obstante, me puede ser útil como guía a la hora de ordenar y delimitar la funcionalidad que quiero añadir a la vista 3D de ChefX3D, priorizarla y establecer una planificación de las siguientes tareas.

El diagrama (en inglés, tremendamente complicado 😉 ) y realizado con Umbrello, está en la sección de documentación de la forja.

Casos de uso genéricos