desarrollo de un sistema de edición de escenas basado en...

286
MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de escenas basado en una librería gráfica de alto nivel: OpenSceneGraph. INGENIERÍA INFORMATICA ESCUELA TECNICA SUPERIOR DE INGENIERÍA Septiembre 2006 Alumno: Miguel Martínez Rodilla Tutor: Marcos Fernández Marín

Upload: others

Post on 13-Jan-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

MEMORIA DEL PROYECTO DE

FIN DE CARRERA

Desarrollo de un sistema de edición de escenas basado en una librería

gráfica de alto nivel: OpenSceneGraph.

INGENIERÍA INFORMATICA ESCUELA TECNICA SUPERIOR DE INGENIERÍA

Septiembre 2006

Alumno: Miguel Martínez Rodilla Tutor: Marcos Fernández Marín

Page 2: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE GENERAL PARTE I....................................................................................................... 7

1.1 Introducción. ..................................................................................................................... 11 1.2 Objetivos. .......................................................................................................................... 12

PARTE II ...................................................................................................13

2.1 Informática gráfica en tiempo real. ................................................................................... 17 2.1.1 Introducción. .................................................................................................................. 17 2.1.2 Orientación hacia el Hardware Gráfico 3D. Librerías gráficas de bajo nivel. ............... 18

2.1.2.1 OpenGl. ................................................................................................................... 19 2.1.2.2 Representación poligonal de los objetos. ................................................................ 20 2.1.2.3 Modelos de Sombreado. Sombreado Local............................................................. 21 2.1.2.4 Primitivas de dibujado............................................................................................. 21 2.1.2.5 Pilas de Matrices. .................................................................................................... 22 2.1.2.6 Empleo de Texturas................................................................................................. 22 2.1.2.7 Depth buffer. ........................................................................................................... 23 2.1.2.8 Shaders. ................................................................................................................... 23

2.1.3 Librerías gráficas de Alto Nivel. Grafos de escena........................................................ 24 2.1.3.1 Grafos de Escena. Generalidades. ........................................................................... 24 2.1.3.2 Tipos básicos de Nodos........................................................................................... 25 2.1.3.3 Proceso de selección de niveles de detalle. ............................................................. 26 2.1.3.4 Proceso de culling. .................................................................................................. 28 2.1.3.5 Multiproceso............................................................................................................ 30

2.1.3.5.1 Procesamiento Paralelo. ................................................................................... 30 2.1.3.5.2 Procesamiento Serie o en Pipeline. .................................................................. 31

2.1.4 Revisión de Grafos de Escena. ....................................................................................... 31 2.1.4.1 OpenGl Performer. .................................................................................................. 32 2.1.4.2 Open Inventor.......................................................................................................... 33 2.1.4.3 VRML ...................................................................................................................... 35 2.1.4.4 OpenSceneGraph..................................................................................................... 36 2.1.4.5 Otras librerías graficas de alto nivel........................................................................ 38

2.1.5 Motores de Videojuegos................................................................................................. 38 2.1.5.1 Motores de Visualización........................................................................................ 38

2.1.5.1.1 3D GameStudio ................................................................................................ 38 2.1.5.1.2 Crystal Space.................................................................................................... 39 2.1.5.1.3 Genesis3D ........................................................................................................ 39 2.1.5.1.4 The Nebula Device........................................................................................... 40 2.1.5.1.5 OGRE............................................................................................................... 40 2.1.5.1.6 Shark3D............................................................................................................ 40 2.1.5.1.7 The Torque Game Engine ................................................................................ 41 2.1.5.1.8 CDX Game Development Kit .......................................................................... 41 2.1.5.1.9 Artist................................................................................................................. 41

2.1.6.2 Motores de Videojuegos.......................................................................................... 42 2.1.6.2.1 Fly3D................................................................................................................ 42

2.1.6.3 Videojuegos Completos .......................................................................................... 43 2.1.6.3.1 Doom................................................................................................................ 43 2.1.6.3.2 Quake ............................................................................................................... 44 2.1.6.3.3 Unreal Tournament .......................................................................................... 45 2.1.6.3.4 Source Engine ................................................................................................. 46

2.1.7 Editores 3D................................................................................................................. 49 2.1.7.1 Maya.................................................................................................................... 51 2.1.7.2 3D Studio Max .................................................................................................... 54

1

Page 3: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.7.3 LightWave 3D..................................................................................................... 56 2.1.7.4 SoftImage XSI..................................................................................................... 57 2.1.7.5 Multigen Creator ................................................................................................. 57 2.1.7.6 OSGEdit .............................................................................................................. 58 2.1.7.7 Valve Hammer Editor ......................................................................................... 59 2.1.7.8 UnrealED............................................................................................................. 60

2.2 Arquitectura de Plugins. .................................................................................................... 61 2.3 Bibliotecas de enlace dinámico ......................................................................................... 63 2.3.1 Desarrollo de Plugins en 3D Studio Max....................................................................... 74

2.3.1.1 Funciones que debe implementar un plugin en 3ds Max .................................... 74 2.3.1.2 La funcion DllMain() .......................................................................................... 74 2.3.1.3 LibNumberClasses .............................................................................................. 75 2.3.1.4 LibClassDesc....................................................................................................... 75 2.3.1.5 LibDescription..................................................................................................... 75 2.3.1.6 LibVersion() ........................................................................................................ 75 2.3.1.7 Descriptores de clases ......................................................................................... 76 2.3.1.8 Mapas de parámetros........................................................................................... 79

2.4 Conclusiones. .................................................................................................................... 79 PARTE III..................................................................................................81

3.1 Metodología ...................................................................................................................... 84 3.2 Materiales .......................................................................................................................... 84 3.3 Planificación temporal....................................................................................................... 84

3.3.1 Diagrama de Gant....................................................................................................... 85 PARTE IV..................................................................................................89

4.1 Introducción ...................................................................................................................... 94 4.2 Análisis de Requisitos. ...................................................................................................... 95

4.2.1 Requisitos generales del sistema. ............................................................................... 95 4.2.2 Requisitos de la representación del grafo de escena .................................................. 95 4.2.3 Requisitos de la representación de tipos de datos en el interfaz................................ 96 4.2.4 Requisitos de la manipulación sobre la representación 3D del grafo......................... 96 4.2.5 Requisitos del sistema de deshacer / rehacer.............................................................. 97 4.2.5 Requisitos del sistema de plugins............................................................................... 97 4.2.6 Requisitos del Manejador de Vista Activa ................................................................. 97

4.3 Análisis.............................................................................................................................. 98 4.3.1 Análisis de la representación de los datos del grafo en el interfaz ............................. 98

4.3.1.1 Grupos de parámetros.......................................................................................... 99 4.3.1.2 Descriptores de parámetros ................................................................................. 99 4.3.1.3 El gestor de parámetros ....................................................................................... 99 4.3.1.4 Objects, Nodes, y AttributeTypes en OpenSceneGraph ................................... 103 4.3.1.5. El Gestor de ObjectTypes, NodeTypes y AttributeTypes. ............................... 104

4.3.2 Análisis de la representación del grafo de escena .................................................... 104 4.3.2.1 Crear un árbol a partir de un grafo .................................................................... 105 4.3.2.2 Mostrar el grafo en múltiples vistas de árbol .................................................... 106 4.3.2.3 Acciones sobre el árbol ..................................................................................... 107 4.3.2.4 Mostrar la información de un nodo del grafo.................................................... 108

4.3.3 Análisis de la interacción con el visor del editor...................................................... 108 4.3.3.1 El gestor de selección........................................................................................ 109 4.3.3.2 El eje manipulador ............................................................................................ 109 4.3.3.3 Creación automática de Matrices de Transformación ....................................... 110 4.3.3.4 Traslación de objetos usando el eje manipulador.............................................. 111 4.3.3.5 Representación de objetos independientes a la escena del editor...................... 112

4.3.4 Análisis del sistema deshacer / rehacer. ................................................................... 113

2

Page 4: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.2.7 Análisis del sistema de plugins. ............................................................................... 114 4.2.8 Análisis del Manejador de Vista Activa................................................................... 115

4.4 Casos de uso.................................................................................................................... 117 4.4.1 Funciones del sistema............................................................................................... 117 4.4.2 Descripción de alto nivel de los Casos de Uso......................................................... 119

Iniciar la aplicación. ...................................................................................................... 119 Iniciar Barras. ................................................................................................................ 119 Crear barra de paneles de comandos. ............................................................................ 119 Iniciar tipos de objeto. ................................................................................................... 120 Registrar un TabOutput. ................................................................................................ 120 Registrar un ObjectType. .............................................................................................. 120 Mapear los grupos de parámetros de un TabOutput...................................................... 120 Cargar Plugins. .............................................................................................................. 121 Cerrar aplicación. .......................................................................................................... 121 Cerrar treebar ................................................................................................................ 122 Cerrar escena. ................................................................................................................ 122 Cargar escena. ............................................................................................................... 122 Establecer un grafo sobre un elemento del árbol. ......................................................... 123 Replicar una escena de una TreeBar a otra. .................................................................. 123 Clonar un TreeCtrl a partir de otro. ............................................................................... 124 Nueva escena................................................................................................................. 124 Crear grafo por defecto. ................................................................................................ 124 Nuevo árbol. .................................................................................................................. 125 Insertar fichero. ............................................................................................................. 125 Cambiar escena activa. .................................................................................................. 125 Deshacer. ....................................................................................................................... 126 Rehacer.......................................................................................................................... 126 Crear Nodo. ................................................................................................................... 126 Crear un nodo según el nombre de su NodeType. ........................................................ 126 Crear una nueva instancia de un nodo según su nombre............................................... 127 Seleccionar elemento en árbol....................................................................................... 127 Seleccionar todas las instancias de un elemento. .......................................................... 128 Seleccionar todos los “mirrors” de un elemento. .......................................................... 128 Mostrar la información de un nodo ............................................................................... 128 Crear los diálogos de un TabOutput.............................................................................. 129 Crear un diálogo a partir de un grupo de parámetros .................................................... 129 Generar el contenido de un TabOutput ......................................................................... 130 Vaciar el contenido de un TabOutput............................................................................ 130 Notificar fin de selección de un ObjectType................................................................. 130 Mostrar los datos de un TabOutput ............................................................................... 131 Seleccionar nodo en el visor.......................................................................................... 131 Agregar nodo a la selección del visor ........................................................................... 131 Crear Matriz de Transformación como padre de un nodo............................................. 132 Actualizar la selección. ................................................................................................. 132 Actualizar el eje manipulador. ...................................................................................... 132 Copiar nodo. .................................................................................................................. 133 Replicar selección. ........................................................................................................ 133 Mover nodo. .................................................................................................................. 133 Duplicar Nodo. .............................................................................................................. 134 Duplicar Seleccion. ....................................................................................................... 134 Eliminar nodo................................................................................................................ 134 Activar modo selección................................................................................................. 135 Activar modo traslación de objetos. .............................................................................. 135 Activar modo escalado de objetos................................................................................. 135 Activar modo rotación de objetos. ................................................................................ 136

3

Page 5: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Activar modo rotar vista................................................................................................ 136 Activar modo trasladar vista. ........................................................................................ 136 Escalar selección. .......................................................................................................... 136 Comenzar escalado de selección. .................................................................................. 137 Realizar escalado de selección. ..................................................................................... 137 Finalizar escalado de selección. .................................................................................... 138 Rotar selección. ............................................................................................................. 138 Comenzar rotación de selección.................................................................................... 138 Realizar rotación de selección....................................................................................... 139 Finalizar rotación de selección. ..................................................................................... 139 Trasladar selección........................................................................................................ 139 Comenzar traslación de selección. ................................................................................ 140 Realizar traslación de selección. ................................................................................... 140 Finalizar traslación de selección. .................................................................................. 140 Centrar la vista en la selección. ..................................................................................... 141 Modificar el zoom de la vista. ....................................................................................... 141 Añadir un StateAttribute a un StateSet.......................................................................... 141 Eliminar un StateAttibute de un StateSet. ..................................................................... 142 Añadir un Modo a un StateSet. ..................................................................................... 142 Eliminar un Modo de un StateSet. ................................................................................ 142 Modificar un Modo de un StateSet. .............................................................................. 142 Modificar el parámetro de un control del panel de comandos. ..................................... 143 Establecer el valor de un parámetro. ............................................................................. 143 Establecer el valor de un parámetro. ............................................................................. 143 Establecer el contenido del portapapeles....................................................................... 144 Pegar el contenido del portapapeles. ............................................................................. 144 Visualizar escena en modo de alambre. ........................................................................ 144 Visualizar escena en modo de relleno. .......................................................................... 145 Visualizar sombreado en modo plano. .......................................................................... 145 Visualizar sombreado en modo suavizado. ................................................................... 145 Mostrar vista superior de la escena. .............................................................................. 145 Mostrar vista inferior de la escena. ............................................................................... 145 Mostrar vista anterior de la escena. ............................................................................... 146 Mostrar vista posterior de la escena. ............................................................................. 146 Mostrar vista lateral izquierda de la escena................................................................... 146 Mostrar vista lateral derecha de la escena. .................................................................... 146

4.4.3 Casos de Uso siguiendo la notación UML. .............................................................. 147 PARTE V..................................................................................................163

5.1. Introducción. .................................................................................................................. 167 5.2 Diagrama de componentes del sistema. .......................................................................... 167 5.3 Diseño de las funciones del sistema mediante diagramas de secuencia y colaboración. 168

5.3.1 Inicio. ....................................................................................................................... 168 5.3.2 Finalizar aplicación .................................................................................................. 170 5.3.3 Nueva Escena ........................................................................................................... 171 5.3.4 Insertar fichero. ........................................................................................................ 172 5.3.5 Modificar Parámetro ................................................................................................ 173 5.3.6 Nuevo árbol .............................................................................................................. 173 5.3.7 Seleccionar elemento en visor.................................................................................. 174 5.3.8 Crear Nodo ............................................................................................................... 175 5.3.9 Seleccionar Elemento en árbol ................................................................................. 176 5.3.10 Undo....................................................................................................................... 177 5.3.11 Seleccionar elementos del árbol en el visor ........................................................... 177 5.3.12 Seleccionar elementos del visor en el árbol ........................................................... 178

4

Page 6: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.13 Copiar elemento de árbol ....................................................................................... 179 5.3.14 Copiar ítem de un único árbol. ............................................................................... 179 5.3.15 SelectAllInstances .................................................................................................. 180 5.3.16 SelectAllMirrors..................................................................................................... 180 5.3.17 CreateParentMatrixTransform ............................................................................... 181 5.3.18 StartTranslation ...................................................................................................... 181 5.3.19 DoTranslate ............................................................................................................ 182 5.3.20 EndTranslate........................................................................................................... 182 5.3.21 RemoveSceneTree.................................................................................................. 183 5.3.22 Exec........................................................................................................................ 183 5.3.23 RecursiveCreateDialogs ......................................................................................... 184 5.3.24 CreateDialogs. ........................................................................................................ 184 5.3.25 CreateDialogFromGroup........................................................................................ 185 5.3.26 RegisterTabOutput (TabOutputManager) .............................................................. 186 5.3.27 RegisterType (ObjectTypeManager)...................................................................... 186 5.3.28 NewInstance ........................................................................................................... 187 5.3.29 CreateTreeNode ..................................................................................................... 187 5.3.30 CargarPlugins ......................................................................................................... 188 5.3.31 Update (Selection)................................................................................................. 188 5.3.32 UpdateAxis............................................................................................................. 189 5.3.33 MapIOControls....................................................................................................... 190 5.3.34 RecursiveOnEndSelection...................................................................................... 190 5.3.35 RecursiveGenerateRollupContent (ObjectType).................................................... 191 5.3.36 RecursiveClearRollupContent (ObjectType) ......................................................... 191 5.3.37 GenerateRollupContent (TabOutput) ..................................................................... 192 5.3.38 ClearRollupContent (TabOutput)........................................................................... 192 5.3.39 GetParamValue (TabOutput) ................................................................................. 193 5.3.40 SetParamValue (TabOutput) .................................................................................. 193 5.3.41 LookAtSelection..................................................................................................... 194 5.3.42 SetRootNode (ActiveViewHandler)....................................................................... 194 5.3.43 SetRootNode (MultiTreeBar)................................................................................. 195 5.3.44 ReplicateSceneTree (MultiTreeBar) ...................................................................... 196 5.3.45 CloneFrom (OSGTreeCtrl) .................................................................................... 196 5.3.46 DeleteNode (OSGTreeCtrl).................................................................................... 197 5.3.47 ActDeleteMultiItem (Action) ................................................................................. 197 5.3.48 DeleteNode (ActiveViewHandler) ......................................................................... 198 5.3.49 Cambiar escena activa............................................................................................ 199

5.4. Diagrama de estados del sistema.................................................................................... 199 5.4.1 Estado del cursor ...................................................................................................... 199

PARTE VI................................................................................................201

6.1 Introducción .................................................................................................................... 205 6.2 Parametrización de datos................................................................................................. 206

6.2.1 El descriptor de parámetros (OSGParamGroupDesc). ............................................ 206 6.2.2 Los grupos de parámetros (OSGParamGroup) ........................................................ 207 6.2.3 El gestor de parámetros (OSGParamManager) ....................................................... 208 6.2.4 El control ColorSwatch ............................................................................................ 211 6.2.5 Las clases OSGTabOutput y OSGTabOutputManager............................................ 212 6.2.6 Un ejemplo de OSGTabOutput : la clase OutCreateNodes...................................... 214 6.2.7 Las clases OSGObjectType y OSGObjectTypeManager......................................... 215 6.2.8 Un ejemplo de OSGObjectType: TypeDrawable..................................................... 217

6.3 Implementación del árbol del grafo de escena. ............................................................... 219 6.3.1 La clase TreeNodeInfo ............................................................................................ 219 6.3.2 La clase CEditTreeCtrl............................................................................................. 220

5

Page 7: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

6.3.3 La clase CEditTreeCtrlEx ........................................................................................ 222 6.3.4 La clase COSGTreeCtrl ........................................................................................... 223 6.3.5 CTreeBar y CMultiTreeBar. .................................................................................... 224

6.4 Interacción con el visor 3D ............................................................................................. 226 6.4.1 La clase OSGSelection............................................................................................. 226 6.4.2 La clase OSGAxisManipulator ............................................................................... 231 6.4.3 La clase MFCKeyboardMouseCallback .................................................................. 233

6.5 El sistema de deshacer / rehacer...................................................................................... 234 6.5.1 La clase OSGAction................................................................................................. 234 6.5.2 La clase OSGHistory................................................................................................ 235

6.6 El sistema gestor de plugins ............................................................................................ 236 6.6.1 El plugin Cartoon ..................................................................................................... 236 6.6.2 La clase OSGPluginManager ................................................................................... 237 6.6.3 La clase OutPlugins.................................................................................................. 239

6.7 El manejador de la vista activa y las clases MFC ........................................................... 241 6.7.1 La clase OSGActiveViewHandler............................................................................ 241 6.7.2 La clase COSGWorldView ...................................................................................... 246

6.8 Problemas y “tips” de implementación. .......................................................................... 249 6.8.1 La actualización de OpenSceneGraph 0.9 a 1.0. ...................................................... 249 6.8.2 La clase RefParticle.................................................................................................. 249 6.8.3 La función clone....................................................................................................... 250 6.8.4 La función DoFrame().............................................................................................. 250 6.8.5 Eliminar un nodo, deshacer y rehacer. ..................................................................... 251

PARTE VII ..............................................................................................253

7.1 Introducción .................................................................................................................... 257 7.2 El editor OSGWorld........................................................................................................ 257

7.2.1 Especificación de los elementos del Interfaz gráfico. .............................................. 257 7.2.1.1 La barras de menus............................................................................................ 258 7.2.1.2 La barra principal de herramientas. ................................................................... 262 7.2.1.3 La barra de nodos. ............................................................................................. 263 7.2.1.4 Los paneles de comandos .................................................................................. 264 7.2.1.5 La barra de árbol ............................................................................................... 267 7.2.1.6 El Visor 3D........................................................................................................ 269

7.3 Ejemplos de escenas mediante el uso del editor.............................................................. 270 7.3.1 Utilización de Sistemas de partículas para crear fuego y humo............................... 271 7.3.2 Utilización de las Luces. .......................................................................................... 271 7.3.3 Efecto Cartoon ......................................................................................................... 272 7.3.4 Efecto BumpMapping .............................................................................................. 272 7.3.5 Efecto de Specular Highlights.................................................................................. 273 7.3.6 Instanciación multiple .............................................................................................. 273 7.3.7 Efecto de niebla........................................................................................................ 274 7.3.8. Ejemplo de utilizacion de Shaders .......................................................................... 274

PARTE VIII.............................................................................................275

8.1 Conclusiones ................................................................................................................... 278 8.2 Trabajos futuros............................................................................................................... 279 8.3 Comparativa con OSGEdit.............................................................................................. 279

PARTE IX................................................................................................281

Bibliografía. .......................................................................................................................... 283

6

Page 8: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

PARTE I INTRODUCCIÓN

7

Page 9: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

8

Page 10: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE PARTE I.........................................................¡Error! Marcador no definido.

1.1 Introducción. ..................................................................... ¡Error! Marcador no definido. 1.2 Objetivos. .......................................................................... ¡Error! Marcador no definido.

9

Page 11: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

10

Page 12: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

1.1 Introducción. En el mundo de los gráficos por ordenador, existen dos líneas de investigación que se encuentran en estados muy avanzados, pero han seguido caminos divergentes: de un lado la Animación 3D que ha centrado toda su atención en la calidad visual de las imágenes, y de otro, la Realidad Virtual o Informática Gráfica en Tiempo Real, que ha intentando conseguir la mayor calidad posible, pero dando prioridad a la rapidez en la generación de imágenes. La realidad virtual puede ser de dos tipos: inmersiva y no inmersiva. Los métodos inmersivos de realidad virtual con frecuencia se ligan a un ambiente tridimensional creado por un ordenador, el cual se manipula a través de cascos, guantes u otros dispositivos que capturan la posición y rotación de diferentes partes del cuerpo humano. La realidad virtual no inmersiva utiliza medios como el que actualmente nos ofrece Internet, en el cual podemos interactuar en tiempo real con diferentes personas en espacios y ambientes que en realidad no existen sin la necesidad de dispositivos adicionales al ordenador. La realidad virtual no inmersiva ofrece un nuevo mundo a través de una ventana de escritorio. Este enfoque no inmersivo tiene varias ventajas sobre el enfoque inmersivo como son el bajo coste y fácil y rápida aceptación de los usuarios. Los dispositivos inmersivos son de alto coste y generalmente el usuario prefiere manipular el ambiente virtual por medio de dispositivos familiares como son el teclado y el ratón que por medio de cascos pesados o guantes. Pero tanto la Animación 3D como la Informática Gráfica en Tiempo Real siempre han estado complementadas por herramientas específicas o interfaces de edición. Estas herramientas gráficas han facilitado al desarrollador de entornos o animaciones la tarea de modelar objetos o generar escenarios, o realizar secuencias de movimientos de manera manual, mediante series de comandos o introduciendo las posiciones de la geometría manualmente. Estas herramientas también han ido evolucionando al mismo tiempo que lo han ido haciendo los motores gráficos, permitiendo en algunas de ellas una visualización en tiempo real del resultado final de la imagen. Además, gracias a la modularidad de estas aplicaciones, cada vez son más las aplicaciones que admiten extensiones, desarrollables por terceras personas, que se pueden ir añadiendo a las mismas para mejorar su capacidad y flexibilidad. Gran parte de los motores gráficos de simulación actuales definen una escena mediante el uso de un Grafo de Escena (Scene Graph), el cual es una estructura en forma de grafo, formado por diversos tipos de nodos que ejercen distintos tipos de influencias sobre sus nodos hijos, bien sea estableciendo una agrupación, introduciendo algún tipo de poda o aplicando alguna transformación afín. Los nodos hijos de estas estructuras suelen ser los objetos geométricos a representar. Aunque hasta hoy los grafos de escena han estado principalmente orientados a la representación de entornos estáticos, u objetos relativamente simples, cada vez más se pueden encontrar grafos de escena que permiten realizar animaciones más complejas y dinámicas, incluso que soportan sistemas de partículas. La motivación de este proyecto radica en proporcionar una herramienta de edición para uno de los últimos grafos de escena disponibles en código abierto: OpenSceneGraph, dada la carencia de potentes herramientas de edición para este grafo de escena. Esta librería está siendo ampliamente utilizada por el Instituto de Robótica de la Universidad de Valencia, debido a la antigüedad de OpenGL Performer (el motor gráfico de SGI basado también en grafo de escena). Para ello, será necesario analizar las carencias de las actuales herramientas existentes, así como las necesidades del Instituto de Robótica para así proponer soluciones que permitan llegar a construir una aplicación a la altura de sus exigencias.

11

Page 13: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

1.2 Objetivos. En este proyecto se pretende construir una aplicación que permita construir y manipular un grafo de escena de la librería OpenSceneGraph, proporcionando un interfaz sencillo e intuitivo, pero a la vez potente, ampliable, y que no requiera apenas conocimientos de programación. Concretamente vamos a enumerar los siguientes objetivos:

• Crear un interfaz sencillo, flexible y dinámico pero a la vez potente, proporcionando al usuario acciones que faciliten algunas de las tareas más tediosas. Se tomará en cuenta el interfaz y el manejo de 3d Studio Max, puesto que es una herramienta muy utilizada por el Instituto de Robótica, y será una de las aplicaciones que complementen con la aplicación desarrollada en este proyecto.

• Dotar a la aplicación de un mecanismo de visualización y manipulación de la estructura del grafo de escena.

• Del mismo modo, realizar una parametrización de los datos del grafo de escena en el interfaz gráfico para permitir la manipulación de los datos, de la manera más intuitiva posible y que aporte la mayor información al usuario.

• Disponer de un sistema de historia, para poder deshacer y rehacer cualquier tipo de acción sobre el grafo.

• Visualizar el estado del grafo de escena en tiempo real, permitiendo una interacción del usuario con la escena, sin necesidad de hacerlo manipulando directamente el árbol.

• Que sea un sistema ampliable, mediante una arquitectura de plugins. De este modo se podrán desarrollar nuevas funcionalidades en la aplicación, sin necesidad de modificar su núcleo. Por tanto se deberá proporcionar un conjunto de clases y librerías disponibles para el desarrollador de plugins.

Todos estos objetivos se deberán cumplir siempre siguiendo las técnicas de desarrollo aprendidas en las asignaturas de Ingeniería del Software, pudiendo obtener, de este modo, unas aplicaciones de buena calidad.

12

Page 14: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

PARTE II ESTADO ACTUAL DE LAS

TECNOLOGIAS IMPLICADAS

13

Page 15: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

14

Page 16: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE PARTE II .......................................................................................................

2.1 Informática gráfica en tiempo real. ................................... ¡Error! Marcador no definido. 2.1.1 Introducción. .................................................................. ¡Error! Marcador no definido. 2.1.2 Orientación hacia el Hardware Gráfico 3D. Librerías gráficas de bajo nivel. .......¡Error! Marcador no definido.

2.1.2.1 OpenGl. ................................................................... ¡Error! Marcador no definido. 2.1.2.2 Representación poligonal de los objetos. ................ ¡Error! Marcador no definido. 2.1.2.3 Modelos de Sombreado. Sombreado Local............. ¡Error! Marcador no definido. 2.1.2.4 Primitivas de dibujado............................................. ¡Error! Marcador no definido. 2.1.2.5 Pilas de Matrices. .................................................... ¡Error! Marcador no definido. 2.1.2.6 Empleo de Texturas................................................. ¡Error! Marcador no definido. 2.1.2.7 Depth buffer. ........................................................... ¡Error! Marcador no definido. 2.1.2.8 Shaders. ................................................................... ¡Error! Marcador no definido.

2.1.3 Librerías gráficas de Alto Nivel. Grafos de escena........ ¡Error! Marcador no definido. 2.1.3.1 Grafos de Escena. Generalidades. ........................... ¡Error! Marcador no definido. 2.1.3.2 Tipos básicos de Nodos........................................... ¡Error! Marcador no definido. 2.1.3.3 Proceso de selección de niveles de detalle. ............. ¡Error! Marcador no definido. 2.1.3.4 Proceso de culling. .................................................. ¡Error! Marcador no definido. 2.1.3.5 Multiproceso............................................................ ¡Error! Marcador no definido.

2.1.3.5.1 Procesamiento Paralelo. ................................... ¡Error! Marcador no definido. 2.1.3.5.2 Procesamiento Serie o en Pipeline. .................. ¡Error! Marcador no definido.

2.1.4 Revisión de Grafos de Escena. ....................................... ¡Error! Marcador no definido. 2.1.4.1 OpenGl Performer. .................................................. ¡Error! Marcador no definido. 2.1.4.2 Open Inventor.......................................................... ¡Error! Marcador no definido. 2.1.4.3 VRML ...................................................................... ¡Error! Marcador no definido. 2.1.4.4 OpenSceneGraph..................................................... ¡Error! Marcador no definido. 2.1.4.5 Otras librerías graficas de alto nivel........................ ¡Error! Marcador no definido.

2.1.5 Motores de Videojuegos................................................. ¡Error! Marcador no definido. 2.1.5.1 Motores de Visualización........................................ ¡Error! Marcador no definido.

2.1.5.1.1 3D GameStudio ................................................ ¡Error! Marcador no definido. 2.1.5.1.2 Crystal Space.................................................... ¡Error! Marcador no definido. 2.1.5.1.3 Genesis3D ........................................................ ¡Error! Marcador no definido. 2.1.5.1.4 The Nebula Device........................................... ¡Error! Marcador no definido. 2.1.5.1.5 OGRE............................................................... ¡Error! Marcador no definido. 2.1.5.1.6 Shark3D............................................................ ¡Error! Marcador no definido. 2.1.5.1.7 The Torque Game Engine ................................ ¡Error! Marcador no definido. 2.1.5.1.8 CDX Game Development Kit .......................... ¡Error! Marcador no definido. 2.1.5.1.9 Artist................................................................. ¡Error! Marcador no definido.

2.1.6.2 Motores de Videojuegos.......................................... ¡Error! Marcador no definido. 2.1.6.2.1 Fly3D................................................................ ¡Error! Marcador no definido.

2.1.6.3 Videojuegos Completos .......................................... ¡Error! Marcador no definido. 2.1.6.3.1 Doom................................................................ ¡Error! Marcador no definido. 2.1.6.3.2 Quake ............................................................... ¡Error! Marcador no definido. 2.1.6.3.3 Unreal Tournament .......................................... ¡Error! Marcador no definido. 2.1.6.3.4 Source Engine ................................................. ¡Error! Marcador no definido.

2.1.7 Editores 3D................................................................. ¡Error! Marcador no definido. 2.1.7.1 Maya.................................................................... ¡Error! Marcador no definido. 2.1.7.2 3D Studio Max .................................................... ¡Error! Marcador no definido. 2.1.7.3 LightWave 3D..................................................... ¡Error! Marcador no definido.

15

Page 17: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.7.4 SoftImage XSI..................................................... ¡Error! Marcador no definido. 2.1.7.5 Multigen Creator ................................................. ¡Error! Marcador no definido. 2.1.7.6 OSGEdit .............................................................. ¡Error! Marcador no definido. 2.1.7.7 Valve Hammer Editor ......................................... ¡Error! Marcador no definido. 2.1.7.8 UnrealED............................................................. ¡Error! Marcador no definido.

2.2 Arquitectura de Plugins. .................................................... ¡Error! Marcador no definido. 2.3 Bibliotecas de enlace dinámico ......................................... ¡Error! Marcador no definido. 2.3.1 Desarrollo de Plugins en 3D Studio Max....................... ¡Error! Marcador no definido.

2.3.1.1 Funciones que debe implementar un plugin en 3ds Max .... ¡Error! Marcador no definido. 2.3.1.2 La funcion DllMain() .......................................... ¡Error! Marcador no definido. 2.3.1.3 LibNumberClasses .............................................. ¡Error! Marcador no definido. 2.3.1.4 LibClassDesc....................................................... ¡Error! Marcador no definido. 2.3.1.5 LibDescription..................................................... ¡Error! Marcador no definido. 2.3.1.6 LibVersion() ........................................................ ¡Error! Marcador no definido. 2.3.1.7 Descriptores de clases ......................................... ¡Error! Marcador no definido. 2.3.1.8 Mapas de parámetros........................................... ¡Error! Marcador no definido.

2.4 Conclusiones. .................................................................... ¡Error! Marcador no definido.

16

Page 18: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1 Informática gráfica en tiempo real.

2.1.1 Introducción. La representación una escena tridimensional en un ordenador requiere que toda la información referente a la descripción de los objetos, la iluminación, la atmósfera y los puntos de vista sean transformados en una imagen 2D que presente una calidad suficiente como para proporcionar una sensación realista. La informática gráfica actual dispone de múltiples métodos para proporcionar definiciones matemáticas de los objetos tridimensionales, así, se pueden emplear definiciones de geometría sólida (CSG), en superficies paramétricas, campos potenciales, fractales, etc. De igual modo, existen múltiples métodos para definir las propiedades físicas de los objetos que constituyen la escena tridimensional, y de iluminar y transformar estas escenas en imágenes planas. En el caso de que se esté buscando la obtención de imágenes estáticas, o bien de secuencias grabadas de este tipo de imágenes, es posible recurrir a cualquiera de estos métodos. Normalmente estas tareas son llevadas a cabo en la CPU, y suelen presentar una complejidad computacional tan elevada que hace que el tiempo empleado en generar cada imagen sea habitualmente de varios minutos o incluso varias horas. Frente a este tipo de aplicaciones en las que prima la calidad de la imagen (a costa del tiempo de cálculo que sea necesario), existen otro tipo de aplicaciones, en las que es necesario que la generación de imágenes se produzca con una rapidez tal que posibilite la interactividad (por encima de 8 imágenes/segundo), o la percepción continua del movimiento (tasas de generación de imágenes en torno a los 50 imágenes/segundo). Con este objetivo, se han diseñado tarjetas gráficas especialmente orientadas a descargar a la CPU de las tareas relacionadas con el renderizado de las imágenes tridimensionales. No todos los métodos software empleados en la actualidad para conseguir imágenes 3D, pueden ser fácilmente implementadas dentro de una estructura hardware. Los métodos empleados para generar estas imágenes en tiempo real estén fuertemente condicionados por las características del hardware gráfico existente, existiendo una línea de investigación paralela a la Informática Gráfica Tradicional, cuyo objetivo es también conseguir la máxima calidad gráfica posible, pero siempre enmarcada por las limitaciones de este hardware gráfico. Esta línea de investigación paralela suele recibir el nombre genérico de Informática Gráfica en Tiempo Real. Para poder realizar representaciones visuales de una escena tridimensional en tiempo real, se ha de disponer de un formato de datos, según el cual, los objetos y sus características gráficas estén definidos a partir primitivas optimizadas para trabajar con este tipo de hardware gráfico. El hardware gráfico dispone de uno o varios procesadores encargados de procesar dichas primitivas (transformar la posición espacial de los objetos y realizar su proyección, cálculos de iluminación, ocultación entre objetos, cálculos de sombreado, mapeado de texturas, etc.), hasta transformarlas en una imagen bidimensional. El conjunto de comandos necesarios para tener acceso a las funcionalidades de este hardware suele estar recogido en una librería gráfica de bajo nivel, la cual, además de permitir realizar una gestión óptima del hardware gráfico, actúa como substrato inicial para la implementación de otras capas software de mayor complejidad. Como se verá en apartados posteriores, existen varias librerías de este estilo, siendo el estándar actual más aceptado la librería OpenGl, la cual será utilizada en los desarrollos implicados en Este proyecto. La necesidad de redibujar varias veces por segundo la escena completa, impone serias restricciones en cuanto al número de polígonos que se ven implicados en la generación de cada imagen. El coste de obtención de cada imagen, depende de varios factores relacionados directamente con el número de vértices que forman las primitivas geométricas de la escena, y el área (en píxeles) que ocupan sobre pantalla. Existen varios métodos para mantener este coste bajo un cierto límite, pero todos tienen como planteamiento básico la selección de los objetos

17

Page 19: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

gráficos relevantes por medio de una estructura jerárquica de dibujado conocida con el nombre de grafo de escena (scene graph). Estas estructuras son árboles formados por un conjunto de nodos organizados de tal modo que cada uno de ellos ejerce una determinada influencia sobre sus ramas hijas. Los nodos hoja de este árbol usualmente están formados usualmente por primitivas de dibujado. El empleo de grafos de escena también facilita enormemente la organización lógica de la escena, y el control por parte del usuario. En los siguientes apartados se muestra un estado del arte sobre el hardware gráfico, descrito a través de las funcionalidades de las librerías gráficas de bajo nivel empleadas para su manejo, se muestran las funcionalidades de las librerías gráficas de alto nivel y sus grafos de escena, y por último se realiza una revisión de los grafos de escena actuales.

2.1.2 Orientación hacia el Hardware Gráfico 3D. Librerías gráficas de bajo nivel. El objetivo básico en la generación de imágenes 3D interactivas es alcanzar unas velocidades de refresco elevadas. El hecho de renderizar una escena 3D de una complejidad media varias veces por segundo, implica una inmensa cantidad de cálculos que suele sobrepasar la capacidad de la CPU del ordenador. Por ello, es norma común recurrir a la utilización de hardware gráfico especialmente diseñado para esta tarea, y, como consecuencia de un API (Application Programmer's Interface) que proporcione un acceso eficiente a sus capacidades. Además, es deseable que dicho API proporcione una interfaz común entre los diferentes tipos de hardware gráfico existentes. En la actualidad hay varios sistemas que proporcionan un API para renderizado de gráficos 3D, pero no todos ellos resultan adecuados para su utilización en tiempo real. Uno de los más conocidos es PHIGS (Programmers's Hierarchical Interactive Graphics System) . PHIGS está basado en GKS (Graphic Kernel System) y es un estándar ANSÍ que permite manipular y dibujar escenas 3D encapsulando descripciones de objetos y atributos en display list, esta característica es especialmente útil si existen objetos complejos que pueden ser definidos una sola vez y dibujados varias veces, o también si la escena va a ser transmitida por red. Uno de sus principales inconvenientes es que no resulta adecuada si los objetos necesitan estar actualizándose continuamente, y también que no soporta algunas características actualmente básicas tales como el mapeado de texturas. PEXlib es otro API, basado originalmente en PHIGS, pero que a diferencia de éste, permite el renderizado en modo inmediato, es decir, los objetos son dibujados a medida que son descritos, sin necesidad de emplear una display list intermedia. PEXlib presenta como inconveniente que tampoco dispone de algunas características avanzadas de rendering y que tan sólo funciona en sistemas basados en X. Otro API muy conocido es Renderman, a diferencia de los anteriores, proporciona un lenguaje de programación para realizar las descripciones de los objetos y sus propiedades, esta característica permite generar imágenes de un nivel de acabado muy elevado, pero es muy difícil diseñar un hardware gráfico que lo soporte. Los tres sistemas anteriores constituyen los sistemas estándar de generación de imágenes históricamente más conocidos, pero presentan algunas carencias importantes a la hora de ser empleados en la generación de imágenes en tiempo real. OpenGl es un API desarrollado a partir de IrisGL, una librería creada por Silicon Graphics en 1982. OpenGl tiene unas funcionalidades similares a PEXlib, pero es independiente de X, siendo en la actualidad soportado por casi la totalidad de sistemas operativos y de hardwares gráficos. Una alternativa a OpenGl en sistemas Windows, es el API Direct3D, el cual es un subconjunto de DirectX, una librería que además de la parte gráfica da soporte de audio, vídeo, gestión de periféricos y gestión de red. Desde sus orígenes Direct3D ha sido considerada de inferior calidad que OpenGl (incluso en sistemas Windows), esta visión está cambiando debido a las

18

Page 20: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

últimos mejoras en su API que lo han hecho más estable y potente. Sin embargo, Direct3D no es un standard abierto, solamente funciona en sistemas Windows, y es más que dudoso que Microsoft tenga intención de hacer que DirectX esté disponible en otras plataformas.

2.1.2.1 OpenGl. OpenGl fue introducida en 1992, y es en la actualidad un estándar industrial cuya especificación es llevada a cabo por el ARB (OpenGL Architecture Review Board), un organismo del que son socios 3DLabs, ATI, Compaq, Evans&Sutherland, Hewlett-Packard, IBM, Intel, NVidia, Microsoft, y SGI. OpenGl es multiplataforma, independiente de vendedor y abierta, lo que le permite adaptarse a las nuevas innovaciones del hardware. Soporta primitivas gráficas básicas tales como puntos, líneas, polígonos e imágenes, y operaciones tales como la aplicación de transformaciones afines o proyecciones, cálculos de iluminación, ocultación entre objetos o mapeado de texturas. En la actualidad existen gran cantidad de tarjetas gráficas desarrolladas para cumplir la especificación de OpenGl. Los drivers de OpenGl encapsulan la información sobre el hardware gráfico al que van destinados, liberando al desarrollador de aplicaciones, de tener que hacer desarrollos adaptados a las características de los diferentes tipos de tarjetas gráficas. El funcionamiento básico de la OpenGl puede ser observado en la Figura 2-1. Los comandos de OpenGl son recibidos desde la parte izquierda del diagrama, la información que se envía es básicamente relativa a vértices de la geometría (Geometry Path) o a imágenes (Imaging Path). Existe la posibilidad de acumular estos comandos en display list para procesarlos en un instante posterior, de otro modo, los comandos son enviados directamente al pipeline de procesado.

Figura 2-1. Pipeline de visualización de OpenGl.

Tanto la información de vértices como de imagen puede llegar en un formato compactado, siendo en este caso descomprimido dentro de la propia pipeline. Puede que la información referente a la geometría esté indicada en forma curvas o superficies paramétricas, en tal caso se evalúan y transforman en una descripción basada en vértices. En la siguiente etapa, se realizan operaciones sobre primitivas formadas de vértices (puntos, segmentos de líneas y polígonos), los vértices son transformados e iluminados, y las primitivas son ensambladas y recortadas por la pirámide de visión. También se realizan operaciones sobre las imágenes, y algunas de ellas se almacenan sobre la memoria de texturas, listas para ser aplicadas sobre la geometría 3D. En la etapa de Rasterización, se utilizan los resultados de la fase anterior para generar una serie de direcciones y valores del framebuffer mediante la utilización de una descripción 2D basada en puntos, líneas o polígonos. Por último, el contenido del framebuffer es actualizado teniendo en cuenta la información anterior, y un conjunto de operaciones tales como comprobaciones de zbuffer, operaciones de mezcla con los actuales colores de framebuffer, operaciones de enmascaramiento etc. OpenGl ofrece acceso a un conjunto de operaciones gráficas del nivel más bajo posible, y como consecuencia no proporciona mecanismos directos para realizar la descripción de objetos

19

Page 21: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

geométricos complejos (como por ejemplo un cubo o una esfera). Estos han de ser ensamblados mediante la utilización de múltiples comandos de OpenGl.

2.1.2.2 Representación poligonal de los objetos. Se puede considerar que una escena 3D está constituida por un conjunto de objetos con determinadas formas y que ocupan determinadas posiciones. La informática gráfica dispone de diferentes métodos para proporcionar definiciones matemáticas de dichos objetos, siendo una de las más comunes considerar que la forma geométrica de un objeto está ser definido por un conjunto de triángulos conectados por sus lados (ver Figura 2-2).

Figura 2-2. Modelo de representación de objetos 3D mediante secuencias de triángulos.

El hecho de emplear una representación de este tipo hace que el proceso de dibujado de una escena pueda ser considerado como el procesado de un conjunto más o menos grande de triángulos. Las actuales tarjetas gráficas 3D incorporan hardware capaz de procesar dichos triángulos y transformarlos en su representación correspondiente en píxeles de pantalla. Las librerías gráficas de bajo nivel proporcionan métodos para realizar descripciones de este tipo de objetos poligonales y emplear de forma adecuada el hardware gráfico. La forma básica de descripción de un objeto en OpenGl consiste en la definición de las coordenadas que especifican vértices entre un par de comandos glBegin/glEnd, así, por ejemplo, para definir un triángulo formado por los vértices en (0,0,0) (0,1,0) y (1,0,1) seria necesaria la siguiente secuencia de código. glBegin(GL_POLYGON); glVertex3i(0,0,0); glVertex3i(1,1,0); glVertex3i(1,0,1); glEnd();

Cada vértice es especificado con dos o tres coordenadas. Adicionalmente se pueden definir una normal, coordenadas de textura y color que serán utilizados en el procesamiento del vértice. La normal se utiliza en los cálculos de iluminación y es especificada por medio de un vector de 3 componentes. El color proporciona información sobre las componentes Roja, Verde, Azul y de Alfa del vértice. Las coordenadas de textura indican la forma en la que imagen que define la textura es mapeada sobre la primitiva. En una fase previa al dibujado del triángulo se pueden haber definido otras características que afectaran a la forma en la que será dibujado, tales como las características del material empleado, la posición y características de las luces que le afectan, la presencia de niebla, etc.

20

Page 22: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.2.3 Modelos de Sombreado. Sombreado Local. OpenGl solamente proporciona métodos de sombreado locales. Métodos muy populares en la imagen de síntesis tradicional como son el trazado de rayos, o la radiosidad, necesitan conocer información de otras partes de la escena diferentes al polígono que se está dibujando, y no resultan adecuados para una aplicación en tiempo real. La razón de esto es que estos métodos requieren un conocimiento global de la escena a dibujar, mientras que el hardware gráfico es una pipeline de operaciones muy localizadas, y que no tiene capacidad para almacenar y recorrer la gran cantidad de información que compone una escena compleja. Existe una posibilidad de emplear estos métodos con OpenGl que consiste en realizar un precálculo de la iluminación empleando algún método de iluminación global, y asociar los resultados a los objetos gráficos en un proceso anterior e independiente del dibujado. Este tipo de técnica solamente resulta adecuada en la representación de escenarios estáticos. En OpenGl, el color de cada vértice es calculado de forma independiente a partir de las propiedades del material y las condiciones de iluminación. Los colores obtenidos en cada vértice son interpolados linealmente sobre las primitivas de dibujado según el método de Gouraud.

2.1.2.4 Primitivas de dibujado. En una escena normal la cantidad de triángulos suele ser aproximadamente el doble que el número de vértices, esto evidencia que la gran mayoría de los vértices están siendo compartidos por varios triángulos. El procesado independiente de los vértices de cada triángulo incrementa de forma innecesaria los costes asociados a la transformación e iluminación de los vértices y también a su transferencia. Es usual que procesado redundante de los vértices incremente estos costes en un factor de 6. Para reducir esta redundancia computacional, es común que el hardware gráfico 3D disponga de

rimitivas de ptriángulos. El

dibujado en las que un mismo vértice es utilizado simultáneamente por varios tipo de primitiva de este tipo más empleada son las tiras de triángulos, también

denominadas t-mesh o también triangle stríp. En este tipo de primitivas, cada vértice es usado de forma conjunta con los dos vértices procesados en último lugar para generar el siguiente triángulo. En el caso de emplear t-meshes largas, en lugar de triángulos sueltos, la mayoría de los vértices son procesados tan sólo 2 veces, reduciendo en un factor de 3 los cálculos asociados a la transformación e iluminación de vértices. Aún así, cada vértice sigue siendo procesado 2 veces, y, por tanto, sigue existiendo un coste redundante. En la Figura 2-3 se pueden observar las primitivas geométricas más significativas empleadas por la librería OpenGl, y como el orden en el que se definen los vértices, especifica la forma en la que se van generando los triángulos individuales.

21

Page 23: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 2-3. Primitivas geométricas empleadas por OpenGl. En arquitecturas en las cuales las transformaciones geométricas e iluminación son realizadas por software, se pueden emplear estructuras indexadas en las que los vértices pueden ser procesados y almacenados una sola vez, y los triángulos se generan en una fase posterior accediendo de forma indexada a estos vértices ya procesados. Sin embargo, por razones de compatibilidad con el hardware gráfico, los APIs actuales no suelen explotar esta posibilidad.

2.1.2.5 Pilas de Matrices. OpenGl proporciona métodos para realizar operaciones con matrices de 4x4, y básicamente gestiona tres tipos de ellas: La matriz model-view que transforma las coordenadas de los vértices; la matriz de texturas que es aplicada a las coordenadas de textura; y la matriz de proyección, la cual describe la pirámide de visión, y es empleada de forma conjunta con la matriz de model-view para transformar la escena 3D en una imagen plana. OpenGl define internamente una pila para cada uno de estos tipos de matrices. Para la gestión de estas pilas de matrices, OpenGl incorpora as cosas definir rotaciones, una serie de funciones permiten entre otrtraslaciones, escalados, y operaciones de push y op sobre las pilas. La matriz en la parte alta de pcada pila, es la que en cada momento se está aplicando a los vértices o las coordenadas de textura. El hecho de utilizar pilas de matrices resulta de gran utilidad en el caso de que exista una organización jerárquica de los objetos que se van a dibujar, y muy especialmente en el caso de que existan objetos con múltiples sistemas de referencia.

2.1.2.6 Empleo de Texturas. La utilización de texturas mapeadas es una de las técnicas que más ha contribuido a mejorar la calidad gráfica de los sistemas de generación de imágenes en tiempo real. Dicha técnica consiste emplear la capacidad de asociar imágenes a las primitivas geométricas que representan los objetos, dichas imágenes proporcionan información de detalle sobre la apariencia de la superficie de los objetos, sobre sus zonas de transparencia, permite aplicar mapas de reflejo, etc.

22

Page 24: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

La incorporación de esta capacidad en los sistemas de generación de imágenes en tiempo real supuso un enorme incremento en el realismo de las imágenes obtenidas (ver Figura 2-4).

Empleo de texturas por OpenGl. Figura 2-4.

Desde hace un par de años es común que el hardware gráfico pueda aplicar varias texturas simultáneamente sobre el mismo objeto, esta capacidad (multitexturing) ha contribuido a incrementar aún más la calidad de la imagen final.

2.1.2.7 Depth buffer. El Depth-buffer (también conocido como Z-buffer) proporciona un método sencillo para almacenar la información sobre la profundidad sobre una imagen bidimensional. El proceso es muy sencillo, cada vez que se dibuja un pixel en pantalla, se almacena la distancia a la que dicho pixel se encuentra de la cámara. Cuando más adelante el proceso de dibujado de un objeto 3D ordene dibujar de nuevo sobre esa posición, bastará con comparar si la distancia de ese objeto es superior o inferior a la ya almacenada, si es mayor, el objeto está más lejos, y, por tanto, está siendo ocultado por el primer pixel. En este caso la orden de dibujado del nuevo pixel es anulada. En caso contrario el nuevo pixel sería dibujado, y la nueva distancia almacenada. Normalmente cada pixel dispone de 24 o 32 bits para almacenar la información referente a la profundidad. Profundidades de z-buffer inferiores suelen hacer que se produzcan errores en la evaluación de la profundidad a la que se encuentran los objetos, y, por tanto, pequeños errores de dibujado. Este método es implementado muy fácilmente en el hardware, y resulta un método muy eficiente para calcular las ocultaciones producidas entre los objetos 3D. Existen otros métodos de ocultación que son compatibles con OpenGl, tales como la utilización de BSP trees, la utilización de Octrees o la pre-ordenación de los objetos, pero estos métodos no son soportados directamente por el hardware gráfico.

2.1.2.8 Shaders. En los últimos años, los fabricantes de hardware gráfico han centrado parte de sus esfuerzos en flexibilizar la forma en la que actúa la OpenGl, permitiendo que algunas de las partes de la pipeline gráfica (hasta ahora totalmente fija) puedan ser reemplazadas por unidades de código

efinibles por el usua

Figura 2-5. Imagen generada con la ayuda de shaders

d rio. Estas unidades son descritas en un lenguaje de alto nivel basado en un ANSÍ C extendido de tal modo que es capaz de realizar operaciones con vectores y matrices, y que proporciona funciones especialmente diseñadas para su utilización en gráficos 3D. Un

23

Page 25: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Shader es una unidad compilable independientemente que ha sido definida mediante este lenguaje.

2.1.3 Librerías gráficas de Alto Nivel. Grafos de escena. Las librerías de bajo nivel como la OpenGl están orientadas a facilitar la utilización hardware gráfico, pero resultan insuficientes si se desea gestionar una escena compleja, y casi todas las escenas de realidad virtual lo son. Como se ha comentado en el anterior apartado, uno de los objetivos principales de OpenGl es proporcionar un API que sea independiente del hardware gráfico, y que al mismo tiempo, permita un control total sobre sus funcionalidades. Como consecuencia de esto, OpenGl proporciona acceso a operaciones gráficas del nivel más bajo posible, y deja en manos del desarrollador de la aplicación la creación y gestión de objetos geométricos más complejos tales como cubos, esferas, coches, casas o animales. Para ayudar al desarrollador en esta tediosa tarea, existen librerías de más alto nivel que encapsulan la complejidad de estos objetos geométricos en estructuras especiales, y que, además, proporcionan métodos para gestionar la inmensa cantidad de información geométrica que suele ser manejada. Es usual que estas librerías de alto nivel, estén implementadas utilizando como base una librería de bajo nivel del estilo de la OpenGl. Las librerías de bajo nivel proporcionan métodos para realizar únicamente descripciones geométricas muy sencillas (por ejemplo un triángulo con un material y una textura determinada). La primera necesidad de un desarrollador de aplicaciones de realidad virtual es agrupar este triángulo con otros similares para poder, por ejemplo, definir la geometría un tornillo. A su vez, agrupar este tornillo con otra serie de elementos, para formar otro objeto de mayor complejidad, como puede ser una lámpara; agrupar esa lámpara con otros objetos para formar una habitación, etc. Esta forma en la que los objetos del mundo real aparecen agrupados de forma jerárquica, ya podría ser una razón suficiente para que las librerías de alto nivel tomasen la decisión de emplear una estructura de datos con una organización jerárquica, pero, además, la organización jerárquica de los elementos que constituyen una escena, facilita la utili i arga del sistema. La zac ón de múltiples sistemas de referencia, y ayuda a controlar la cestr u de alto uct ra jerárquica empleada de forma generalizada por todas las librerías gráficasnive e sa. l, r cibe el nombre de Grafo de Escena o Scene Graph en literatura ingle En los s eralidades de los grafos de escena, se iguientes subapartados se muestran las genpres ta de selección de nivel de detalle y en n los tipos de nodos básicos empleados, y los métodoscull ,ing encargados de mantener la carga del sistema dentro de unos limites razonables. Por último, se muestra la forma en la que actúan las librerías gráficas de alto nivel para aprovechar las capacidades de un sistema multiprocesador.

2.1.3.1 Grafos de Escena. Generalidades. Un grafo de escena es un grafo dirigido acíclico de nodos que contiene los datos que definen un escenario virtual y controlan su proceso de dibujado. Contiene descripciones de bajo nivel de la geometría y la apariencia visual de los objetos, así como descripciones de alto nivel referentes a la organización espacial de la escena, datos específicos de la aplicación, transformaciones, etc. Los grafos de escena almacenan la información del escenario virtual en diferentes tipos de nodos. Existen nodos que almacenan la información geométrica y actúan como nodos hijos dentro del grafo de escena; el resto de los nodos suelen aplicar algún tipo de modificación sobre el segmento de jerarquía que depende de ellos, bien sea estableciendo agrupaciones, aplicando

24

Page 26: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

alguna transformación afín o realizando algún tipo de selección sobre alguna de sus ramas hijas. El proceso de dibujado consiste en realizar un recorrido de dicho grafo, aplicando las operaciones indicadas por cada tipo de nodo. El Grafo de Escena tiene como funciones principales:

• Contribuir a establecer una organización lógica de la escena. • Establecer dependencias jerárquicas entre distintos sistemas de referencia. • Posibilitar el proceso de selección entre múltiples niveles de detalle. • Posibilitar el proceso automático de Culling (eliminación automática de los objetos que

se encuentran fuera del campo de visión). • Facilitar el control de la escena por parte del usuario. • Hacer más cómodo el acceso a las librerías gráficas de bajo nivel (OpenGl en este caso).

En la siguiente imagen (Figura 2-5) se puede apreciar la descomposición de un objeto en sus diferentes componentes, de manera agrupada, lo cual sería una aproximación al grafo de escena que lo definiría.

Fi aproximación al correspondiente Grafo de Escena.

gura 2-6. Descomposición de un objeto en su

2.1 2.3. Tipos básicos de Nodos. En la actualidad existen varias librerías gráficas de alto nivel, y cada uno de sus grqfos de escena presenta sus propias particularidades. Sin embargo, existe un conjunto básico de nodos que, a veces con distintos nombres, se encuentran presentes en todos ellos:

• Nodo de Geometría. Almacenan la información poligonal de los objetos, también almacenan informaciones referentes a su apariencia, tales como material, textura, etc. Usualmente actúan como nodos hoja.

25

Page 27: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Nodo Grupo. Se emplean para agrupar varios nodos hijos, bien sea a nivel meramente organizativo, o para facilitar el proceso de culling jerárquico.

• Nodo Nivel de Detalle. Usualmente llamados nodos LOD (Level of Detail). Seleccionan uno de sus hijos, basándose en la distancia entre el objeto con múltiples niveles de detalle y el punto de vista.

• Nodo de Transformación Afín. Permite aplicar una matriz de transformación que afectara a ubicación espacial de sus nodos hijos. Son necesarios para la definición de objetos móviles y también para la creación de estructuras articuladas.

• Nodo de Switch. Permiten realizar una selección entre sus nodos hijos. También es usual que el usuario tenga cierta capacidad para personalizar el comportamiento de los nodos, para ello los nodos suelen tener la capacidad de almacenar datos genéricos que necesite el usuario, y también rutinas de callback escritas por el usuario que son invocadas junto con el código interno de gestión del nodo.

2.1.3.3 Proceso de selección de niveles de detalle. Cualquier sistema gráfico presenta unas limitaciones que afectan al número de primitivas geométricas que pueden ser procesadas en una unidad de tiempo. Debido a estas limitaciones, el objetivo principal de las bases de datos orientadas a tiempo real, es emplear estrategias que consigan reducir la complejidad de la base de datos a representar, sin que ello repercuta en una merma de la calidad visual final. La selección de niveles de detalle es una de estas estrategias. La idea principal del proceso de selección de niveles de detalle se basa en la observación de que un objeto, cuando se encuentra alejado, no puede ser apreciado en detalle, bien sea por el reducido número de píxeles que ocupa en pantalla, debido al efecto de la perspectiva, o bien por efecto de las condiciones atmosféricas, tales como la niebla, o la iluminación. Esta circunstancia hace que un objeto originalmente muy complejo, pueda ser sustituido por otro geométricamente más sencillo. Como consecuencia, una base de datos para gráficos en tiempo real suele hacer que cada objeto presente distintas versiones de diferente complejidad geométrica, cada una de las cuales representa al objeto en un margen de distancias concreto. Además, se ha de establecer un criterio que determine cual de ellas en concreto ha de ser visualizada en cada instante. El criterio suele consistir en emplear la distancia existente entre el objeto y el punto de vista, en función de ella, se selecciona la representación que resulte más adecuada: una representación geométricamente muy sencilla si el objeto se encuentra tan alejado que es imposible percibir sus detalles, o una estructura geométricamente compleja si el objeto se encuentra tan cercano que sus detalles resultan perceptibles. Si bien la distancia entre el objeto y el punto de vista, es el criterio principal para realizar la selección entre los distintos niveles de detalle, en realidad, para que el proceso se realice de forma óptima, se han de tener en cuenta otros factores tales como el campo de visión empleado, la resolución en píxeles de la imagen, la precisión óptica del sistema de monitorización, ciertos efectos atmosféricos como la niebla o el humo, etc. Otros aspectos que pueden ser tenidos en cuenta, son la importancia del objeto dentro de la escena, o la carga del sistema. Es usual que cada objeto presente tres o más niveles de detalle. En general, el hecho de disponer de varios niveles de detalle intermedios hace las transiciones entre niveles de detalle resulten menos bruscas. La condición de cambio de nivel de detalle, (en función de la distancia u otros criterios) se produce en un instante concreto, y esto hace, que las representaciones de un objeto, entre un frame y el siguiente, resulten ligeramente diferentes. El sistema visual humano es muy sensible a estas discontinuidades, y es necesario prestar un interés especial a la forma en la que se producen los cambios entre niveles de detalle. Existen varias técnicas, que permiten reducir

26

Page 28: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

los efectos indeseables de las transiciones entre niveles de detalle, unas de ellas consisten en seleccionar el punto adecuado de transición, otras, en la creación de muchos niveles de detalle distintos, de tal forma que las diferencias entre dos niveles de detalle consecutivos sean mínimas, y otras hacen que los saltos no se produzcan de forma brusca, sino mediante transiciones suaves entre las representaciones, no existiendo una distancia a la cual un modelo es directamente sustituido por otro, sino un rango de distancias, o bien, un rango temporal en el cual se realiza una transición progresiva entre las dos representaciones: La técnica de Fading produce un fundido suave entre las imágenes correspondientes a dos niveles de detalle consecutivos, pero, presenta como inconveniente que incrementa temporalmente la carga en el periodo en el que los dos modelos están siendo dibujados simultáneamente; la técnica deMorphing, hace que los vértices de la geometría de uno de los modelos se modifiquen suavemente, hasta adoptar la posición de los vértices del otro modelo. Esto requiere que algunos vértices sean creados o destruidos en tiempo real, y, por tanto, obliga a que existan fuertes dependencias entre los modelos que representan los distintos niveles de detalle. Durante los periodos de transición la CPU consume un tiempo adicional en la gestión del morphing. Es el método que presenta mejores resultados tanto a nivel visual como computacional, sin embargo, el hec existan dependencias tan fuertes entre los distintos niveles de detalle, hace que ho de que dichos modelos sean muy difíciles de generar, y que en la práctica, sea muy poco usado. Para tener una referencia de la magnitud de la reducción de cálculos que supone la utilización de niveles de detalle, se puede indicar que la representación poligonal de una persona de una calidad aceptable requiere unos 2250 polígonos, mientras que el nivel de detalle más bajo puede ser resuelto con tan sólo 38. En la Figura 2-6 se pueden apreciar los diferentes niveles de detalles empleados en la representación del busto de una persona.

Figura 2-7. Diferentes niveles de complejidad en la representación geométrica de un busto.

En la figura anterior, la representación de más calidad tiene aproximadamente unos 60.000 caras, la que aparece en tercer lugar presenta aproximadamente 600 caras, y por último la más sencilla, está formada por tan sólo 60 caras. Esto evidencia que con la utilización adecuada de niveles de detalle se obtienen unas tasas de reducción de su coste computacional que se mueven en dos ordenes de magnitud. En la Figura 2-7 se ha realizado una representación conjunta de las geometrías que representan eltercer y cuarto nivel de detalle, situándolas a distancias de la cámara cada vez mayores, es fácil omprobar que a medida que la distancia va aumentando las

diferencias entre ellos se vuelven rácticamente imperceptibles.

cp

27

Page 29: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 2-8. Evidencia de que la capacidad de percepción de detalles disminuye con la distancia del objeto.

Existe un gran número de investigaciones relativas al desarrollo de técnicas de simplificación geométrica que pueden ser empleadas para la generación de niveles de detalle.

2.1.3.4 Proceso de culling. En una aplicación de simulación, o en cualquier entorno virtual en general, el usuario se encuentra inmerso en una inmensa base de datos geométricos. Sin embargo, en cada instante está mirando en una dirección concreta, y, por consiguiente, gran parte de la geometría permanece fuera de su campo de visión. Enviar toda la base de datos al hardware gráfico resultaría muy costoso, y, además, es innecesario. La CPU puede determinar cuales son los objetos que están dentro de la pirámide de visión (denominada viewing frustum o simplemente frustum en la literatura inglesa) y con ello reducir considerablemente la cantidad de datos a transferir al hardware gráfico y consecuentemente la cantidad de trabajo a realizar por éste. Este proceso es conocido como culling, y es junto el proceso de gestión de niveles de detalle, uno de los principios que permite mantener la cantidad de geometría a dibujar dentro de unos márgenes adecuados. Existen métodos de culling muy avanzados que tienen en cuenta las ocultaciones producidas entre los objetos de la escena, este tipo de culling es esencial en el caso de entornos de tipo arquitectónico, formados por muchas habitaciones y paredes. Básicamente consisten en

ede

determinar que objetos son visibles a través de las puertas y ventanas, y almacenar la información en estructuras de datos adecuadas que son rellenadas en una fase previa a la simulación. Otro tipo de técnica de culling consiste en dividir el espacio en celdas regulares, y calcular que otras celdas son visibles desde cada una de ellas. Esta operación ha de ser también realizada en una fase de preproceso. En tiempo de ejecución simplemente se determina la celdaen la que está el usuario, y en función de ello, se activa o desactiva la visualización de celdas correspondientes. Esta técnica es especialmente útil en aplicaciones en las que el espacio puser fácilmente compartimentado, como por ejemplo aquellas que consisten en el recorrido decarreteras o túneles. Estas dos últimas técnicas pueden ser aplicadas en bases de datos que tienen características muy concretas, y presentan como ventaja principal que los cálculos importantes son realizados en una fase de preproceso. Sin embargo, no resultan totalmente adecuadas en aquellos casos en los que la base de datos contiene objetos móviles, o bien, en aquellos casos en los que el usuario no tiene ningún tipo de restricción en cuanto a su movimiento. Existen métodos de culling genéricos que pueden ser aplicados en cualquier circunstancia, y queestán basados en el cálculo de intersección entre la pirámide de visión y las envolventes de los objetos de la escena (conocidos en la literatura inglesa como bounding volumes). Esta técnica

28

Page 30: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

pres ta s en corno inconveniente principal, el hecho de que las intersecciones han de ser calculadaen tiemp paces de o de ejecución. Los algoritmos que realizan este tipo de culling han de ser caestablec a que producen sobre la CPU, y el ahorro de trabajo que er un balance entre la cargprod euc n sobre el hardware gráfico. La utiliz g volumes resulta especialmente adecuada para las bases de datos ación de boundinorganizadas en forma de Grafo de Escena, ya que su estructura puede ser aprovechada para definir una organización jerárquica de bounding volumes. Cada nodo tiene asociado un bounding volume que engloba al nodo en sí, y a todos sus hijos. La librería que gestiona el scene graph, tiene capacidad para recalcular automáticamente la forma de esas envolventes cada vez que existe una modificación en la topología de la base de datos. Es usual que cada nodo tenga una lista que contiene referencias a sus nodos padre, de modo que cuando el bounding volume de un nodo es modificado, esa modificación es propagada hacia sus padres. De este modo la jerarquía de bounding volumes permanece continuamente actualizada. Es bastante común emplear como envolventes paralelepípedos alineados con los ejes (también conocidos como bounding boxes), o esferas (bounding spheres). Este tipo de envolventes son aproximaciones de la forma original, y, por tanto, puede ocurrir que el bounding volume de un objeto esté intersectando con la pirámide de visión, y, sin embargo, no ocurra lo mismo con el objeto en sí. Por esta razón, es adecuado que la envolvente se adapte lo máximo posible a la forma real del objeto. Analizado desde esta óptica, las bounding boxes son una mejor aproximación, sin e te bounding mbargo, la actualización, transformación y testeado medianspheres es mucho más rápida. Algunas librerías como OpenGl Performer emplean sistemas mixtos, en los que las geometrías finales del grafo de escena se procesan mediante bounding boxes y los nodos intermedios mediante bounding spheres. El método de procesado de una escena con este tipo de culling jerárquico consiste en hacer un recorrido recursivo del grafo de escena, comprobando para cada nodo la forma en la que su envolvente intersecta con la pirámide de visión, tomando las siguientes decisiones:

• El bounding volume está completamente fuera de la pirámide de visión: ni este nodo ni sus hijos han de ser dibujados. El recorrido del scene graph continúa sin entrar en esta rama.

• El bounding volume está completamente dentro de la pirámide de visión: este nodo y sus hijos han de ser dibujados. En esta rama ya no es necesario realizar más comprobaciones de cull.

• El bounding volume intersecta con la pirámide de visión: se continúa realizando el proceso de cull sobre los nodos hijos. En el caso de que sea un nodo final, se procede a su dibujado.

En el caso de emplear este tipo de culling es muy conveniente tener una buena organización jerárquica de la escena, de tal modo que los objetos con una ubicación espacial próxima aparezcan agrupados debajo de un mismo nodo. Así por ejemplo, supongamos en el caso del tornillo que forma parte de una lámpara, la cual se encuentra en el salón de una casa que forma parte de un pueblo; si esta escena tuviese una organización jerárquica adecuada en la que hubiese sucesivos nodos tomillo->lámpara->salón->casa->pueblo, bastaría con comprobar que la casa está fuera de la pirámide de visión para descartar su dibujado y las comprobaciones de culling con todos los objetos que se encuentran en su interior. En siguiente diagrama (Figura 2-8) se muestra de forma gráfica una situación similar en la que se representa una escena sencilla formada por seis objetos que aparecen agrupados mediante distintos nodos intermedios, así como sus correspondientes bounding spheres. Se puede observar claramente la relación entre la organización jerárquica de los nodos del grafo de escena y las bounding spheres correspondientes a cada nodo.

29

Page 31: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 2-9. Bounding volumes en un proceso de culling jerárquico.

Existen métodos de culling que también tienen en cuenta las condiciones de visibilidad debidas a las condiciones atmosféricas (bien sea niebla, lluvia, etc.). Un objeto que normalmente es visible a una determinada distancia puede, que a la misma distancia, deje de serlo en el caso de que exista una niebla densa.

2.1 5.3. Multiproceso. Las liap nsumir gran cantidad de recursos, por ello caciones de gráficos en tiempo real suelen coes h t abi ual que en algunos casos sea necesario recurrir al empleo de ordenadores con variosprocesadores. Hay dos formas posibles de emplear de forma conjunta varios procesadores: La organización enparalelo y la organización en serie o pipeline. La primera de ellas presenta como ventaja que tiene poca latencia, pero es de difícil implementación, pues encontrar la forma en la que para ilel zar procesos encierra bastante complejidad. La organización en pipeline, presenta como inconve que la anterior, pero, por el contrario, resulta de una niente que tiene más latencia implementación mucho más sencilla. También es posible definir estructuras mixtas, pero es un área que no ha sido muy investigada.

2.1. .53 .1 Procesamiento Paralelo.

Hay ajo total es varias formas de paralelizar un algoritmo: empleando asignación estática, el trabdividido en varios bloques de trabajo, y cada procesador realiza uno de dichos bloques de trabajo en paralelo con los otros. Cuando los procesadores han terminado de procesar sus bloques, el resultado ha de ser mezclado, para que esto sea factible, es necesario que el coste computacional del procesado de cada bloque sea altamente predecible. Mediante la asignación dinámica, los trabajos a realizar por las CPUs son dejados en una zona común, cuando un procesador ha finalizado su trabajo actual toma otro bloque de trabajo de la zona común y lo procesa. El hecho de que cada CPU solicite un paquete de trabajo, supone una sobrecarga que se puede minimizar haciendo que los paquetes de trabajo tengan un tamaño adecuado. Esto puede evitar que el sistema se quede desbalanceado debido a que alguna CPU tenga que estar esperando a que finalizase el trabajo alguna otra que había tomado un bloque de trabajo demasiado grande. El principal problema de la utilización de un procesamiento paralelo es que necesita que el proceso pueda ser dividido en paquetes de trabajo que puedan ser realizados de forma paralela.

30

Page 32: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.3.5.2 Procesamiento Serie o en Pipeline.

La forma de realizar un proceso en serie consiste en dividir el trabajo en una serie de bloques que pueden ser realizados en cascada, de tal modo que los datos de salida de un procesador son empleados como entrada del siguiente. La generación de una imagen en tiempo real puede ser considerada como constituida por una serie de etapas que se realizan en cascada. La forma tradicional de emplear varios procesadores en una aplicación de gráficos en tiempo real consiste en dividirla en tres etapas: APP, CULL y DRAW. El procesado de la escena se realiza en el proceso de APP, y consiste en la actualización de los valores de los nodos con los valores provenientes de algún mecanismo de gestión del comportamiento de la escena. El procesado visual consiste en la realización de las operaciones de culling y dibujado (CULL y DRAW). Es habitual que los procesos de culling y draw sean realizados de forma automática. La misión de cada una de estas etapas es la siguiente:

• APP. Lee valores de los periféricos de entrada, realiza la simulación de los objetos que se mueven, actualiza la base de datos visual e interacciona con otras posibles simulaciones conectadas a través de la red.

• CULL. Aplica el culling jerárquico determinando que porciones de la escena son potencialmente visibles, realiza una selección de los niveles de detalle, realiza una ordenación de la geometría por su estado gráfico, ordena los objetos transparentes por distancia para su correcto dibujado, y finalmente, crea una lista con los objetos que han de ser dibujados.

• DRAW. Se encarga de alimentar al hardware gráfico con la lista de los objetos que han quedado de la fase anterior.

Algunas librerías gráficas como OpenGl Performer incluyen en la pipeline de procesado de la escena otros procesos:

• ISECT. Realiza cálculos de intersección entre segmentos de línea y la geometría del grafo de escena, lo cual se puede emplear para detección de colisiones.

• COMPUTE. Realiza cálculos complejos de forma asíncrona. • DBASE. Gestiona de forma asíncrona la base de datos que define la escena.

Dependiendo del número de CPUs disponibles y del tipo de aplicación se pueden emplear

ólo un único procesador las tres pAPP y C a de APP en s, uno podría ecomplejos con dos o más salidas gráficas, es común encontrar estructuras mixtas formadas por 8 o m

distintos modelos de multiproceso, así, en el caso de disponer de s eta as serían ejecutadas en la misma CPU. En el caso de disponer de dos, los procesos de

ULL pueden ser ejecutada en una y el DRAW en la otra, o bien se ejecutaría la etap una CPU y las de CULL y DRAW en las otra. En el caso de existir 3 procesadorestar dedicado al APP, otro al CULL y otro al DRAW. En sistemas de simulación

ás CPUs.

.1.4 Revisión de Grafos de Escena. 2 Una vez presentadas las características básicas de las librerías gráficas de bajo y alto nivel, resu alta didad las características de los grafos de escena más decuado analizar con más profuncon d fos de oci os. Si bien en este apartado no se profundiza en el análisis de la totalidad de los graescena actuales, sí que se trata sobre aquellos que han tenido una mayor influencia en la evolució e hace una descripción del n de esta rama de la informática gráfica. Con esta intención sfunc nio amiento de OpenGl Performer, que encapsula en estructuras de más alto nivel la mayoría de las fu tadas hacia ncionalidades de OpenGl y proporciona funcionalidades añadidas orienapli i e cac ones que necesitan una elevada tasa de refresco, como por ejemplo aplicaciones dsimulac tor que proporciona una interfaz ión visual o escenografía virtual; la librería Open Inven

31

Page 33: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

gráf e ica y un grafo de escena muy flexibles que facilitan la creación y manipulación interactiva duna escena 3D; VRML, un formato de fichero que describe un grafo de escena y que tiene la intenció ternet n de ser el estándar para la navegación en espacios tridimensionales a través de In; y por último se profundizara en OpenSceneGraph, que es la que hemos utilizado en el presente proyect nGl, y con gran similitud con OpenGl Performer, con la o, una librería basada en Opeprin acip l diferencia de que es de codigo abierto, y por tanto totalmente gratuita. En los s tallaran las propiedades básicas de estos grafos de escena, y se iguientes apartados se dehará a icas. En un último un descripción de cuales son los nodos que los constituyen y característapa ortad se muestran de forma rápida otros grafos de escena existentes en la actualidad.

2.1 1.4. OpenGl Performer. OpenGl Performer es un Grafo de Escena diseñado para optimizar al máximo la utilización del hard arw e gráfico. Es una librería muy orientada al mercado de la simulación visual, siendo su may r pri tasas o oridad la obtención de tasas de refresco muy altas, llegando a mantener constantes de 50 frames/segundo. Proporciona soporte para multiproceso, permitiendo dividir el trabajo entre múltiples CPUs, gestionando su sincronización y transferencia de información. Además, proporciona algunas características avanzadas tales como la detección de intersecciones, la gestión de terrenos, morphing geométrico o incluso una pequeña interfaz de usuario. Los nodos utilizados por la librería Performer son los siguientes:

• Nodo Geode: Es un nodo hoja que almacena la información geométrica de un objeto (Geometry node). Está formado por una lista de estructuras llamadas pfGeoSet que encapsulan características de bajo nivel referentes a primitivas de dibujado y su apariencia gráfica, y que almacenan la información en un formato muy próximo a la OpenGl.

• Nodo Grupo: Sirve para agrupar varios nodos hijos. • Nodo Scene: Actúa como nodo padre de todo el grafo de escena. Se utiliza también para

almacenar informaciones visuales comunes a toda la escena, tales como condiciones de niebla, etc.

iluminación, modos de dibujado, condición de

• ser modificados Nodo SCS: Permite definir un sistema de coordenadas que no puedendurante la simulación (Static Coordínate System), se utilizan para ubicar objetos en distintas posiciones de la escena

• Nodo DCS: Permite definir un sistema de coordenadas que puede ser modificado durante la simulación (Dynamic Coordínate System). Se utiliza para implementar objetos articulados u objetos que se desplacen por la escena.

• (Flux Coordínate System). Es de características similares al DCS, pero Nodo FCS:presenta características especiales para su utilización en multiproceso.

• Nodo Switch: Es un nodo que puede tener varios hijos y permite que el usuarioseleccione cuales de ellos quiere que sean dibujados.

• Nodo Secuence: Es un nodo que puede tener varios hijos, los cuales va mostrando de forma secuencial. Se utiliza para representar secuencias animadas. Una secuencia consiste en una lista ordenada de hijos, cada uno de los cuales con una duración asignada. Es posible hacer que la secuencia se ejecute de inicio a fin, de fin a inicio, que se repita cíclicamente, etc.

• Nodo LOD: Se emplea para gestionar distintos niveles de detalle de un objeto. • Nodo Layer: Es un nodo hoja, que permite establecer un orden de dibujado en el caso

de geometría coplanar. • Nodo LighSource: Contiene la especificación de una fuente de luz.

32

Page 34: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Nodo BillBoard: Rota una geometría de modo que siempre aparezca orientada hacia el punto de vista. Es especialmente útil para representar objetos que tienen una simetría axial, como pueden ser árboles, farolas, etc.

• Nodo Partition: Particiona la geometría para realizar intersecciones eficientes. • s también un nodo hoja que se utiliza para renderizar textos Nodo Text: E

tridimensionales. • Nodo ASD: Permite realizar transiciones suaves entre superficies complejas tales como

grandes superficies de terreno (Active Surface Definition).

2.1.4.2 Open Inventor. La l e s 3D basa denominimpespecifi del Open Inventor, una vers

ibr ría Inventor es también un sistema de definición, manipulación y renderizado de escenada en la utilización de descripciones geométricas de alto nivel. La versión original seaba Iris Inventor funcionaba exclusivamente sobre máquinas SGI, y estaba

lementada como una capa por encima de la librería IrisGl. En el momento que ARB creo la cación de librería OpenGl, también se realizó una descripción

ión multiplataforma del antiguo Iris Inventor que utilizase como base a la librería OpenGl.

Inve r orado de nodos nto prima la usabilidad sobre el rendimiento. Está formado por un conjunto muy elabde u con so muy sencillo, pero no proporciona un buen rendimiento en tiempo real (al menos comparadootro ss si temas como OpenGl Performer). Las principales características de Open Inventor son:

• Facilita la organización de escenas 3D. Por tener una estructura de grafo de escena, permite organizar jerárquicamente la información de forma sencilla.

• Proporciona estructuras gráficas predefinidas. Las formas básicas proporcionadas por Inventor son cajas, conos, esferas y cilindros, además, permite definir textos 2D y 3D.

• Proporciona utilidades gráficas ya definidas, por ejemplo rutinas para manejar matrices. • Tiene mecanismos muy flexibles de descripción de formas y objetos. Permite definir

objetos a partir de curvas y superficies de tipo NURBS, y también a partir de mallas de triángulos.

• Tiene capacidades de rendering sofisticadas. Permite seleccionar entre distintos modos de renderizado. Se pueden seleccionar distintas cámaras y distintos modos de visualización interactiva.

• Proporciona un método integrado de selección y manipulación interactiva de objetos. • Es extensible de tal modo que es posible crear nuevos tipos de primitivas y objetos. • Tiene un formato de fichero 3D con descripciones de alto nivel. • Permite incorporar animaciones, teniendo nodos especialmente diseñados para ese

propósito. • No está diseñado para soportar multiproceso.

Inventor es un grafo de escena en el que las propiedades de cada nodo afectan a los nodos que están por debajo de él y también a los nodos colocados a su derecha. Cada nodo puede ser una forma, una propiedad de su apariencia, una transformación, una cámara o una luz. Algunos de los tipos nodos que Open Inventor emplea son los siguientes:

• Nodo Shape: Representa un objeto 3D o 2D como puede ser una esfera o un cubo. • Nodo Transform: Representa transformación afín, como por ejemplo una traslación o

una rotación. • Nodo Appearance: Modifica la apariencia de los objetos que le siguen en el grafo. • Nodo Light: Aplica una iluminación a los nodos que le siguen. • Nodo Camera: Visualiza los nodos que le siguen.

33

Page 35: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Nodo Separator: Separa el efecto de los nodos que hay por debajo de él de tal modo que no afecte a los nodos que hay a su derecha.

• Nodo Units: Especifica el tipo de unidades medida del mundo real que se corresponde a los nodos que le siguen (como por ejemplo centímetros, pulgadas o metros), y aplica un factor de escala en el caso que sea distinto de los nodos que le precedían.

• Nodo Sensor: Detecta el momento en el que ocurre un determinado evento, como por ejemplo que un timer llegue a su final, o que un nodo haya sido seleccionado por el usuario, y lanza una llamada a una rutina de callback definida previamente.

• Nodo Manípulator: Asigna a los objetos una interfaz 3D que permite de modificar su posición, su tamaño y orientación de un modo muy sencillo.

• Nodo Complexity: Permite controlar la calidad con la que se quieren dibujar los nodos que le siguen.

• Nodo Texture: Especifica una textura para los nodos que le siguen. • Nodo Environment: Define efectos atmosféricos, como por ejemplo niebla. • Nodo Normals: Es utilizado para realizar cálculos de iluminación.

En la Figura 2-9 se puede apreciar el aspecto de un Grafo de Escena de Inventor. Todos los grafos de escena comienzan con un nodo que actúa como raíz, y usualmente existe una cámara en la parte izquierda del grafo que es el que permite visualizar el resto de la escena. El siguiente nodo es de tipo Light, que sirve para iluminar a los objetos que le siguen, si ese nodo estuviese puesto después de la primera esfera, ésta no estaría iluminada. El resto son los objetos de la escena. Cada uno de ellos tiene su propio subgrafo que comienza por un nodo Separator que hace que lo que ocurra en el subgrafo no afecte al resto de los nodos. A cada nodo Shape le precede un nodo Transform, que permite colocar cada objeto con la posición y orientación deseada.

Figura 2-10. E utilizado por Invjemplo de Grafo de escena entor.

Una de las objetivos principales de In finir escenas 3D interactivas. Inventor gestiona automáticamente la selección 3D, así como el movimiento del usuario por la por la escena 3D o os 3D. También permite asociar animaciones automáticas a los objetos.

ventor es depulación de objetos y mani

en torno a los objet

34

Page 36: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.4.3 VRML VRML (Virtual Reality Modeling Language) es un formato de fichero de texto que sirve para realizar descripciones de objetos 3D y entornos interactivos en Internet. Permite la incorporación de textos, imágenes y secuencias de audio y vídeo. Es posible hacer que un entorno VRML, conecte con otro entorno VRML en otro lugar de la red de dos formas posibles: puede que un objeto 3D de una escena, por ejemplo un mueble, se esté cargando de una dirección en Internet diferente de la de la habitación principal, o puede que al seleccionar la puerta de dicha habitación accedamos a una habitación que está en otro servidor dentro de la red. Además, VRML ha sido diseñado para trabajar interactuando con Java y JavaScript. Concebido como una extensión de Inventor, sufre de sus mismos problemas de rendimEl formato VRML se encuentra en su versión 2.0. Su primera versión (VRML 1.0) sólocrear y visualizar mundos 3D estáticos. En la versión VRML 2.0 incorpora elementos que permiten hacer que los objetos 3D se modifiquen automáticamente y sean capaces de responder a la acción del usuario. En la Figura 2-10 se muestra un esquema con los definidos por VRML, gran cantidad de ellos (Group, switch, LOD...) ya son conocidos de grafos de escena como Performer o Inventor.

iento. permitía

Grouping nodesAnchor Billboard Collision

SensorsCylinderSensor PlaneSensor

AppearanceAppearanFontStyle

ce

ImageTexture Material MovieTexture PixelTexture TextureTransform

ProximitySensor SphereSensor TimeSensor TouchSensor VisibilitySensor

Group Transform

Special GroupsInline LOD Geometry Interpolators Switch Box

Cone Cylinder ElevationGrid Extrusion In

ColorInterpolator CoordinateInterpolator NormalInterpolator OrientationInterpolator PositionInterpolator

Common NodesAudioClip DirectionalLight PointLight

ScalarInterpolator dexedFaceSet exedLineSet

PointSet Sphere

Script Shape Sound

Ind

SpotLight Text WorldInfo

Geometric PropertiesColor CoordinatNormal TextureCoordi

e

nate

Bindable NodesBackground Fog NavigationInfo Viewpoint

Tabla 2-1. Nodos de VRML 2.0.

Llama la atención de existencia de nodos muy especializados como el Background que permite añadir imágenes de fondo, lo que permite representar por ejemplo montañas lejanas y un cielo, o de un tipo de nodo para crear fácilmente terrenos irregulares (nodo ElevationGrid). También existen nodos como el Collision que permiten hacer que un objeto reaccione como si fuese sólido de tal modo que el usuario no puede atravesarlo pero si caminar sobre él. Existe un grupo de nodos que actúan como sensores (de un modo similar a como hacia inventor) y que permiten que la escena reaccione a las acciones del usuario. Los distintos nodos de tipo interpolator permiten crear animaciones predefinidas que pueden ser ejecutadas cuando sea necesario. Con este tipo de nodos se pueden definir modificaciones dinámicas sobre los objetos de la escena,

35

Page 37: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

así es posible definir un objeto que presente un morphing geométrico, una puerta de apertura automática o un objeto que varia cíclicamente su color o que recorre una trayectoria determinada. El nodo Sound permite incorporar sonidos con una ubicación espacial tridimensional. Uno de los nodos más importantes en VRML es el nodo Script, el cual básicamente contiene un programa que recibe eventos de entrada, los procesa y genera eventos nuevos, mediante la utilización de este tipo de nodos se puede hacer que la escena y sus objetos presenten comportamientos muy sofisticados. También resulta muy interesante la capacidad que tien l dos e e usuario para definir nodos PROTO los cuales pueden contener en su interior más noVRML, campos y scripts. Un desarrollador puede definir un nodo PROTO con unas determi pliado por un nadas características, de tal modo que puede ser utilizado, modificado o amsegundo desarrollador. En e milar a gen ral se puede establecer una clasificación similar en nodos grupo y nodos hoja sila de Pe tidad de nodos (Figura 2-10), y las rformer o Inventor. Pero la gran caninte p e rde endencias que se establecen entre ellos, hacen VRML resulte mucho más confuso qulos grafos de escena anteriores.

2.1 4 Ope caplicacivirt ográfica bajo nivadic aaplicaci El c zpara tenplata rC++ tgrafo de escena ser rápidamente portado a un gran

desarrollado en IRIX, portado a Linux, Windows,

Play Todo el código de O(permite a proyectoslibremente). Open Sculling, nodos c ndibujado c OpenSceneGrrendimiento igOpen Sce Gsoporta m ip Open Scene G

.4. OpenSceneGraph.

nS eneGraph (OSG) es un toolkit gráfico de alto nivel y portable para el desarrollo de ones gráficas de alto rendimiento tales como simuladores de vuelo, juegos, realidad

ual visualización científica. Está orientado a objetos y construido a partir de la librería OpenGL, esto libera al desarrollador de implementar y optimizar llamadas gráficas de el, y provee muchas utilidades

ion les para un rápido desarrollo de ones gráficas.

ora ón del grafo de escena ha sido diseñado er mínimas dependencias de una ma específica, requiriendfo o poco más que

es ándar y OpenGL. Esto ha permitido al

número de plataformas (originalmente

FreeBSD, Mac OSX, Solares, HP-UX e incluso Station2).

penSceneGraph esta publicado bajo de código abierto y cerrado utilizarlcene Graph soporta view frustum cu

on ivel de detalle (LOD), clasificación domo parte del corazón del grafo de escena.

aph es uno de los grafos de escena disponiuala a otros grafos de escena como OpenG

ne raph opta por soluciones muy parecidas a ult roceso, característica que soporta OpenGL

raph esta formado por los siguientes espac

• osg : Es el núcleo de la librería OSG, y proporcioescena tales como Nodes, Status, y Drawables, a

Figura 2-11. Imagen de un videojuego usando OpenSceneGraph.

occlusion culling, small feature de

r o Vega Scene Graph. no

res:

la OpenSceneGraph Public License a, modificarla y distribuirla lling, e estado, vertex arrays y listas

bles de mayor rendimiento. Este L Performe

OpenGL Performer. Por contra, Performer.

ios de nomb

na las clases básicas del grafo de sí como clases matemáticas y otras.

36

Page 38: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• osgDB: osgDB proporciona soporte para leer y escribir grafos de escena, propo clases para manejo de ficheros. rcionando un framework para plugins y

• os X proporcionar un gF : Es una extensión del núcleo del grafo de escena parafr eam work de efectos especiales.

• os A mientas para ayudar a los gG : osgGA (osg GUI Abstraction) proporciona herrade rrsa olladores para trabajar con distintos sistemas de ventanas.

• osgInt entorno de programación que permite la consulta en rospection : Proporciona untiempo de ejecución de las propiedades y los métodos relacionados con las librerias OSG.

• osgParticle : osgParticle amplia el núcleo del grafo de escena para soportar efectos de partículas.

• osgProducer : Es una librería de utilidades que integra OpenProducer para proporcionar clases de viewer de propósito general.

• osgSim : osgSim extiende el núcleo del grafo de escena para soportar Nodes y Drawables que especifiquen la simulación visual, tales como soporte para un punto de luz navegacional y transformaciones de grados de libertado del estilo OpenFlight.

• osgTerrain : Librería de utilidades que proporciona soporte para la generación de bases de datos de terreno.

• osgText : Extiende el núcleo del grafo de escena para dar soporte a texto de alta calidad. • osgUtil : Proporciona clases de utilidad de propósito general, tales como recorridos de

update, cull, y/o Draw, operadores de grafo de escena como son optimisation, tri stripping, y tessellation.

• osgUtx : osgUtx es un entorno de programacion para la evaluacion de aplicaciones.

OpenSceneGraph emplea los siguientes tipos básicos de nodos:

Transform : Clase base para aplicar una transformación al subgrafo. nsform : Transformación de una matriz 4x4.

orm : Nodo de transformación de grados de libertad. Geode : Es un nodo hoja que almacena la información geométrica de un objeto.

siempre aparezca orientada hacia el

simetría axialetalle de un objeto

os. : Es un nodo que puede tener varios hijos, los cuales va mostrando de

ena

Node : La clase base para todas la clases que derivan de Node. Group : Agrupa varios nodos hijos.

MatrixTra PositionAttitudeTransform : Transformación que usa un Vector de tres

coordenadas (Vec3) para la posición, y una rotación de Cuaternion (Quat) para la actitud, y un Vec3 para el pivote.

DOFTransf

Billboard : Rota una geometría de modo que punto de vista. Es especialmente útil para representar objetos que tienen una

, como pueden ser árboles, farolas, etc. LOD : Se emplea para gestionar distintos niveles de d Impostor : añade soporte para el cacheado jerárquico de imágenes. Switch : Es un nodo que puede tener varios hijos y permite que el usuario

seleccione cuales de ellos quiere que sean dibujad Sequence

forma secuencial. Se utiliza para representar secuencias animadas. Una secuencia consiste en una lista ordenada de hijos, cada uno de los cuales con una duración asignada. Es posible hacer que la secuencia se ejecute de inicio a fin, de fin a inicio, que se repita cíclicamente, etc.

LightSource : Posición un objeto Light en la esc ClipNode : Posiciona un objeto ClipPlane en la escena Projection : Sobrecarga la matriz de proyección. OccluderNode : Permite colocar en la escena planos y cajas para definir

oclusiones entre objetos.

37

Page 39: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.4.5 Otras librerías graficas de alto nivel En los últimos años han surgido distintos grafos de escena, es norma general que de un modo u otro reproduzcan las funcionalidades de los tres citados anteriormente. Cabe destacar que algunos de ellos proporcionan un rendimiento similar a OpenGl Performer y son de código abierto y multiplataforma. No tiene sentido aquí profundizar en las particularidades de cada uno de ellos, simplemente se mostrará una descripción abreviada y un enlace de Internet para obtener información adicional: OpenRM. (http://openrm.sf.net) Es un entorno de desarrollo OpenSource, empleado para implementar aplicaciones 3D en sistemas Unix/X11 y Win32, puede trabajar con varios threads. OpenSG. (http://www.opensg.org) Es una librería basada en C++ y OpenGl que contiene un grafo de escena. Es distribuido bajo los principios de Open Source, es multi-thread, multiplataforma (Linux, Irix, Windows), y fácilmente extensible. Es mantenido por varias empresas y centros de investigación. PLIB/SSG. (http://plib.sf.nef). PLib es un conjunto de librerías multiplataforma diseñadas para ayudar a los desarrolladores de aplicaciones 3D interactivas. Es también distribuida bajo los principios de OpenSource. SSG (Sim ódulos que proporciona un grafo de escena implementado ple Scene Graph) es uno de sus msob penGl y C++. re la base de O RMScenegraph. (http://www.r3vis.com/RMSSceneGraph)- Es un grafo de escena basado en OpenGl, actualmente disponible para Unix, Linux y Win32. SGI OpenGL Optimizer. (http://www.sgi.com/software/optimizer). Es un conjunto de herramientas orientadas al mercado del CAD/CAM. Optimizer en sí mismo no es un grafo de escena, pero emplea internamente un grafo de escena (similar a VRML) especialmente optimizado para manejar modelos voluminosos. SGL. (http://sgl.sf.net). Es un conjunto de librerías multiplataforma desarrolladas en C++ y que operan sobre OpenGl, gestiona de forma adecuada la selección de objetos y cálculo de intersecciones, permite cargar distintos tipos de formatos de imagen, y dispone de varios métodos de culling. Sun's Java 3D. (http://java.sun.com/products/java-media/3D). El API de Java3D proporciona un conjunto de interfaces orientados a objetos, que permiten a los desarrolladores definir una escena de 3D y su comportamiento, de una forma independde plataforma. Internamente dispone de un grafo de escena que introduce algunos conceptos comúnmente no considerados como parte del entorno de simulación tales como sonido espacial 3D.

iente

.1.5.1.1 3D GameStudio

mercial de juegos de ordenador. Consta de un motor de niveles y modelos, un compilador de scripts y librerías de

modelos, texturas,... Manipula con igual rendimiento escenas de interior y de exterior. Tiene un

2.1.5 Motores de Videojuegos

2.1.5.1 Motores de Visualización

2

3D GameStudio es un kit de desarrollo co3D, un motor 2D, un editor

38

Page 40: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

motor de iluminación que soporta sombras verdaderas y fuentes de luz en movimiento. El principal objetivo que esta aplicación persigue es que el desarrollador del juego no necesite sun programador experimentado. Se reduce al máximo el esfuerzo de desarrollo a costa de perdeflexibilidad en el diseño del juego. La última versión (v5) es de marzo de 2002. Ofrece tres posibilidades para crear un juego: 1) Juegos diseñados a base únicamente de controles, para usuarios con pocos conocimientos de

programac

er r

ión.

o Delphi, para programadores con experiencia.

llamado

ristal Space es un kit de desarrollo gratuito de juegoSoporta seis grados de libertad, luces de colores, mipmsup cprocedu , halos(Py n

lide, y visualización por software, soporte para fuen

n gran proyecto para el desarrollo de software abiertubscritas a sus listas de correo.

ado a eventos. La cola de eventoseda. El gestor de eventos se enca

rio. Aunón y eve

visualines graf

ción de escee fotogramas por segundo siempre y cuando estén coolígonos. También puede ser utilizado para escenas d

realiza tomando ciertas precauciones. Sus principales precalculada y chequeo de la varios exteriores sin imponer a

de la escena.

2) Juegos o efectos diseñados con algo de programación utilizando C-scripts.

3) Juegos o efectos programados en C++

Incorpora un núcleo de videojuegos, A5. Pero lo que aquí se entiende por núcleo es un sistema de desarrollo que se encarga de generar efectos 3D y controlar la inteligencia artificial del juego.

2.1.5.1.2 Crystal Space

C

erfi ies reflectivas, sprites 3D (basados en frames rales, radiosidad, sistemas de partículas

tho y otros), soporte para visualización a 8-bits, 1GActualmente Crystal Space puede ejecutarse sobre GNBeOS, NextStep, OpenStep, MacOS/X Server, DOS, us

Es un paquete orienteventos a quien proccscmdProcess) y gestiona los eventos de usuaaplicación, se limita a mensajes de visualizaci

2.1.5.1.3 Genesis3D

Genesis3D es un motor de código libre para latiempo real y que permite construir aplicaciodiseñado principalmente para la visualizadp

colisiones, iluminación la visualización de escen

Figura 2-12. Captura del editor de 3D Gamestudio.

s 3D libre y portable escrito en C++. apping, portales, espejos, transparencias,

, niebla volumétrica, lenguaje de script

tes, transformaciones jerárquicas,...

e es o. Hay alrededor de 600 personas

gestiona los eventos del sistema y envía rga de lanzar la visualización (evento que existe cierto paso de mensajes en la ntos de usuario.

zación de escenas tridimensionales en icas 3D de altas prestaciones. Ha sido nas de interior logrando una elevada tasa mpuestas por una cantidad moderada de e exterior si el diseño de las escenas se

características son la detección rápida de isibilidad. Su principal inconveniente es lgún tipo de restricción o límite al tamaño

o animaciones de esqueleto), texturas

6-bits y 32-bits, Direct3D, OpenGL,

U/Linux, Windows, Windows NT, OS/2, y Macintosh entre otros. Crystal Spac

39

Page 41: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

La versión actual es la v1.1 (noviembre de 1999), se va enriqueciendo mediante las contribuciones o comentarios que realizan los usuarios. No incluye rutinas de gestión de eventos.

2.1.5.1.4 The Nebula Device

he Nebula Device (RadonLabs) es un nuevo motor de juegos gratuito de calidad profesional. Sus creadores, son el equipo que desarrollo rban Assault (publicado por Microsoft en 1998).

(Xbox). Nebula es un motor de arquitectura moderna. Desarrollado en C++ y orientado a objetos, sus clases (DLLs) se cargan de forma

X, D.

uías 3D, texturas, materiales, luces, sonidos,

Proporcionar herramientas básicas de trabajo en equipo para el desarrollo del juego.

El servidor de entrada gestiona los eventos de entrada de usuario utilizando una lista de eventos. Se utiliza un mecanismo de paso de mensajes para el tratamiento de los jugadores en red.

2.1.5.1.5 OGRE

OGRE (Object-Oriented Graphics Rendering Engine) es un motor escrito en C++ flexible, orientado a escenas, y diseñado para hacer más simple e intuitiva a los desarrolladores la producción de juegos utilizando hardware de aceleración 3D.

a librería de clases permite abstraer los etalles asociados a las librerías de bajo nivel

(OpenGL o Direct3D), proporcionando una

hark3D es un kit de desarrollo de alto nivel para aplicaciones 3D en tiempo real. Esta orientado a juegos, aplicaciones de realidad virtual y visualización.

licaciones multiusuario a través de una red de computadores o internet. Distribuido. Contiene un servidor de múltiples escenas.

TU

Utilizado también para desarrollar The Nomads

independiente en tiempo de ejecución. El motor puede ejecutarse en Linux, Windows 9Windows NT. Permite intercambiar sin interrupción la visualización con OpenGL y Direct3Nebula utiliza como lenguaje de script el estándar tcl/tk. Los principales objetivos de Nebula sonlos siguientes:

• Independencia de la plataforma. • Gestión de la base de datos del juego: jerarq

animaciones, estados y sus relaciones. •

Ld

interfaz basada en objetos.

2.1.5.1.6 Shark3D Figura 2-13. Juego de billar desarrollado con OGRE

S

Optimizado para ap

Incluye gestión de eventos de usuario y paso de mensajes para comunicación en red y como comunicación entre los diferentes elementos de su arquitectura.

40

Page 42: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.5.1.7 The Torque Game Engine

The Torque Game Engine (TGE) (Garagegames) es el motor comercial desarrollado por DINAMIX para su juego Tribes 2. Enfocado a la simulación de misiones militares, incluye utilidades para la creación de terrenos, superficies acuáticas, interiores estilo portal y sistemas de partículas. También incluye soporte multiplataforma (Windows, Mac OS y Linux), soporte

uario y lenguaje de script estilo C++. Permite importar bjetos desde 3D Studio MAX y dispone de librerías matemáticas, de detección de colisiones,

de f aIncl e so de mensajes para comunicación en red.

para red, creación de interfaces de uso

ísic de vehículos y una base de datos espacial. uy gestión de eventos de usuario y pa

Figura 2-14. Editor de Torque Game Engine

de un

o

mejorar la velocidad de visualización que permite maximizar el uso del ardware grafico disponible. Estas estructuras jerárquicas permitirán mantener una frecuencia e cuadro uniforme, sobre los 30 fps, consiguiendo la continuidad visual necesaria en el juego.

2.1.5.1.8 CDX Game Development Kit

CDX Game Development Kit es un kit de desarrollo de videojuegos de código libre. Consta conjunto de clases de C++ para crear juegos para Windows y utilizando DirectX. Permite la creación de juegos sencillos. Contiene rutinas de gestión de los eventos de entrada.

2.1.5.1.9 Artist

Artist (Animation Package for Real-Time Simulation) es un paquete de animación de bajo coste para el desarrollo de aplicaciones 3D complejas e interactivas en tiempo real: juegos, simulación y realidad virtual. Artist permite generar gráficos con velocidad optimizada y aspectos de comportamiento de los objetos en un juego, simulaciones o aplicaciones de realidad virtual. Consigue enlazar ambos aspectos de forma eficiente y sencilla, generando el código necesaripara ejecutar la simulación del comportamiento. Puede generar bases de datos graficas optimizadas para hd Incluye las siguientes herramientas:

• Modelador de objetos geométricos de propósito general. • Base de datos jerárquica grafica. • Conversores de fichero desde los formatos gráficos usuales.

41

Page 43: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Interfaz 3D para añadir objetos interactivos en las escenas de los juegos. • Editor de jerarquía grafica para la configuración de los parámetros de la gestión de la

base de datos y la incorporación de descripciones de comportamiento a los objetos geométricos de la base de datos.

• Descripción de alto nivel orientada a objeto del comportamiento de los objetos y las características del juego.

Figura 2-15. Captura del programa Artist.

2.1 2

2.1.6.2

s un núcleo de videojuegos de reciente creación, altamente estructurado y comentado y rientado a objetos. Ambas versiones están desarrolladas en C++ y todo el código específico del

juego se encuentra desarrollado con DLLs plugins (se incluye una herramienta para crear na amplia gama de herramientas y utilidades que facilitan el proceso de

desarrollo del juego.

úcleo y permitiendo un desarrollo modular. e pueden implementar múltiples aplicaciones sin necesidad de replicar el núcleo.

do nto

e funciones virtuales que s objetos del juego deben redefinir.

.6. Motores de Videojuegos

.1 Fly3D

s un motor de Fly3D e juegos gratuito que acompaña al libro 3D Games de Alan Watt y Fabio Policarpo. El motor se encuentra actualmente en la segunda versión v2.0 (disponible en el segundo volumen del libro). Eo

plugins). Contiene u

El motor permite crear videojuegos y aplicaciones graficas en tiempo real de forma fácil y sencilla. Para ello se crean nuevos plugins que se enlazan con la aplicación, sin necesidad de recompilar el nSLa implementación del comportamiento visual y dinámico esta también modularizada, debienimplementar para cada objeto una función específica de visualización y otra de comportamie(simulación). Para conseguir que los objetos del juego se comporten de forma uniforme, heredan de un objeto base de Fly3D. El objeto base contiene una serie dloEs un motor de código libre y los videojuegos creados usando Fly3D v.1 pueden incluso comercializarse.

42

Page 44: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.6.3 Videojuegos Completos La información existente sobre videojuegos es muy abundante en la red. Gran parte de esta información hace referencia a trucos de juego, manuales, modificaciones de código, creación deficheros de configuración, evaluaciones, módulos de desarrollo concretos e incluso, a veces, el código fuente. No obstante, la información sobre la implementación de videojuegos es mínima, en algunos casos s

e limita a algún fichero cabecera, algún API o cierta información sobre las mación, además de ser escasa, se suele limitar iones se dispone del código del juego para istema.

de los videojuegos se lleva a cabo en las

tra en aspectos como visualización o en la para la gestión del comportamiento de los

implícito, a lo que no se ha prestado mucha

mayor parte de ellos corresponde a pequeños eden considerarse como motores de videojuegos.

mente comerciales) con código publicado. o los videojuegos Doom y Quake por las

• Son juegos de código libre. Ciertas versiones de Doom y Quake tienen el código ión y modificación bajo licencia GNU.

ta completamente liberado. En otros videojuegos de código libre, ciertas partes del código son bibliotecas de código cerrado, pueden usarse pero no modificarse

te conocidos y utilizados.

de no ne l

2.1 3

oom es o de laberintos en primera persona creado por John Carmack en 1993. Es un

bre la parte física de la entidad, como posición de la entidad o tipo. as entidades no incluyen información sobre los eventos del sistema.

primitivas utilizadas. En cualquier caso, esta infora la parte grafica del juego. Solo en contadas ocaspoder estudiar como se gestionan los eventos del sLa mayor parte de la investigación en el campocompañías desarrolladoras de juegos. La investigación que se ha llevado a cabo en las universidades y centros de investigación se cenaplicación de técnicas de inteligencia artificialpersonajes, siendo el modelo de simulación algo importancia. Existen numerosos juegos con código abierto. La juegos creados por aficionados y que no puMuy pocos son los videojuegos complejos (habitualDentro de estos se han elegido como base del estudisiguientes razones:

liberado, disponible para su predistribuc• Su código es

(como Serious Sam o Unreal Tournament ). • Doom y Quake marcaron un hito en la historia de los videojuegos y son ampliamen

• Despiertan interés de una amplia comunidad de programadores. • Son juegos robustos y ampliamente probados. • Siguen el paradigma convencional de videojuegos. • El primer videojuego importante cuyo motor se utilizo para la creación de otros

videojuegos fue Doom. El autor de Doom mejoro e incorporo características 3D a este motor, creando Quake, que a su vez sirvió también para la creación de nuevos videojuegos.

demás, se ha incluido en el estudio el videojuego Unreal Tournament, porque a pesarAte r e código liberado, despierta un gran interés en la comunidad científica.

.6. .1 Doom

un juegDjuego 2D, aunque simula cierta profundidad. La única versión del juego liberada es la v1.1 paraLinux (Idsw). Utiliza como entidades básicas las estructuras things, que definen elementos del juego como monstruos, armas, llaves o posiciones de inicio de un jugador. El tipo de datos thing incluye

nicamente información soúL

43

Page 45: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Para gestionar los eventos se utiliza una lista doblemente enlazada con un único puntero a cabeza. Cada evento contiene tres funciones que definen las acciones a realizar cuael evento. Los eventos se ejecutan comenzando por la cabeza

ndo suceda de la lista hasta alcanzar la cola,

jecutando para cada evento las acciones asociadas. en la

sistema

os a rvalos de muestreo. Por ejemplo, en Doom no existe la bomba de relojería. Para que

na granada estalle, esta debe ser disparada y estallara cuando colisione con el suelo, una pared

ealiza en cabeza de la lista, por ello, s nuevos eventos se trataran siempre en el

siguiente ciclo, independientemente de que algún evento corresponda al ciclo actual. Cualquier evento que se produzca con una frecuencia superior a la frecuencia de muestreo, es sencillamente obviado.

2.1.6.3.2 Quake

Quake es un juego de arcade de laberintos en primera persona creado por John Carmack en 1996. Es el primer juego realmente 3D. La versión objeto de este estudio ha sido la v2.3. El elemento básico de Quake para la gestión del comportamiento de los personajes y objetos es la entidad. Las entidades son partes independientes del entorno virtual, como monstruos, jugadores, objetos o posiciones en el espacio. Una entidad especial es world, que define el entorno estático por el que se mueven los personajes. En la entidad confluyen una serie de propiedades físicas y otras propiedades que determinan sus reglas de comportamiento. Al comportamiento de las entidades se le denomina dentro del juego inteligencia artifi tificial. La

teligencia artificial utiliza tres propiedades de la entidad para gestionar los eventos:

comportamiento.

• Función que define el comportamiento justo antes de modificar físicamente la entidad

eLos eventos no tienen tiempos asociados, se ejecutan todos y en el orden en que aparecen lista. La lista de eventos se recorre desde la cabeza hasta la cola. Todos los eventos son evolucionados obligatoriamente a la máxima velocidad que elpueda obtener. El sistema analiza desde el último estado, cual es el nuevo estado en el que se debe encontrar el sistema en función del tiempo transcurrido. Este esquema de simulación obliga a que un objeto nunca pueda programar eventos situadvarios inteuu otro personaje. La gestión de eventos discretos debe realizarse de forma explícita por el programador al margen

Figura 2-16. Captura del juego Doom 3.

del núcleo del videojuego y cada objeto debe gestionarla de forma independiente. La ordenación de los eventos en la lista no es cronológica sino que dependerá del orden en que se gestione el sistema. La inserción de nuevos eventos se rlo

cial, aunque no utilicen técnicas propiamente de inteligencia arin

• Tiempo en el que debe suceder el siguiente evento relacionado con la entidad, momentoen el que cambiara de algún modo su

(como moverla o hacer que dispare). • Función que define el comportamiento de la entidad después de modificar su parte

física. La descripción de la escena esta constituida por un vector de entidades. El vector se recorre en orden, comenzando por la entidad world (primera posición del vector), y se comprueba si cada

44

Page 46: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

una de las entidades tiene que modificar su comportamiento en el instante actual, comprobandsi el tiempo asociado al evento vencerá en el próximo intervalo de tiempo. Este intervalo lo

o

redefine el programador.

a

el s

racing

ir e

tre icies c LOD

p

2.1.6.3.3 Unreal Tournament

Unreal Tournament es un motor grafico comercial desarrollado por la empresa Epic Games, mente modular y orientado a objetos. Es multijugador, basado en arquitectura alt

cliente/servidor. Nace en 1998 tratando de emular a Quake2. Disponible para las plataformas Linux, Windows, Macintosh, Playstation 2 y Xbox. Para desarrollar con este motor se debe adquirir una licencia que da acceso a todo el código fuente, a las herramientas y juegos. Cierto código y las librerías del núcleo están disponibles gratuitamente. Para trabajos y desarrollos que hagan uso del motor grafico sin tratar modificar el núcleo (como son los desarrollos y proyectos de inteligencia artificial e interfaces) el motor es una herramienta posible, por lo que se utiliza ampliamente en investigación (Gamebots o CaveUT). Utiliza el sistema DSG (Dynamic Scene Graph Technology) que es una extensión natural drenderizado en portales, interpolación de meshes, radiosidad, arboles BSP, LOD, superficiecurvas y superficies reflectantes. Incorpora luces multicolores, dinámicas, lightmaps, rayty enveloped lighting. Soporta el formato DXF. Incorpora texture mapping, mapas de sombras, mapas de niebla, textura detallada para definobjetos muy detallados, texturas procedurales, texturas en tiempo real de ondas, 12 niveles dmipmapping, animación de texturas, texturas procedurales, dinámicas y multitextura. De enotros detalles destacamos: detección de colisiones cilíndrica, superf urvas con ,mapas de entorno, inteligencia artificial avanzada, sistema físico adaptable, sprites 3D o sonido digital 3D.

Figura 2-17. Captura del juego Unreal Tournament 2007.

Define un lenguaje de script: UnrealScript, que es un lenguaje semicompilado para acceder a la lógica del juego y usar el potencial del motor grafico. Permite trabajar con una interfaz de alto nivel para controlar los objetos en un juego.

45

Page 47: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

El desarrollo de juegos y herramientas que hacen uso del editor de mapas UnrealED. La orientación a objetos de Unreal permite añadir nuevos objetos y funcionalidades una vezterminado el desarrollo.

tre los jugadores los actores. Cada actor en el mapa puede estar bajo control de un jugador o el control de un

script. El script define completamente como el actor se mueve e interacciona con otros actores.

l bucle de actualización sigue los siguientes pasos:

al servidor la petición de movimiento. El servidor le contesta con el

n

ada tick. Un tick es la menor unidad de tiempo con la cual el actor uede ser actualizado. Normalmente la frecuencia de ticks suele estar entre 10 y 100 veces por

ción ).

ientras un actor esta ejecutando una función latente, la ejecución del actor se paraliza hasta de ejecutarse. Sin embargo, otros actores o la maquina virtual puede seguir

jecutándose. Cada actor tiene su propio hilo de ejecución. Pero, estos hilos son virtuales. Unr sEn la operación de actualización de los actores, se les informa de los eventos pendientes, ejec n l código asociado a la actualización de los acto variable erente a Doom y Quake, quienes actualizan el sistema sup e tualización es fijo). La clase los objetos de un juego en Unreal. La clase Actor con e racciones con otros acto , e de toda adefi o por el control del jugador.

2.1 3

Sou ente Valve Source Engine) es un motor 3D de videojuego desarrollado or Valve Corporation. Entre sus características cabe destacar su alto grado de modularidad y exibilidad, renderer con shaders, tecnología de expresión facial, y un eficiente sistema físico

Xbo 6Source.

La maquina virtual de Unreal esta compuesta de: servidor, cliente, motor de visualización y motor de soporte de código. El servidor controla el juego y las interacciones eny

E 1. El servidor comunica el estado del juego a los clientes. El estado del juego es el conjunto de

estados de sus elementos. 2. Cada cliente envía

nuevo estado del juego. El cliente comienza el proceso de visualización de su escena. 3. El cliente realiza la operación de actualizacion (Tick()) del estado del juego, tomando e

consideración el tiempo desde la ultima actualización (ultima llamada a la función Tick()). Para gestionar el tiempo, Unreal divide cada segundo del juego en ticks. El estado del videojuego se actualiza con cpsegundo, aunque este valor depende de la potencia de la CPU. Las funciones que necesitan mas de un tick para su ejecuse llaman funciones latentes (como Sleep, FisnishAnim o MoveToMque terminae

eal imula la utilización de hilos. Los scripts se ejecutan en paralelo.

uta do el código del script asociado. Todo eres se diseña para que el tiempo que ha pasado desde la ultima actualización pueda ser

(igual que en Fly3D, pero difoni ndo que el intervalo desde la ultima ac

Actor es la clase padre de todostien todas las funcionalidades necesarias para que el actor se mueva, interes afecte al entorno y se relacione con los objetos del juego. Pawn es la clase padr

eal, las cuales son capaces de tener un control a alto nivel s l s criaturas y jugadores en Unrnid por i su nteligencia artificial o

.6. .4 Source Engine

rce Engine (oficialmpflen red. Source soporta tanto entornos de 32 bit como 64 bit y plataformas Microsoft Windows, Xbox,

x 3 0 y Playstation 3. Debutó en noviembre de 2004 con Half Life 2 y Counter-Strike:

46

Page 48: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Source actualiz n de ciertos aspectos sin tener que romper otras áreas del motor, o rom

na de las tecnologías desarrolladas para la versión de Xbox de Half –Life 2 fue el File onsistente en cargar los recursos de un mapa al tiempo que el jugador se mueve por

l, en lugar de realizar una carga única antes de jugar. Con este sistema se redujo el tiempo de carg ste sistema era una expansión del sistema de cacheado, ya imp Source Eng carga de ciertos recursos está típica pan a rre. Las xtson c con un inusual sistema de cacheado de son :

está diseñado ascendentemente para ser altamente modular. Esto permite una fácil ación y modificació

per la continuidad del motor.

UStreaming, cé

a a tan solo 15 segundos. Elementado.

ine utiliza un sistema de “cacheado”, a través del cual la manejada y administrada al vuelo, en lugar de una única operación mediante la

tall de carga. Los datos de texturas y sonidos son las principales áreas donde esto ocute uras se cargan en memoria, pero solo se mueven a la tarjeta grafica del sistema cuando

ne esarias, y los ficheros de sonido son cargados ido solo los primeros 0.125 segundos de cada fichero son pre-cacheados.

Figura 2-18. Imagen generada con el Source Engine.

Ambos sistemas mantieantiguos se liberan, y cu

nen los datos en la pila hasta que no hay más espacio y los recursos ando está atascado o ralentizado, el motor se queda parado o entra en un

que este tartamudeo puede ser causado por un mal rendimiento del sistema, se ha bservado también en algunas configuraciones de hardware que deberían ser lo suficiente

potentes para manejar esta tasa de datos, y a pesar de muchas teorías , la causa precisa continua sien d dos años después del debut del motor. La mayor parte de

bucle hasta que los datos llegan. El resultado de estas pausas es una especie de molesto tartamudeo del juego. Mientraso

do esconocida al publico, incluso

47

Page 49: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

las soluciones encontradas apuntan a evitar el sistema de cacheado, ya que no puede ser o directamente.

• Shaders versión 2.0, bump mapping, LOD sobre modelos y el mundo.

zado sistema de partículas que puede emitir sprites o modelos.

• Efectos de partículas, destellos, humo, rayos, sangre, y efectos ambientales como niebla

• Escalabilidad.

erial perse o al ser

arrojado sobre otra superficie, y cual es la masa y la flotabilidad de este objeto.

ersonajes

• Personajes detallados.

imación basado en esqueletos.

deshabilitad En Febrero de 2006, se introdujeron unos cambios en el motor Source, con el objetivo de reducir el problema. Esta actualización se caracterizó por una implementación limitada del sistema de file streaming, y la respuesta fue bastante positiva. Renderer

• Author Shaders con HLSL. • Cube mapping y enviroment mapping. • Luces dinámicas, vertex lighting y light maps, muchos tipos de luces incluyendo

parpadeantes, de pulso, etc. • Iluminación de alto rango dinámico. • Agua con refracción y efectos. • Avan• Proyección de sombras permisible por gran numero de personajes por escena. • Entornos abiertos/cerrados.

o Terreno deformable. o Materiales dinámicamente renderizados (césped, árboles…).

• Superficies de subdivisión, bump maps difuso y especular. • Iluminación por radiosidad en tiempo real.

o lluvia.

Sistema de Materiales

• En lugar de usar las tradicionales texturas, Source define conjuntos de materiales que especifican de que está hecho el objeto y la textura usada para ese objeto. Un matespecifica como se romperá un objeto al ser golpeado, como sonará al rom

Este sistema es mucho más flexible que cualquier otro sistema basado únicamente en texturas.

• Los materiales pueden interactuar con objetos o NPCs como barro o hielo sobre vehículos.

P

• Ojos realistas. o Enfocado automático sobre el jugador. o Brillo en los ojos

• Musculatura simulada proporciona emociones, habla, y lenguaje corporal. • Habla independiente del lenguaje, los personajes pueden hablar naturalmente en

distintos lenguajes. • Sistema de an• El sistema de animación basado en capas puede sintetizar complejas animaciones de

varias partes. Física

48

Page 50: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Mundo más receptivo con interacciones realistas. • Sonidos y gráficos enlazados con la física. • La IA de los personajes puede interactuar con los objetos simulados físicamente. • Cuerdas/cables, maquinas, sistemas de restricción. • Controladores de procedimientos físico personalizados.

máticos, tensión de la amortiguación, etc.

• Todo el código está escrito en C/C++ usando Visual Studio 6.0. Se pueden derivar nuevas entidades de manera fácil y rápida desde las clases base existentes.

• Sistema de monitorización interno. • Herramientas de medida del rendimiento gráfico. • El diseño modular del código (mediante DLL’s) permite intercambiar componentes del

ra una fácil actualización o reemplazamiento de código. e DirectX9 escritos en HLSL.

• Rénder (creación de la imagen final)

individuales que luego serán usados n la escena. Existen diversas técnicas de modelado; Constructive Solid Geometry, modelado

l proceso de modelado puede incluir algunas actividades relacionadas con la preparación del

a

dedicados (como Lightwave 3D, Rhinoceros D o Moray), un componente de una aplicación (Shaper, Lofter en 3D Studio) o por un lenguaje

de descripción de escenas (como en POV-Ray). En algunos casos, no hay una distinción estricta

• Vehículos. o Las ruedas resbalan y patinan. o Suspensión realista en cada rueda. o Inclinación realista en aceleraciones/deceleraciones y giros. o Parámetros configurables individualmente tales como caballos de potencia,

velocidad, aceleración, material de los neumáticos, fricción de los neu

Programación

núcleo pa• Shaders d• Exportadores XSI, Max y Maya .smd para exportar modelos 3D.

2.1.7 Editores 3D El proceso de creación de gráficos 3D por computador puede ser dividido en estas tres fases básicas:

• Modelado • Composición de la escena

Modelado La etapa de modelado consiste en ir dando forma a objetosecon NURBS y modelado poligonal son algunos ejemplos. Los procesos de modelado puede incluir la edición de la superficie del objeto o las propiedades del material (por ejemplo, color, luminosidad, difusión, especularidad, características de reflexión, transparencia u opacidad, o el índice de refracción), agregar texturas, mapas de relieve (bump-maps) y otras características. Emodelo 3D para su posterior animación. A los objetos se les puede asignar un esqueleto, una estructura central con la capacidad de afectar la forma y movimientos de ese objeto. Esto ayudal proceso de animación, en el cual el movimiento del esqueleto automáticamente afectara las porciones correspondientes del modelo. Véase también animación por Cinemática Directa (Forward Kinematic animation) y animación por Cinemática Inversa (Inverse Kinematic animation). El modelado puede ser realizado por programas3

49

Page 51: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

entre estas fases; en dichos casos, el modelado es sólo una parte del proceso de creación de escenas (por ejemplo, con Caligari trueSpace). Composición de la escena Esta etapa involucra la distribución de objetos, luces, cámaras y otras entidades en una escena que será utilizada para producir una imagen estática o una animación. Si se utiliza para Animación, esta fase, en general, hace uso de una técnica llamada Keyframing, que facilita la creación de movimientos complicados en la escena. Con la ayuda de la técnica de keyframing, en lugar de tener que corregir la posición de un objeto, su rotación o tamaño en cada cuadro de la animación, solo se necesita marcar algunos cuadros clave (keyframes). Los cuadros entre keyframes son generados automáticamente, lo que se conoce como 'Interpolación'. La iluminación es un aspecto importante de la composición de la escena. Como en la realidad, la iluminación es un factor importante que contribuye al resultado estético y a la calidad visual del trabajo terminado. Por eso, puede ser un arte difícil de dominar. Los efectos de iluminación pueden contribuir en gran medida al humor y la respuesta emocional generada por la escena, algo que es bien conocido por fotógrafos y técnicos de iluminación teatral. Renderizado

e fin

lar niebla, polvo y otros efectos atmosféricos, y las cáusticas para simular

. general, de

farm (granja de rénder) para acelerar la producción de

A p rimp a

Se llama Render al proceso final de generar la imagen 2D o animación a partir de la escena creada. Esto puede ser comparado a tomar una foto o en el caso de la animación, a filmar una escena de la vida real. Generalmente se buscan imágenes de calidad fotorrealista, y para estse han desarrollado muchos métodos especiales. Las técnicas van desde las más sencillas, como el rénder de alambre (wireframe rendering), pasando por el rénder basado en polígonos, hasta as técnicas más modernas como el Scanline Rendering, el Raytracing, la radiosidad o el l

Mapeado de fotones. El software de rénder puede simular efectos cinematográficos como el lens flare, la profundidad de campo, o el motion blur (desenfoque de movimiento). Estos artefactos son, en realidad, un producto de las imperfecciones mecánicas de la fotografía física, pero como el ojo humano está acostumbrado a su presencia, la simulación de dichos efectos aportan un elemento de realismo ala escena. Se han desarrollado técnicas con el propósito de simular otros efectos de origen natural, como la interacción de la luz con la atmósfera o el humo. Ejemplos de estas técnicas incluyen los sistemas de partículas que pueden simular lluvia, humo o fuego, el muestreo

olumétrico para simuvel efecto de la luz al atravesar superficies refractantes. El proceso de rénder necesita una gran capacidad de cálculo, pues requiere simular gran cantidad de procesos físicos complejos. La capacidad de cálculo se ha incrementado rápidamente a través de los años, permitiendo un grado superior de realismo en los rénders

studios de cine que producen animaciones generadas por ordenador hacen uso, enElo que se conoce como render foto amgr as.

esa de haber muchos paquetes de modelado y animación 3D, solo nombraremos los más ort ntes, o aquellos que así lo requieran por su similitud o relación con el actual proyecto.

50

Page 52: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.7.1

Maya es la c lizer (en California), o ). En 1993 Wavefront adquirió TDI, y en 1995 Silicon Graphics Incorporated (SGI) adquirió Alias y Wavefront b Softimage ese mismo año) y las combinó en ade los 90, la ip inación de herramientaRenderMan para ulas, tales como urassic Park, The Abyss y Terminator 2: El juicio final. la compañía resultante de combinar Alias y Wavefront le llevó mas de dos años lanzar Maya.

aya es un paquete de modelado 3D, creado originalmente por Alias Systems Corporation, pero adq id d Entertainment. Autodesk adquirió el s stria cinematográfica Maya, es us s Maya Complete un precio similar a cualquier otro paquete 3D, pero solía ser considerablemente más caro. Maya Per a e para uso no comercial, totalmente gratuito. Las imágene Maya fue desarr . La ultima versió ada en agosto de 2006. La versión 6.5 fue la última versión qúltimos años. En fusionaría Maya mado Mayax. En subs antendrían separados : Maya para soluciones 3D de alt id aja fidelidad. La adquisición se co l .

Maya

ulminación de 3 líneas de software 3D: Wavefront's The Advanced Visua Th mson Digital Image Explore (en Francia) y Alias Power Animator (en Canadá

(de ido a la presión de Microsoft por adquirir un sola compañía, produciendo un único paquete de sus dos fuentes. A mediados

eline más popular en las películas de Hollywood era una combps: Alias Studio para el modelado, Softimage para la animación y Photorealistic

el rendering. Esta combinación se usó en numerosas pelícJA M

uir o actualmente por Autodesk bajo su división Media anoftware en Octubre de 2005 tras adquirir Alias. Normalmente se usa en la indu

y de la TV, así como en los videojuegos.

ado en la mayor parte de las películas de hoy día. Esta disponible en dos versione (el paquete menos potente) y Maya Unlimited. Maya Unlimited tiene hoy en día

son l Learning Edition (PLE) está disponibls generadas por esta versión contienen una marca de agua.

ollado por Alias y lanzado para Microsoft Windows, Linux, IRIX, y Mac OS Xn de Maya, versión 8.0, fue lanzue soportó IRIX, debido a la caída de popularidad de dicha plataforma en los la adquisición, la preocupación de los usuarios de Maya era si Autodesk con su software 3D Studio Max, creando alguna especie de híbrido llaecuentes entrevistas se clarificó que se m

a f elidad, y max para bmp etó en Enero de 2006

Figura 2-20. Captura del programa Maya 3D.

51

Page 53: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

La carac e Maya es su posibilidad de software de terceros, que puede hac utransforflexibili iga a grandes estudios que tienden

astante a escribir código personalizado para sus producciones usando el SDK proporcionado.

ambién cabe destacar de Maya su lenguaje de Script potente e independiente de la plataforma llam lenguajeentorno enguaje). Adicionalmente, las interacc pueden instantáneamente. Esto proporciona a los animadores el poder de añadir funcionalidad a Maya sin e á incl a Los fich etría, se guardan como secuencias de ope io ra May Atremedit s iores del software.

e

ología arbitraria. o La continuidad de las Subdivision Surfaces elimina muchos de los problemas

que pueden ocurrir en las uniones al animar usando NURBS. sion Surfaces a esqueletos en nivel grueso y los

ducirán suavemente a los niveles más finos.

Animación de camino (Path Animation). Este tipo de animación controla la posición y rotación de un objeto a lo largo de una curva. Se debe de asociar el

terística mas importante der q e cambien su apariencia estándar y, usando solo el núcleo de Maya, puede

marlo en un software altamente personalizable. Aparte de su intrínseca potencia y dad, esta característica en sí ha hecho que Maya atra

b T

ado Maya Embedded Language (MEL), similar a Tcl. No se proporciona únicamente como Script, sino también para personalizar la funcionalidad de su núcleo (muchos de los

s de Maya y herramientas están escritas en este liones de usuario están implementadas y guardadas como scripts MEL, que los usuariosver y arrastrar a una barra de herramientas donde pueden crear nuevas “macros”

ten r experiencia en programación C o C++ ni sus compiladores, aunque esta opción estuid con el SDK.

eros, que incluyen todos los datos de geomrac nes MEL, que pueden ser guardados opcionalmente como ficheros legibles (.ma, paa SCII), editables en cualquier fichero de texto externo al entorno Maya, y permite un

herramientas externas. También pueden ser endo nivel de flexibilidad al trabajar conado para permitir al fichero ser abierto por versiones anter

Características de modelado:

• NURBS. • Modelado Poligonal. • SubDivision Surface Modeling. Es una manera sencilla de crear objetos complicados

tales como manos humanas. Combina las mejores características de las nurbs con el modelado poligonal. Subdivision surfaces permite usar una sola superficie para modelar formas complejas. Una única superficie de subdivisión puede tener diferentes niveles ddetalles en sus diferentes regiones. Esto es, una región que tiene una forma compleja puede tener mas puntos de control para permitir un mayor detalle, mientras que una región simple o plana necesita muchos menos puntos de control. Ventajas de las Subdivision Surfaces :

o Permiten mayor nivel de control sobre formas que sobre polígonos. o Permiten usar geometría compleja únicamente en las regiones complejas del

modelo. o Permiten pliegues y top

o Se pueden enlazar Subdiviefectos se tra

Características de animación, configuración de personajes y deformadores:

• Animación basada en Keyframes (Fotogramas clave) o Animación no lineal. Tras animar un personaje con Keyframes o motion

Capture, se puede muestrear su animación en una secuencia editable llamadaclip de animación.

o

objeto a la curva. • Animación de captura de movimiento.

52

Page 54: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

o Animación con Esqueletos. Los esqueletos son estructuras articuladas jerarquizadas que permite posicionar y animar objetos vinculados. Un esqueleto proporciona un modelo deformable del mismo modo que el esqueleto humano

Cinemática Inversa

o Restricciones. Posibilitan añadir restricciones a la posición, orientación o

el proceso de animación.

o Character Sets. Es un nodo que contiene un conjunto de atributos que se pueden aplicar a isma animación.

Deformers. Son herramientas de alto nivel que se pueden usar para manipular

o rígido, o

tan crear efectos de animación e Maya ofrece gran número de

Cara e

• o

• cartoon usando modelos 3D. • Iluminacion: en el mundo real, cuando la luz brilla sobre una superficie, las partes de la

superficie que están encaradas hacia el foco de luz aparecen iluminadas, y las partes de la superficie contrarias aparecen oscuras.

• PaintEffects : componente de Maya usado para pintar trazos de pincel y efectos de 3D.

Ray renderer. • RenderMan for Maya : Renderer de Pixar para Maya.

lo hace con el cuerpo humano. Tal como en el cuerpo humano, la ubicación de las uniones (joints) y el númerode uniones a añadir al esqueleto determina como se moverá el modelo. Cuando se enlaza un modelo a un esqueleto, se le denomina Skinning. Existen varios métodos de animación:

Cinemática Directa

Full body IK Solver o Skinning. Es el proceso de configurar un personaje o modelo de manera que

pueda ser deformado por un esqueleto.

escalado de un objeto respecto de otros. Además, con restricciones se pueden imponer límites específicos a los objetos y automatizar

distintos objetos a los que quieras aplicar la mo

(al modelar) o llevar (al animar) los componentes de bajo nivel de cierta geometría. Los Deformers, son conocidos en otro tipo de paquetes como “Modifiers”.

Características sobre dinámica y simulación:

• Partículas: se pueden animar y visualizar movimiento de partículas con varias técnicas. • Campos: el movimiento de fuerzas naturales se puede simular con campos dinámicos. • Simulación de Cuerpo Blando: se puede recrear un objeto geométrico como un objeto

flexible llamado cuerpo blando. • Simulación de Cuerpo Rígido: un cuerpo rígido es una superficie poligonal o NURBS

convertida en una forma. A diferencia de las superficies convencionales, los cuerpos rígidos colisionan entre si en lugar de atravesarse durante una animación. Para animar un cuerpo rígido, se usan campos, claves, expresiones, restricciones de cuerpcolisiones con partículas.

• Efectos: Lo efectos en Maya son módulos que facilicomplejos tales como humo o fuego. Cada efecto dopciones y atributos para modificar los resultados.

rísticas de rendering : ct

Shading(sombreado): en Maya, la apariencia de una superficie está definida por como está sombreada. El sombreado de una superficie es una combinación del material básicde un objeto y las texturas aplicadas al mismo. En Maya, los materiales (también llamados Shaders), definen la sustancia del objeto. Algunos de los atributos más básicos de materiales incluyen color, transparencia ybrillo. Toon Shading: da una apariencia 2D o de animación

partículas en una superficie 2D o sobre geometría 3D en el entorno• Mental Ray : Mental

53

Page 55: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Características adicionales de la versión Unlimited :

• Maya Fluid : simulador de fluidos, efectos atmosféricos, pirotécnicos, de viscosidad y oceánicos.

bjetos

iona un

a

sor a

o

ns. Esta usado ampliamente por desarrolladores de pero puede ser también usado para producciones pre-renderizadas tales como

películas, efectos especiales y presentaciones arquitectónicas. Aparte de sus herramientas de modelado y animación, la ultima versión de 3ds Max también incluye shaders (tales como ambient occlusion y subsurface scattering), simulación dinámica, sistema de partículas, radiosidad, creación y render de normal map, iluminación global, un interfaz intuitivo y totalmente personalizable, su propio lenguaje de Script (MaxScript) y mucho más. También existen cantidad de plugins especializados que pueden ser comprados por separado, tales como Brazil r/s y FinalRender. El modelado de polígonos es mucho mas común en el diseño de juegos que en cualquier otra técnica de modelado, ya que el control muy especifico sobre polígonos de manera individual permite una máxima optimización. También es relativamente más rápido de calcular en tiempo real. Normalmente, el modelador comienza con una primitiva, y haciendo uso de herramientas como bevel, extrudo y corte de polígonos, añade detalles y refina el modelo.

• Maya Cloth: Simulación de ropa y telas, cualquier objeto textil, incluidas velas, forros, tiendas, cortinas y ropa de cama. Usado el la película Spiderman 2.

• Maya Fur: Simulación de piel animal, vello, lana y hierba en superficies NURBS, de subdivisión o modelos poligonales.

• Maya Hair: Simulación para cabello humano, cabellos totalmente dinámicos en opoligonales y NURBS.

• Maya Live: Combina la acción en vivo 2D con elementos 3D. Proporcsecuenciador 2D integrado y un solver de fotograma raíz interactivo. También permite reconstruir elementos de grabaciones en vivo como geometría 3D, además de generar lsalida a aplicaciones externas.

2.1.7.2 3D Studio Max

3D Studio Max, es un software de modelado 3D, desarrollando por Autodesk Media & Entertainment (formalmente conocido como Discreet y Kinetix). Fue desarrollado como sucede 3D Studio para DOS, pero para la plataforma Win32. Más tarde Kinetix se fusionó con l

ltima adquisición de Autodesk, Discreet Logic. Actualmente, en su 8ª versión en Junio deú2006. El 3D Studio original fue creado por Yost Group y publicado por Autodesk. 3D StudiMax fue también originalmente creado por Yost Group. Autodesk adquirió el producto en susegunda publicación e interiorizo su desarrollo completamente durante las dos siguientes publicaciones. 3ds Max es uno de los programas de animación 3D mas usados. Tiene gran capacidad de

odelado y una potente arquitectura de plugimvideojuegos,

54

Page 56: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 2-21. Captura del programa 3D Studio Max

3ds Max venia normalmente con distintos emisores de partículas. Como en su version 8, existen

emisores de partículas básicos, mostrando comportamientos específicos. Los emisores de partículas tradicionales son Spray, Nieve, Ventisca, PArray, PCloud, y Super Spray.

, desarrollado rtículas de MAX. A diferencia de la

s 3D, Particle Flow permite al una serie de eventos definidos por

almente creado por Havok. Reactor edad, y otras fuerzas. Como muchos plificado, pero puede ser

os vértices.

xisten varios renderers para generar imágenes, estos son:

l renderer por defecto. Es bastante robusto, soporta iluminación tracing.

6

Particle Flow es un sistema de partículas sofisticado, no lineal, basado en eventospor Oleg Bayborodin como uno de los siete emisores de pamayoria de sistemas de partículas disponibles en los paqueteusuario diseñar el comportamiento de la partícula basado enel usuario (Procedimientos), usando un GUI intuitivo. 3ds Max incluye un motor físico, llamado Reactor, originpuede simular cuerpos rigidos, cuerpos blandos, ropa, gravmotores físicos, Reactor utiliza un envoltorio convexo sim

ersonalizado para usar todos lp E

• Scanline rendering. Es eglobal, radiosidad y ray

• Mental ray. Es un renderer de calidad desarrollado por Metal Images. Mental Ray está integrado en las ultimas versiones de MAX y es una potente herramienta de render, conbucket rendering (similar al Satelling Rendering de Maya) que distribuye la carga del render entre distintas maquinas mas eficientemente. Mental Ray también viene con cantidad de herramientas que permiten gran número de efectos para ser creados con relativa facilidad.

• RenderMan. Herramienta de conexión a la pipeline Renderman para aquellos que necesiten integrar Max con renders de Renderman.

55

Page 57: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.1.7.3 LightWave 3D

LightWave 3D es un programa para el modelado 3D, render y animación. Aunque el progse originó en el Commodore Amiga, ha sido migrado para funcionar en Mac OS X, WindowSgi IRIX, y el motor de render también ha sido portado a Linux. Actualmente desarrolladocompletamente por NewTek.

rama s,

y su or ejemplo, no se usan iconos; en su lugar se usan funciones con su

titul e compuesto por dos partes, un entoranimaci y animan para el render. A diferencia de otros paq e xiste una aplicación

dependiente para el render, que puede ser ejecutada en múltiples máquinas.

e especial de Script llamado LScript. Este SDK está asado en el lenguaje C, y se puede crear casi cualquier cosa, desde un shader personalizado

lladores de todo el mundo.

lmente se conoce como LightWave 3D.

gent

LightWave ha sido durante tiempo bien conocido por su excelente capacidad para el renderinusual interfaz de usuario (p

o d scriptivo). Como muchos otros paquetes 3D, Lightwave estáno de modelado de objetos donde los modelos o las mallas se crean y un entorno de ón donde los modelos se preparan

uet s, estas dos partes son programas independientes. También ein Algunas funciones de LightWave son multi-hilo, lo cual significa que pueden usar hasta ocho procesadores al mismo tiempo en la misma maquina al renderizar una imagen. Los programadores pueden ampliar las características de LightWave usando un SDK que se incluye con el paquete, así como un lenguajbhasta distintos formatos de exportadores de escena. LightWave en si incluye docenas de plugins gratuitos y se pueden obtener muchos mas de distintos desarro En 1988, Allen Hastings creó un programa de render y animación llamado Videoscape, y su amigo Stuart Ferguson creó un programa de modelado 3D complementario llamado Aegis Modeler. Estos dos programas serían lo que actua Newtek planeaba incorporar Videoscape y Aegis en su paquete de edición de video, Video Toaster. Según Hastings, Newtek pretendía originalmente llamar a este nuevo software 3D Newtek 3D Animation System for the Amiga. Mas tarde, en Diciembre de 1989, a Hastings se le ocurrió el nombre LightWave 3D, inspitado por los paquetes 3D de aquel entonces: IntelliLight y Wavefront. En 1990, se lanzó el paquete Video Toaster, incorporando Lightwave 3D, listo para ejecutar en el Commodore Amiga.

Figura 2-22. Captura del programa LightWave 3D.

56

Page 58: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

LightWave 3D ha estado disponible como una aplicación independiente desde 1994, y la vers9.0 ahora corre bajo Max OS X y cualquier PC con Windows.

ion

de

l mantenimiento de NewTek y un grupo dirigido por el Peebler, entre los que figuraban desarrolladores como

. Por segunda vez en su historia NewTek sufrió un importante bandono de ingenieros y programadores. Tras meses de confusión, este grupo formó una nueva

o lanzaron su propio paquete 3D, Modo.

nados con premios Emmy desde 1993 y ganaron sus 10º y ue galardonado con un Emmy por la tecnología que

rcado abarca desde los aficionados (dado su bajo precio), gos, televisión y cine. La compañía recientemente

e 3D. como un editor se superficie basado en nodos

ptativa de Pixel (APS) que permite a la malla variar su complejidad dependiendo de los criterios definidos por el usuario, incluyendo la distancia a la cámara,

aximizando la eficiencia de render.

.1.7.4 SoftImage XSI

El contrInc, una3D, que se convirtió rápidamente en el programa de 3D más pSoftima nzaron a reescribir Softimage 3D para iEn 1998med o

2.1 5

ultigen Creator es una herramienta para generar modelos optimizados de objetos, terrenos, y entornos virtuales para usar en simulaciones de tiempo real y otro tipo de aplicaciones.

ases de datos 3D en tiempo real. No existen comandos ni lenguaje de Script; Tan solo una estructura de base de datos jerarquizada controlada

ructuras de los

DEM y NGA DTED a una uperficie de terreno, usando triangulación de Delaunay en una proyección plana de la

superficie. Las herramientas incluyen controles para múltiples LOD, criterio de concordancia de

LightWave ganó fama como el programa usado para crear efectos especiales para las series de ciencia ficcion Babylon 5 y Seaquest DSV; El programa también se utilizó en la producciónpelículas como Titanic, y las recientes Sin City y Star Wars. En 2001, se originó un problema entre evidepresidente de desarrollo 3D, BradAllen Hastings o Stuart Fergusonacompañía, Luxology. Fue entonces cuand NewTek y LightWave has sido galardo11º galardones en 2004. En 2003 NewTek ftuvo mayor impacto en televisión. Ahora en su novena versión, su mehasta el desarrollo de alto nivel como videojuelanzó su versión para 64 bit de LightWavEsta versión incluye nuevas características Subdivision Ada

m

2

incante más grande de Maya. En 1987, Softimage compañía situada en Montreal, escribió Softimage

po ular de ese período. En 1994, Microsoft compró ge Inc. y come

W ndows NT. El resultado se llamó Softimage XSI. Microsoft vendió Softimage a Avid. La versión a

iad s del 2003 era la 3.5.

Figura 2-23. Imagen generada por el programa SoftImage XSI.

.7. Multigen Creator

M

Creador está diseñado para construir b

completamente a través de un interfaz visual. Los usuarios controlan las estobjetos y los sub-objetos, texturas, luces, el orden de procesamiento de los datos, niveles de detalle (LOD), etc. Entre las opciones disponibles se encuentran Terrain, Power y Binary Separating Planes. La opción Terrain permite a los usuarios convertir datos USGSs

57

Page 59: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

bordes, etc. Tiene capacidad para detectar líneas de costa, cabos, y valles para una representación exacta y eficiente. Las herramientas de mapeado de texturas (Texture Mposibilitan a los usuarios a aplicar colores, texturas y materiales de manera automática e interactiva. El editor de texturas esta integrado con una Paleta personalizable. Durante el proceso de construcción de la base de datos se mantiene doble precisión interna. La opción Terrain es compatible con las herramientas Poblar y Dispersar (Poblate and Scatter), que permiten a los usuarios colocar modelos de manera aleatoria y automática sobre el terreno.

apping)

Cre r XF, 3Ds y OBJ. Para abrir ficheros SHP en Creador, el usu

Flight para escribir un conversor propio; • Usar Multigen Paradigm’s SiteBuilder3D para trabajar con los datos en ArcView, y

luego exportarlos a OpenFlight; re FME para convertir ficheros SHP a DFD.

odelado 3D, RoadPro se usa para construir carreteras en 3D, y Vega se

odelo 3D en tiempo real

hosting de Source Forge y el respaldo de la

r montar escenas, hacer pequeños ajustes, y ejecutar

, el desarrollo continúa enfocándose en hacer un completa de creación de contenidos con modelado,

tes herramientas de este tipo en el mundo.

ionado bastante desde su nacimiento, desde un interfaz rígido tual, generado dinámicamente casi en su totalidad.

ada paso del diseño fue hecho con la ayuda de Ricardo Rodríguez y la contribución de gente

ado puede importar ficheros Dario tiene tres opciones: • Usar la API Open

• Usar el softwa Creator incluye FlightViewer, un plug-in para previsualizacion. FlightViewer posibilita el modode vuelo en tiempo real o modo de rotación, visualiza modelos con texturas, materiales, luces ysombras, carga de puntos de vista guardados en Creador ,vista en diferentes modos (wireframe, solido y puntos), actualización constante de la estadísticas de render, tales como triángulos por segundo o fotogramas por segundo (FPS). Los productos Multigen-Paradigm están siendo usados para proporcionar una base de datos 3Den tiempo real en un proyecto de una autopista de California.

reador se usa para mCusa para realizar aplicaciones de visualización 3D interactivas. Creador también se ha usado para desarrollar un modelo 3D del desarrollo de proyecto de línea de costa en Vallejo, CA. El modelo incluía tiendas, hoteles, terreno y calles.

ultiGen-Paradigm’s Urban Simulation Services Group entregó un mMpara el Centennial Center a la ciudad de Las Vegas. La base de datos 3D comprendía 160 acres y fue hecha a partir de planos, datos de elevaciones, imágenes digitales y datos de sistemas de información geográfica (GIS). Sitebuilder 3D se uso para convertir mapas digitales 3D yfotografías aéreas en elementos 3D como carreteras, caminos, edificios y campos. Creador se uso para renders de edificios y mejorar detalles. Por ultimo, Vega se uso para proporcionar un interfaz personalizado para visualizar e interactuar con el modelo.

2.1.7.6 OSGEdit

OSGEdit comenzó en 2002, apoyado por el comunidad OpenSceneGraph (OSG). De entre sus características, debería permitiprocesos típicos de un grafo de escena. Aunque la idea evolucionó en cierto modocompositor de escenas, no una herramientaanimación, etc., puesto que ya existen bastan El diseño de OSGEdit ha evoluc

echo completamente a mano hasta el achCrepartida por todo el mundo, como es usual en este tipo de proyectos de código abierto.

58

Page 60: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

La generación del GUI está automatizada, ya que esta es la única manera de soportar cualquier característica de OSG en un tiempo razonable de tiempo. No obstante, esta característica del interfaz se ve penalizada con un incremento de la inestabilidad del programa.

pción XML proporcionando eta-datos sobre las clases OSG. Los meta-datos separan los detalles OSG del interfaz de

das con la pción undo/redo del programa.

escripción XML. Esto reduce el coste de

n32 utilizando la brería GTK+.

se representa mediante un árbol donde se pueden seleccionar los nodos para cualquier operación. Este árbol es realmente un grafo, un mismo nodo puede colgar de distintas ramas, aunque realmente represente un nodo compartido, no una copia.

de propiedades integrado en la ventana (la mayoría

o guardar en todos los

l Valve Hammer Editor era antes conocido con el nombre de Worldcraft. os sus mods.

faz

La generación automática de la GUI se realiza utilizando una descrimusuario, proporcionando un mecanismo genérico para conocer los atributos de cada clase, y las características de dichos atributos. El interfaz de usuario se genera a partir de estos meta-datos, así como las acciones que actualizan el grafo de escena, relacionao Desde la versión 0.6.0, tanto la barra de menú como la barra de herramientas se generan automáticamente desde una ddesarrollo al añadir nuevas herramientas al GUI, ya que no necesitar escribir, compilar y depurar código fuente. Otra de las novedades de esta ultima versión es la implementación tanto para entorno X como para Wili

Características de OSGEdit :

• El grafo de escena

Figura 2-24. Captura del programa OSGEdit.

• Cada tipo de nodo tiene un dialogo soportadas).

• Se pueden manipular las transformaciones visualmente, hay herramientas para mover, escalar, y rotar nodos de transformación visualmente con el ratón.

• Todas las operaciones excepto new/open/save y zoom se pueden deshacer y rehacer sin límite.

/LOD unicamente. • Se pueden crear nodos tipo Group/Transform/Switch• Se pueden abrir todos los formatos que soporta OSG así com

formatos que soporta OSG. • Se pueden unir ficheros, añadiéndolos como nodos hijo. • Se pueden copiar, cortar y pegar nodos.

2.1.7.7 Valve Hammer Editor

EValve Hammer es el editor oficial de la empresa Valve para el juego Half-Life y todEs un editor gratuito, se puede descargar de cualquier página oficial. Con el se pueden crear mapas para Half-Life, Counter-Strike, etc... su funcionamiento es sencillo, tiene una interintuitiva, y su puesta en funcionamiento es sencilla. Ahora mismo la versión oficial es la 4.0. Esta en inglés, aunque hay una versión no-oficial en español.

59

Page 61: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Actualmente la versión oficial de este software de la desarrolladora Valve es la 4.0. Estaya si es de "pago", se adquiere cuando se compra una copia original de los siguientesvideojuegos: Half-Life 2, Counter-Strike Source, Day of Defeat Source. Cuando adquirimos uno o varios de estos productos, estamos obligados a registrarlos en la plataforma Online Steam de la propia compañía

versión

desarrolladora del Half-Life, Valve. Una vez registrada nuestra copia de oftware en dicha plataforma se nos dara la posibilidad para acceder al Kit de desarrollo de

t Kit) smods para el Source Engine. La herramienta se llama Source SDK (Software Developmendonde dispondremos de las siguientes herramientas:

• Valve Hammer Editor 4.0 • HL2 Model Viewer • HL2 Face Poser

2.1.7.8 UnrealED

nreadED, es el software editor de niveles usado para crear niveleUde

s para Unreal, otros juegos

jue sed r hic olos jue Ademáco n Unrea , con la fro lop n

de UnrealED, la primera en aparecer fue la versión 1.0, la cual ya ientas con sus 4 vistas. Esta versión era extremadamente

e bEn ay un inopcionsignifieditor inestab1.0. Junto cUnreaanteriores. Mantenía los colores de su int aeditor estáticcombiúnico entre tla vers

UnrealED opera con el concepto de brush (pincel). Los brushes pueden ser formas primitivas (tales como cubos, esferas y conoces), formas predefinidas (como escaleras), o formas

Unreal series , y juegos basados en el motor Unreal, como puede ser Deus Ex. Este tipo de go utilizan su propia versión del mismo programa. Todos los juegos Unreal en PC tenían en

ito de niveles incluido de manera gratuita, y algunos otros juegos que usaban su motor ier n lo mismo con una versión mas especifica del mismo. Esto extendió la longevidad de

gos. Los diseñadores amateur podían ahora crear contenidos adicionales para el juego.s, el lenguaje Script llamado UnrealScript permitía a los editores personalizar el

nte ido del juego.

lED tiene un interfaz de usuario personalizable, pero lo mas común son las cuatro vistasvista superior en la parte superior izquierda, y en sentido de las agujas del reloj la vista

nta , la vista lateral, y una vista en perspectiva. Tiene una fila de botones con distintas cio es de salvado, guardado, así como para funciones de editado.

Han existido varias versiones

isualizaba la barra de herramvin sta le, particularmente al reconstruir mapas.

la ctualización a la versión 2.0, se mejoró su aspecto visual con unos botones más coloridos terfaz más atractivo. Se añadieron nuevas herramientas y características (tales como es de búsqueda, y un nuevo editor de formas 2D), y experimentó una actualización cante de escalabilidad, y aunque el continuaba con sus extraña ilidad, no lo era tanto como la versión

on Unreal Tournament 2003 estaba lED 3.0, mucho mas estable q los

erf z, y el aspecto de su versión 2.0. Al se añadió un navegador de mallas as para soportar mallas estáticas, y nado con varios navegadores en un navegador con pestañas para alternar exturas, mallas, actores, etc… Esta es ión actual de UnrealED.

Figura 2-25. Captura de UnrealED

60

Page 62: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

personalizadas (como prismas y otros poliedros). Usaneometry), se pueden crear objetos y habitaciones com

do operaciones CSG (Constructive Solid plejas añadiendo, sustrayendo e

ivel se construye con una mezcla de

n algún software como Maya o os

s y

lgunos diseñadores de edificios, para poder proporcionar una visita en tiempo real de sus omenzado a construir modelos usando

público visitar un edificio antes de su

Gintersectando brushes entre si. Los brushes aditivos pueden ser sólidos, semisólidos o no-sólidos. UnrealED trata el mundo como una masa gigante. Para crear espacio, los brushes son sustraídos de la masa, de modo que se crea un espacio hueco por donde pasar. Inversamente, la adición de

asa crea espacio sólido dentro del espacio hueco. Un nmsuma y resta de brushes. Estos brushes se usan para compilar un nivel en un árbol BSP (Binary Space Partitioning) para render y detección de colisiones. Desafortunadamente, a medida que los niveles se complican, más propensos a error son los BSP, dando como resultado errores de visualización y de colisiones. De aquí el uso de Mallas Estáticas introducido en la versión 2.0 del motor.

as mallas estáticas son geometría pre-renderizada, creada coL3D Studio Max, que puede ser importada y posicionada dentro de los niveles. Aunque lniveles se construyen con brushes, las mallas estaticas se pueden usar para crear edificioformas complejas que los brushes tienen difícil para emular. Puesto que las mallas estáticas solose cargan en memoria una vez, aunque sean usadas múltiples veces en la escena, son una mejorforma de usar recursos. Acreaciones, con gravedad y detección de colisiones, han c

nreadED, y asi poner en practica sus ideas. Permitir al Uconstrucción puede desarrollar un mejor resultado previo a la construcción del mismo. El problema es la conversión de medidas desde programas de diseño tales como Autocad y 3D Studio Max a UnrealED.

2.2 Arquitectura de Plugins. Un plugin (o plug-in) es un programa que interactúa con la aplicación principal (un navegadoun programa de correo, por ejemplo), para proporcionar una función especifica. Por ejemplo

• Leer o editar

r o :

tipos específicos de fichero (por ejemplo, ficheros multimedia).

n

de

• Encriptar o desencriptar emails (por ejemplo, PGP). • Filtrar imágenes en programas de tratamiento de imágenes.

La aplicación principal proporciona los servicios que permite a los plugins usar, incluyendo lamanera en que los plugins se registran a sí mismos en la aplicación principal, y el protocolo por el cual los datos se intercambian con el plugin. Los plugins son dependientes de estos servicios que proporciona la aplicación principal, y no suelen funcionar por sí solos. En cambio, la aplicación principal es independiente de los plugins, haciendo posible que los plugins se añadao se actualicen dinámicamente sin que sea necesario hacer cambios en la aplicación principal. Los plugins sin ligeramente diferentes de las extensiones, que modifican o añaden funcionalidad. La principal diferencia es que los plugins generalmente dependen del interfaz usuario de la aplicación principal, y tienen bien definidos los límites para su conjunto de acciones. Las extensiones generalmente tienen menos restricciones en sus acciones, y pueden proporcionar sus propias interfaces. Algunas veces se usan para decrementar el tamaño de la aplicación principal, y ofrecer funciones adicionales.

61

Page 63: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Quizá el primer software en incluir la función de plugin fue HyperCard y QuarkXPress (Macintosh), ambos lanzados en 1987. En 1988, Silicon Beach Software incluyó la funcionalidad de plugin en Digital Darkroom y SuperPaint. Por aquellos tiempos, los plugins

a

o de vida de las aplicaciones obsoletas. Adobe Photoshop y el PI de plugins After Effects se han convertido en un estándar y se ha adoptado hasta cierto unto por aplicaciones de su competencia.

• Hace posible el personalizar la aplicación de maneras no pensadas por el autor, o que al a intención de hacer.

• Da la posibilidad de difundir la responsabilidad. Mucha gente trabaja en proyectos de

de n,

• icada por la aplicación padre (la p plementar una clase virtual pura, con la x una biblioteca compartida cargable en tiempo

evos formatos de

to

siquiera existe. plugins brinda nueva funcionalidad y acciones para la barra de menús

ramientas.

ón de eb en un navegador Web.

nueva funcionalidad puede ser añadida por

eran implementados como librerías compartidas, que debían instalarse en una ruta indicada en laplicación principal. Las APIs de código abierto suelen proporcionar un interfaz estándar, permitiendo a otros desarrolladores crear plugins que interactúen con la aplicación principal. Un API estable permite que los plugins de otros desarrolladores funcionen perfectamente aunque la versión original cambie, y prolonga el ciclAp Los Plugins le dan a una aplicación la capacidad de agregar funcionalidades nuevas en tiempo de ejecución. De entre sus ventajas podemos destacar:

menos no tenía l

software abierto ya que ser autor de una pieza de código les brinda cierta satisfacción personal. Utilizando plugins, una persona puede desarrollar un plugin, y reclamar su autoría.

• Es posible compartir código entre aplicaciones sin mucho que ver entre ellas si estas comparten una infraestructura de plugins entre si. Un ejemplo serían los visores imágenes. Existen muchos visores. Teniendo una infraestructura de plugins en comúsería posible desarrollar plugins que funcionen en cada uno de estos visores.

• Finalmente, hace posible que sólo cierta funcionalidad este disponible si alguna librería de o aplicación de terceros no está disponible en el sistema.

Existen dos tipos de plugins:

El primer tipo de plugins implementa una interfaz especifa licación principal). Esto es similar a ime cepción de que la clase se encuentra ende ejecución. Este tipo de plugins también se les llama módulos cargables. Ejemplos de módulos cargables son módulos de soporte para nuimágenes, destacadores de sintaxis, y módulos para importar y/o exportar datos a diferentes formatos. Las ventajas de este tipo de plugins es que terceros fabricantes pueden añadir nuevos formatos a la aplicación. Ej: Un editor para programadores puede destacar código escrien lenguaje VDM-SL, aún cuando el autor del editor no tiene idea que ese lenguaje

• El segundo tipo de y la barra de herEjemplos para este tipo de plugins sería la clásica opción para exportar una galería HTML desde un visor de imágenes (aún cuando este no tenía esta funcionalidad anteriormente), verificación y corrección de ortografía en un editor, validacipáginas WLa ventaja de este tipo de plugins es que terceros, con las consecuencias descritas anteriormente.

62

Page 64: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.3 Bibliotecas de enlace dinámico DLL es el acrónimo de Dynamic Linking Library (Bibliotecas de Enlace Dinámico), térmon el que se refiere

ino a los archivos con código ejecutable que se cargan bajo demanda del

ivos n

e requerían

e

cprograma por parte del sistema operativo. Esta denominación se refiere a los sistemas operatWindows siendo la extensión con la que se identifican los ficheros, aunque el concepto existe eprácticamente todos los sistemas operativos modernos. El propósito inicial de las DLL era ahorrar tanto espacio de disco como memoria qulas aplicaciones, guardándolas en el disco duro. En una librería convencional no compartida, los ragmentos de código se añaden tal cual al programa que la necesita. Si dos programas llaman a f

la misma rutina, ese código estará duplicado. Por el contrario, cualquier código compartido por muchas aplicaciones se puede separar en una DLL que exista en un único fichero en disco y una única instancia en memoria. El amplio uso de las DLLs ha permitido a las últimas versiones dWindows funcionar bajo condiciones ajustadas de memoria. Las DLLs proporcionan los beneficios típicos de las librerías compartidas, tales como modularidad. La modularidad permite hacer cambios al código y los datos de una DLL compartida por distintas aplicaciones sin tener q modificar ninguna de estas aplicaciones. Esta forma básica de modularidad permite aplicar parches y service packs a grandes aplicaciones, tales como Microsoft Office, Microsoft Visual Studio, incluso el propio Microsoft Windows. Creación de una biblioteca de enlace dinamico A menudo es más sencillo crear una biblioteca de enlace dinámico que crear una aplicación. La razón es que habitualmente una DLL consta de un conjunto de funciones autónomas que pueden ser utilizadas por cualquier aplicación. Lo normal es que en las DLLs no haya código que se encargue del procesamiento de bucles de mensaje o de la creación de ventanas. Una biblioteca de enlace dinámico es simplemente un conjunto de módulos de código fuente, cada uno de los cuales contiene un conjunto de funciones. Estas funciones se escriben con la esperanza de que les llame una aplicación (archivo EXE) u otra DLL. Después de compilar todos los archivos de código fuente, se enlazan igual que el archivo EXE de una aplicación. Sin embargo, para una DLL e r s debe especificar al enlazador la opción /DLL. Esta opción provoca que el enlazadogenere una información ligeramente diferente en la imagen del archivo DLL resultante, de manera que el cargador del sistema operativo reconozca que la imagen del archivo es una DLL y no n

u a aplicación.

Para que una aplicación (u otra DLL) llame a las funciones contenidas en una DLL, primero se debe proyectar la imagen del archivo DLL en el espacio de direcciones del proceso llamante. Esto se puede llevar a cabo de dos maneras: con enlazado implícito en tiempo de carga o con enlazado explícito en tiempo de ejecución. Una vez se ha proyectado la imagen de un archivo DLL en el espacio de direcciones del proceso llamante e ejecutan en el , las funciones de la DLL están disponibles para todos los hilos que sproceso. De hecho, la DLL pierde casi toda su identidad como DLL: para todos los hilos del proceso, el código y los datos de la DLL simplemente parecen código y datos adicionales que están en el espacio de direcciones del proceso. Cuando un hilo llama a cualquier función de la DLL, esta función toma los parámetros que le han pasado en la pila del hilo y también utiliza esta pila para guardar las variables locales que pudiera necesitar. Además, el hilo o proceso llamante posee todos los objetos creados por el código de las funciones de la DLL: una DLL nunca posee da na en Win32. Por ejemplo u e reserva en el espacio , si na función de una DLL llama a VirtualAlloc, la región sde direccion mina la proyección de la es del proceso del hilo llamante. Si más adelante se eliDLL del esp o el espacio de direcciones permanece aci de direcciones del proceso, la región d

63

Page 65: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

reservada po e a DLL ha rqu el sistema no es consciente del hecho de que una función de lreservado la región. La región reservada la posee el proceso y sólo será liberada si un hilo llama a la función VirtualFree o si termina el proceso. Como ya sabemos, las variables globales y estáticas de un archivo EXE no se comparten entre los múltiples ejemplares en ejecución del mismo EXE. Cuando un proceso proyecta una imagen de archivo DLL en su espacio de direcciones, el sistema crea también ejemplares de las variables globales y estáticas. Existe una técnica que permite que una DLL comparta sus variables globales y estáticas entre múltiples proyecciones de la DLL. Sin embargo, esta técnica no es la que se aplica por defecto en Win32 (se deben realizar algunas acciones adicionales para conseguir este comportamiento). Proyectar una DLL en el espacio de direcciones de un proceso Para que un hilo llame a una función de una DLL, se debe proyectar la imagen del archivo DLL en el espacio de direcciones del proceso del hilo llamante. Se puede conseguir esto de dos maneras: enlazando implícitamente las funciones de la DLL y cargando explícitamente la DLL.

Enlazado implícito El enlazado implícito es el método más habitual de proyectar la imagen de un archivo DLL en el espacio de direcciones del proceso. Cuando se enlaza una aplicación, se debe especificar un conjunto de archivos LIB al enlazador. Cada archivo LIB contiene la lista de las funciones a las que el archivo de DLL permite que llame una aplicación (u otra DLL). Cuando el enlazador ve que la aplicación llama a una función incluida en el archivo LIB de una DLL, incrusta información en la imagen del archivo EXE resultante que indica el nombre de la DLL que contiene las funciones que requiere el EXE Cuando el sistema operativo carga un archivo EXE, el sistema examina el contenido de la imagen del archivo EXE para ver qué DLLs deben estar cargadas para que la aplicación se ejecute. Entonces, el sistema intenta proyectar las imágenes de archivo DLL requeridas en el espacio de direcciones del proceso. Cuando busca el archivo DLL, el sistema examina los siguientes directorios:

1. El directorio que contiene la imagen del archivo EXE. 2. El directorio actual del proceso. 3. El directorio de sistema de Windows. 4. El directorio de Windows. 5. Los directorios enumerados en la variable de entorno PATH.

Si no se puede encontrar el archivo DLL, el sistema operativo muestra un cuadro de mensaje y termina inmediatamente el proceso completo. Cuando se utiliza este método, no se elimina la proyección de todas las imágenes de archivo DLL proyectadas en el espacio de direcciones del proceso hasta que se termina el proceso. Enlazado explícito La imagen de un archivo DLL se puede proyectar explícitamente en el espacio de direcciones de un proceso cuando uno de los hilos del proceso llama a la función LoadLibra-ry o LoadLibraryEx: HINSTANCE LoadLibrary(LPCTSTR IpszLibFile); HINSTANCE LoadLibraryEx(LPCTSTR IpszLibFile, HANDLE hFile, DWORD dwFlags);

Estas dos funciones localizan una imagen de archivo en el sistema del usuario (utilizando el orden de búsqueda mencionado anteriormente) e intentan proyectar la imagen del archivo DLL

64

Page 66: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

en el espacio de direcciones del proceso llamante. El valor HINSTANCE que devuelven estas funciones identifica la dirección de memoria virtual en la que se proyectó la imagen de archivo. Si no se puede proyectar la DLL en el espacio de direcciones del proceso, las funciones devuelven NULL. Podemos observar que la función LoadLibraryEx tiene dos parámetros adicionales: hFile y dwFlags. El parámetro hFile está reservado para una utilización futura y por el momento debe ser NULL. Para el parámetro dwFlags, se debe especificar un 0 o una combinación de DONT_RESOLVE_DLL_REFERENCES, LOAD_LIBRARY_AS_DATAFILE y LOAD_WITH_ALTERED_SEARCH_PATH. Estos flags se tratan brevemente a continuación. DONT_RESOLVE_DLL_REFERENCES: Al especificar este flag se le indica al sistema que proyecte la DLL en el espacio de direcciones del proceso llamante. Normalmente, cuando se proyecta una DLL en el espacio de direcciones de un proceso, el sistema llama a una función especial de la DLL, que se llama habitualmente DllMain, y que se utiliza para inicializar la DLL. Si se especifica este flag, el sistema simplemente proyecta la imagen de archivo sin llamar a la función DllMain. Además, una DLL podría importar las funciones contenidas en otra DLL. Cuando el sistema proyecta una DLL en el espacio de direcciones del proceso, el sistema también comprueba si la DLL requiere otras DLLs y también las carga automáticamente. Cuando se especifica el flag DONT_RESOLVE_DLL_REFERENCES, el sistema no carga automáticamente ninguna de estas DLLs adicionales en el espacio de direcciones del proceso. LOAD_LIBRARY_AS_DATAFILE: Este flag es muy similar al anterior; es decir, el sistema simplemente proyecta la DLL en el espacio de direcciones del proceso como si fuera un archivo de datos. El sistema no pierde más tiempo en prepararse para ejecutar el código del archivo. Por ejemplo, cuando una DLL se proyecta en el espacio de direcciones del proceso, el sistema examina la información de la DLL para determinar qué atributos de protección de página se deberían asignar a las diferentes secciones del archivo. Cuando no se especifica este flag, el sistema establece los atributos de protección de página como si fuese a ejecutar el código de ese archivo. Este flag es útil por varias razones:

• Si tenemos una DLL que contiene sólo recursos y ninguna función, es preferible especificar este flag. Al hacerlo, se proyecta la imagen de archivo de la DLL en el espacio de direcciones del proceso y se puede utilizar entonces el valor HINSTANCE que devuelve LoadLibraryEx en las llamadas a las funciones que cargan los recursos.

• También se puede utilizar este flag si se desean utilizar recursos que están contenidos en un archivo EXE. Normalmente, al cargar un archivo EXE se inicia un nuevo proceso, pero también se puede utilizar la función LoadLibraryEx para proyectar una imagen de archivo EXE en un espacio de direcciones de proceso. De nuevo, una vez se ha asignado el valor HINSTANCE del EXE, se puede acceder a los recursos contenidos en él. Dado que un archivo EXE no tiene la función DllMain, hay que especificar este flag cuando se llama a LoadLibraryEx para que cargue un archivo EXE.

LOAD_WITH_ALTERED_SEARCH_PATH: Al especificar este flag se cambia el orden de búsqueda que utiliza LoadLibraryEx para localizar el archivo de DLL especificado. Normalmente, LoadLibraryEx busca los archivos en el orden mencionado anteriormente. Sin embargo, si se especifica el este flag, LoadLibraryEx busca el archivo utilizando el siguiente orden:

1. El directorio especificado en el parámetro lpszLibFile. 2. El directorio actual del proceso. 3. El directorio de sistema de Windows. 4. El directorio de Windows.

65

Page 67: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5. Los directorios enumerados en la variable de entorno PATH. Cuando se carga explícitamente una DLL, la imagen de archivo se puede eliminar explícitamente la proyección del espacio de direcciones del proceso en cualquier momento llamando a la función FreeLibrary: BOOL FreeLibrary(HINSTANCE hinstDll);

Cuando se llama a FreeLibrary, se le debe pasar el valor HINSTANCE que identifica a la DLL que se desea liberar. Este valor es el que devolvió una llamada anterior a LoadLibrary o LoadLibraryEx. En realidad, las funciones LoadLibrary y LoadLibraryEx incrementan un contador de utilización asociado a la biblioteca especificada, y la función FreeLibrary decrementa dicho contador. Por ejemplo, la primera vez que se llama a LoadLibrary para que cargue una DLL, el sistema proyecta la imagen del archivo DLL en el espacio de direcciones del proceso llamante y asocia a la DLL un contador de utilización con un valor 1. Si un hilo del mismo proceso llama más tarde a LoadLibrary para que cargue la misma imagen del archivo DLL, el sistema no la proyecta por segunda vez en el espacio de direcciones del proceso. En su lugar, el sistema simplemente incrementa el contador de utilización asociado a la DLL. Para que se elimine la proyección de la imagen del archivo DLL del espacio de direcciones del proceso, los hilos del proceso deben llamar a FreeLibrary dos veces (la primera llamada a FreeLibrary simplemente decrementa el contador de utilización de la DLL a 1, y la segunda llamada lo decrementa a 0). Cuando el sistema ve que el contador de utilización de una DLL ha llegado a O, elimina la proyección de la imagen del archivo DLL del espacio de direcciones del proceso. Después de eliminar la proyección de la imagen de archivo, si un hilo intenta llamar a una función de la DLL, provocará una violación de acceso porque el código de la dirección especificada ya no está proyectado en el espacio de direcciones del proceso. El sistema mantiene un contador de utilización de una DLL para cada proceso. Es decir, si un hilo de un Proceso A realiza la llamada HINSTANCE hinstDll = LoadLibrary("MiLib.DLL");

y después un hilo del Proceso B realiza la misma llamada, se proyecta MILIB.DLL en los espacios de direcciones de ambos procesos (el contador de utilización de la DLL en el Proceso A y en el Proceso B es 1 en ambos). Si un hilo del proceso B llama más tarde a FreeLibrary(hinstDll);

el contador de utilización de la DLL con respecto al Proceso B se hace 0, y se elimina la proyección de la DLL del espacio de direcciones del Proceso B. Sin embargo, la proyección de la DLL en el espacio de direcciones del Proceso A no se ve afectada, y el contador de utilización de la DLL asociado al Proceso A sigue valiendo 1. Un hilo puede llamar a la función GetModuleHandle HINSTANCE GetModuleHandle(LPCTSTR IpszModuleName);

para determinar si una DLL está proyectada en el espacio de direcciones de su proceso. Por ejemplo, el código siguiente carga MILIB.DLL sólo si no está ya proyectada en el espacio de direcciones del proceso: HINSTANCE hinstDll; hinstDll = GetModuleHandle("MiLib"); // se asume la extensión DLL if (hinstDll == NULL) { hinstDll = LoadLibrary("MiLib"); // se asume la extensión DLL }

66

Page 68: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

También se puede determinar el nombre de trayecto completo de una DLL (o EXE) si todo lo que se tiene es el valor HINSTANCE de la DLL. Para ello, se utiliza la función GetModuleFileName: DWORD GetModuleFileName(HINSTANCE hinstModule, LPTSTR IpszPath, DWORD cchPath);

El primer parámetro es el HINSTANCE de la DLL (o EXE). El segundo, IpszPath, es la dirección del búfer en el que la función pondrá el nombre de trayecto completo de la imagen de archivo. El tercer y último parámetro, cchPath, especifica el tamaño del búfer en caracteres. Hay otra función de Win32 que se puede utilizar para decrementar el contador de utilización de una DLL: VOID FreeLibraryAndExitThread (HINSTANCE hinstDll, DWORD dwExitCode);

Supongamos que escribimos una DLL que crea un hilo cuando se proyecta por primera vez en el espacio de direcciones de un proceso. Cuando el hilo termina de realizar su trabajo, puede eliminar la proyección de la DLL del espacio de direcciones del proceso. Para que el hilo elimine la proyección de la DLL debe llamar a FreeLibrary y después inmediatamente a ExitThread. Pero si el hilo llama a FreeLibrary y a ExitThread individualmente, se produce un error muy serio. El problema, claro está, es que la llamada a FreeLibrary elimina inmediatamente la proyección de la DLL del espacio de direcciones del proceso. En el mo-mentó en que vuelve la llamada a FreeLibrary, el código que contiene la llamada a ExitThread ya no está disponible y el hilo no intentará ejecutar nada. Esto provocará que se lance una violación de acceso y que ¡termine el proceso completo! Sin embargo, si el hilo llama a FreeLibraryAndExitThread, esta función llama a FreeLibrary, provocando que se elimina la proyección de la DLL inmediatamente. La siguiente instrucción que se ejecuta se encuentra en KERNEL32.DLL, no en la DLL que se acaba de eliminar. Esto significa que el hilo puede continuar ejecutándose y que puede llamar a ExitThread. ExitThread provocará que el hilo termine y no volverá. La funcion de entrada/salida de la DLL Una DLL de Win32 puede, opcionalmente, tener una sola función de entrada/salida. El sistema llama a esta función en varias ocasiones que vere os más adelante. Estas llamadas son minformativ ación y as y habitualmente son utilizadas por una DLL para realizar tareas de inicializliberación para cada proceso o cada hilo. Si la DLL no necesita estas notificaciones, no es necesario implementar esta función en el código fuente de la DLL. Por ejemplo, si creamos una DLL que sólo contiene recursos, no es necesario implementar esta función. Si existe esta función de entrada/salida, debe ser como ésta: BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID flmpLoad) { switch (fdwReason) { case DLL_PROCESS_ATTACH: // La DLL se proyecta en el espacio de // direcciones del proceso break; case DLL_THREAD_ATTACH: // Se crea un hilo break; case DLL_THREAD_DETACH: // Un hilo termina sin problemas break; case DLL_PROCESS_DETTACH:

67

Page 69: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

// Se elimina la proyección de la DLL del // espacio de direcciones del proceso. break; } return(TRUE); // Sólo se utiliza para DLL_PROCESS_ATTACH }

El sistema operativo llama a esta función de entrada/salida en varios momentos. Cuando se llama a esta función, el parámetro hinstDll contiene el descriptor del ejemplar de la DLL. Como el parámetro hinstExe para WinMain, este valor identifica la dirección de memoria virtual en la que se proyectó la imagen del archivo DLL en el espacio de direcciones del proceso. Habitualmente, se guardará este parámetro en una variable global para poder utilizarlo en las llamadas que cargan recursos, como DialogBox y LoadString. El último parámetro, flmpLoad, es un valor distinto de cero si la DLL se carga implícitamente o cero si se carga explícitamente. El parámetro fdwReason indica la razón por la que el sistema llama a la función. Este parámetro puede ser uno de estos cuatro valores: DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, DLL_THREAD_ATTACH o DLL_THREAD_DETACH. DLL_PROCESS_ATTACH Cuando se proyecta por primera vez una DLL en el espacio de direcciones del proceso, el sistema llama a la función DllMain de la DLL, pasando el valor DLL_PROCESS_ATTACH como parámetro fdwReason. Esto sólo sucede cuando se proyecta por primera vez la imagen del archivo DLL. Si un hilo llama después a LoadLibrary o LoadLibraryEx para una DLL que ya está proyectada en el espacio de direcciones del proceso, el sistema operativo simplemente incrementa el contador de utilización de la DLL; no llama de nuevo a la función DllMain de la DLL con el valor DLL_PROCESS_ATTACH. Cuando procesa DLL_PROCESS_ATTACH, una DLL debería realizar todas las inicializaciones relativas al proceso que necesiten las funciones contenidas en la DLL. Por ejemplo, la DLL podría contener funciones que tengan que utilizar su propio Heap (creado en el espacio de direcciones del proceso). La función DllMain de la DLL podría crear este Heapllamando a HeapCreate durante el procesamiento de la notificación DLL_PROCESS_ATTACH. El descriptor del Heap creado se podría guardar en una variable global a la que tuviesen acceso las funciones de la DLL. Cuando DllMain está procesando la notificación DLL_PROCESS_ATTACH, el valor de retorno de DllMain indica si la inicialización de la DLL ha tenido éxito. Por ejemplo, si la llamada a HeapCreate ha tenido éxito, DllMain debería devolver TRUE. Si no se ha podido crear el Heap, devuelve FALSE. Para cualquiera de los otros valores de fdwReason (DLL_PROCESS_DETACH, DLL_THREAD_ATTACH y DLL_THREAD_DETACH) el sistema ignora el valor que devuelve DllMain. Obviamente, debe haber algún hilo en el sistema que sea el responsable de ejecutar el código de la función DllMain. Cuando se crea un nuevo proceso, el sistema proyecta el espacio de direcciones del proceso y después proyecta la imagen del archivo EXE y todas las imágenes de archivo DLL requeridas en el espacio de direcciones del proceso. A continuación, el sistema crea el hilo primario del proceso y utiliza este hilo para llamar a cada una de las funciones DllMain de DLL con un valor DLL_PROCESS_ATTACH. Después de que todas las DLLs proyectadas hayan respondido a esta notificación, el sistema provoca que el hilo primario del proceso comience a ejecutar el código de inicio en tiempo de ejecución de C del EXE, seguido de la función WinMain del EXE. Si alguna de las funciones DllMain de DLL devuelven FALSE, indicando que la inicialización no ha tenido éxito, el sistema termina todo el proceso, eliminando todas las imágenes de archivo de su espacio de direcciones y mostrando un cuadro de mensaje al usuario que indica que no ha podido comenzar el proceso. Cuando un hilo de un proceso llama a LoadLibrary o LoadLibraryEx, el sistema localiza la DLL especificada y proyecta la DLL en el espacio de direcciones del proceso. Después, el sistema llama a la función DllMain de la DLL con el valor DLL_PROCESS_ATTACH,

68

Page 70: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

utilizando el hilo que realizó la llamada a LoadLibrary o LoadLibraryEx. Después de que la función DllMain de la DLL haya procesado la notificación, el sistema permite que vuelva la llamada a LoadLibrary o LoadLibraryEx, y el hilo continúa su procesamiento con normalidad. Si la función DllMain devuelve FALSE, indicando que la inicialización no tuvo éxito, el sistema elimina automáticamente la proyección de la imagen del archivo DLL del espacio de direcciones del proceso y la llamada a LoadLibrary o LoadLibraryEx devuelve NULL. DLL_PROCESS_DETACH Cuando se elimina la proyección de una DLL del espacio de direcciones de un proceso, el sistema llama a la función DllMain de la DLL, pasando DLL_PROCESS_DETACH como valor fdwReason. Una DLL debería realizar todas las liberaciones relativas al proceso cuando procese este valor. Por ejemplo, una DLL podría llamar a HeapDestroy para destruir un Heap que ha creado durante la notificación DLL_PROCESS_ATTACH. Si se llama a la función DllMain de una DLL con un valor fdwReason igual a DLL_PROCESS_ATTACH y DllMain devuelve FALSE, indicando que la inicialización no ha tenido éxito, el sistema no dejará de llamar a DllMain con el valor DLL_PROCESS_DETACH. Por esta razón, debe asegurarse de que no intenta liberar nada que no se haya inicializado con éxito. Si se está eliminando la proyección de la DLL porque el proceso está terminando, el hilo que llama a ExitProcess es el responsable de ejecutar el código de la función DllMain. Bajo circunstancias normales, éste es el hilo primario de la aplicación. Cuando la función DllMain vuelve al código de inicio de la biblioteca de tiempo de ejecución de C, este código llama explícitamente a la función ExitProcess para terminar el proceso. Si se está eliminando la proyección de la DLL porque un hilo del proceso ha llamado a FreeLibrary, este hilo ejecuta el código de la función DllMain. La llamada a Fre-eLibrary no volverá hasta que la función DllMain haya terminado de ejecutarse. Si un proceso termina porque algún hilo del sistema llama a TerminateProcess, el sistema no llama a la función DllMain de la DLL con el valor DLL_PROCESS_DETACH. Esto significa que las DLLs proyectadas en el espacio de direcciones del proceso no tendrán la oportunidad de realizar ninguna liberación antes de que el proceso termine. Esto podría provocar la pérdida de datos. Sólo se debería utilizar la función TerminateProcess como último recurso.

69

Page 71: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Library. Figura 2-26. Los pasos que lleva a cabo el sistema cuando un hilo llama a Load

70

Page 72: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

La Figura 2-27. Los pasos que se lleva a cabo el sistema cuando un hilo llama a FreeLibrary.

DLL_THREAD_ATTACH Cua o o, el sistema examina todas las imágenes de archivo DLL nd se crea un hilo en un procesproy t pacio de direcciones del proceso y llama a cada una de las ec adas actualmente en el esfunc n con el valor DLL_THREAD_ATTACH. Esta notificación io s DLLses DllMain de estaindica a todas las DLLs que realicen todas las inicializaciones de cada hilo. Por ejemplo, la versión DLL de la biblioteca de tiempo de ejecución de C asigna un bloque de datos para que una aplicación multihilo pueda utilizar de forma segura las funciones contenidas en la biblioteca de tiempo de ejecución de C.

nido la oportunidad de procesar esta

El hilo recién creado es el responsable de ejecutar el código de todas las funciones DllMain dela DLL. Sólo después de que todas las DLLs hayan tenotificación, permitirá el sistema que el nuevo hilo comience a ejecutar la función de su hilo. Si un proceso ya tiene varios hilos ejecutándose en él cuando se proyecta una nueva DLL en su espacio de direcciones, el sistema no llama a la función DllMain de la DLL con el valor DLL_THREAD_ATTACH para ninguno de los hilos ya existentes. El sistema llama a la función DllMain de la DLL con un valor DLL_THREAD_ATTACH sólo si la DLL está proyectada en el espacio de direcciones del proceso en el momento en que se crea el hilo nuevo. Observe también que el sistema no llama a ninguna de las funciones DllMain con un valor DLL_THREAD_ATTACH para el hilo primario del proceso. Todas las DLLs que están proyectadas en el espacio de direcciones del proceso cuando se llama al proceso por primera vez reciben la notificación DLL_PROCESS_ATTACH, pero no la DLL_THREAD_ATTACH.

71

Page 73: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

DLL_THREAD_DETACH Cuando un hilo termina llamando a ExitThread, el sistema examina todas las imágenes de archivo de DLL proyectadas actualmente en el espacio de direcciones del proceso y llama a todas las funciones DllMain de la DLL con un valor DLL_THREAD_DETACH. Esta notificación les indica a todas las DLLs que realicen todas las liberaciones correspondientes al hilo. Por ejemplo, la versión de DLL de la biblioteca de tiempo de ejecución de C libera el bloque de datos que utiliza para gestionar las aplicaciones multihilo. Importante Si un hilo termina porque llama a TerminateThread, el sistema no llama a todas las funciones DllMain de la DLL con un valor DLL_THREAD_DETACH. Esto significa que todas las DLLs proyectadas en el espacio de direcciones del proceso no tendrán la oportunidad de realizar ninguna liberación antes de que termine el hilo. Esto podría provocar que se perdiesen datos. Igual que TerminateProcess, solo se debe utilizar TerminateThread como último recurso. Si se está ejecutando algún hilo cuando se elimina la proyección de la DLL, no se llama a DllMain con DLL_THREAD_DETACH para ninguno de los hilos. Se podría comprobar esto en el procesamiento de DLL_PROCESS_DETACH para realizar cualquier liberación que resulte necesaria. Exportar funciones y variables de una DLL Cuando se crea una DLL, se crea un conjunto de funciones a las que se desea que un EXE u otras DLLs sean capaces de llamar. Cuando una función de DLL pasa a estar disponible para un archivo EXE o de otra DLL, se dice que la función está exportada. Win32 hace posible que se exporten variables de datos globales además de funciones. Ahora veremos los pasos que se deben seguir para exportar las funciones y variables globales de una DLL. El código siguiente (tomado de un archivo fuente de DLL) muestra cómo exportar una función llamada Ada y una variable entera global llamada g_nUsageCount desde una DLL: _declspec(dllexport) int Add (int nLeft, int nRight) { return (nLeft + nRight); } _declspec(dllexport) int g_nUsageCount = O ;

En su mayor parte, nada de este código debería resultarle nuevo a excepción de _declspec(dllexport). El compilador de Microsoft C/C++ la reconoce como una nueva palabra clave. Cuando el compilador compila la función Add y la variable g_nUsageCount, incrusta alguna información adicional en el archivo .OBJ resultante. El objeto de esta información es que el enlazador la analice sintácticamente y la procese cuando enlaza todos los objetos OBJ de la DLL. Cuando se enlaza la DLL, el enlazador detecta esta información incrustada acerca de la función y de la variable exportada, y genera automáticamente un archivo LIB que contiene la lista de símbolos exportados por la DLL. Este archivo LIB, claro está, se necesitará para enlazar cualquier EXE que llame a las funciones exportadas de la DLL. Además de crear el archivo LIB, el enlazador incrusta una tabla de nombres exportados de función o de variable y la dirección en la cual está situada la función o variable dentro de la imagen de archivo DLL. El enlazador asegura que la lista esté orden

ada alfabéticamente en función del nombre de símbolo.

Importar funciones y variables de una DLL Cuando se desea que un EXE llame a las funciones o acceda a las variables contenidas en una DLL, se le debe indicar al compilador que las funciones o variables a las que se desea acceder

72

Page 74: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

están contenidas en una DLL. Por ejemplo, el fragmento de código siguiente muestra cómo importar la función Ada y la variable g_nUsageCount exportadas por la DLL que hemos visto en el apartado anterior: _declspec(dllimport) int Add (int nLeft, int nRight); _declspec(dllimport) int g_nUsageCount;

Como _declspec(dllexport), _declspec(dllimport) es una palabra clave reconocida por el

compilador de Microsoft C/C++. Esta palabra clave le indica al compilador que la función Add y la variable g_nUsageCount están contenidas en una DLL a la que el EXE tendrá acceso cuando se cargue. Esto provoca que el compilador genere código especial para estos símbolos importados.

Cuando se desea importar un símbolo, no se tiene que utilizar la palabra clave _declspec(dllimport). En su lugar, basta con utilizar la palabra clave extern estándar de C. Sin embargo, el compilador es capaz de generar un código ligeramente más eficiente si conoce por adelantado que el símbolo al que se hace referencia va a ser importado desde el archivo LIB de una DLL. Por tanto, le recomiendo que utilice la palabra clave _declspec(dllimport) para los símbolos de funciones y de datos importados. Un hilo puede obtener la dirección de la función o variable exportada por una DLL llamando a la función GetProcAddress: FARPROC GetProcAddress (HINSTANCE hinstDll, LPCSTR IpszProc);

El parámetro hinstDll especifica el descriptor de la DLL. El valor que devuelve LoadLibrary o LoadLibraryEx identifica este valor de descriptor. El parámetro IpszProc puede tomar dos form cadena terminada en cero que contiene el as. En primer lugar, puede ser la dirección de una nombre de la función cuya dirección deseamos: Ipfn = GetProcAddress (hinstDll, "AlgunaFuncEnDll");

Observe que el parámetro IpszProc aparece en el prototipo como LPCSTR, en vez de LPC no se TSTR. Esto significa que la función GetProcAddress sólo aceptará cadenas ANSÍ —le puede pasar una cadena Unicode a esta función—. La razón es que los símbolos de función y variable se almacenan siempre como cadenas ANSÍ en la tabla de exportaciones de la DLL. La segunda forma del parámetro IpszProc indica el número ordinal de la función cuya dirección deseamos: Ipfn = GetProcAddress (hinstDll, MAKEINTRESOURCE(2));

Esta utilización asume que conocemos que el creador de la DLL le ha asignado a la función AlgunaFuncEnDll el valor ordinal 2. Los dos métodos proporcionan la dirección de la función AlgunaFuncEnDll contenida en la DLL. Si no se puede encontrar la función, GetProcAddress devuelve NULL. Archivo de cabecera de una DLL Habitualmente, cuando se crea una DLL, también se crea un archivo de cabecera. Este archivo tiene los prototipos de todas las funciones y variables que la DLL está exportando. Cuando se compilan los archivos de código fuente del EXE, se incluirá este archivo de cabecera. A menudo también desearemos incluir este archivo de cabecera cuando se compilen los archivos de código fuente de la DLL.

73

Page 75: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.3.1 Desarrollo de Plugins en 3D Studio Max. El SDK de 3ds max es un conjunto de clases de C++ y sus rutinas. Escribir un plugin implica

egrar

ue utiliza 3D Studio Max para la programación de plugins, es que se ha tomado como principal referencia para el desarrollo de la arquitectura de

ue no de manera literal, si en cuanto a la filosofía de la utilización de los bloques de parámetros y los mapas de parámetros, así como la manera de implementar la

n. De Animatable deriva ReferenceMaker. Esta clase permite hacer referencias a otros objetos. De ReferenceMaker

. u

ReferenceMaker dependiente que ha cambiado.

s de 3ds por 3ds max o Windows en tiempo de carga y proporcionan

la DLL cargada y las distintas clases del plugin que proporciona la DLL.

• LibNumberClasses() ssDesc(i)

• LibDescription()

in()

de 3ds max se implementan como DLLs. Cuando los desarrolladores compilan y enlazan el código de su plugin, se genera una DLL.

madas son: inicializar los controles personalizados del interfaz de usuario, e inicializar los controles comunes de Windows. El código siguiente muestra un ejemplo.

crear objetos a partir de las clases e implementar métodos para permitir la comunicación entre el plugin y el sistema. Además de utilizar las clases proporcionadas por el SDK, se pueden intnuevas clases al framework del SDK de manera similar. El motivo de profundizar en la metodología q

plugins de este proyecto, aunq

DLL internamente, ya que se ha considerado como un método potente, sencillo y flexible para los programadores de plugins.

La mayoría de las clases del SDK heredan de tres clases abstractas. La clase raíz de estas tres es la clase Animatable. Define la mayor parte de los métodos de animació

deriva ReferenceTarget. Una referencia es un enlace bidireccional entre objetos de una escenaCrea un registro oficial de las dependencias entre el ReferenceMaker y ReferenceTarget. Sfunción principal es permitir que un ReferenceTarget informe de algún modo a su

2.3.1.1 Funciones que debe implementar un plugin en 3ds Max

Las siguientes funciones deben ser implementadas por los desarrolladores de pluginmax. Estas funciones son invocadasinformación sobre Estas funciones son:

• DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)

• LibCla

• LibVersion()

2.3.1.2 La funcion DllMa

Los plugins

La función DllMain() la implementa un desarrollador y es llamada por Windows cuando se carga el plugin. La mayoría de los plugins tan solo hacen dos llamadas dentro de esta función. Estas lla

int controlsInit = FALSE; BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) { // Hang on to this DLL's instance handle. hInstance = hinstDLL; if (! controlsInit) { controlsInit = TRUE; // Initialize MAX's custom controls InitCustomControls(hInstance); // Initialize Win95 controls

74

Page 76: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

InitCommonControls(); } return(TRUE); }

Hay que tener en cuenta que la llamada a DllMain() puede realizarse mas de una vez, por lo que

2.3.1.3 LibNumberClasses

a cargarlas. Cuando encuentra una, necesita determinar el número de clases tipo plugin dentro de la DLL. El programador proporciona esta

efiniendo la función LibNumberClasses().

hay q controlar que los controles no se inicialicen mas de una vez.

Cuando 3ds max arranca, busca DLLs par

información a 3ds max dPor ejemplo:

__declspec(dllexport) int LibNumberClasses() { return 1; }

El desarrollador debe devolver el numero de clases de plugin que hay implementado dentro de

2.3 4

El plugi smo para obtener los Descriptores de Clases definidos por el plugin. Los Descriptores de Clases proporcionan al sistema de la informa L. La función LibClassDesc(i) permite al siste a . Una DLL puede tener varios Descriptores de

la DLL.

.1. LibClassDesc

n debe proporcionar al sistema algún mecani

ción sobre las clases plugin en el DLm acceder a los Descriptores de Clases

Clases, uno para cada clase plugin. La función debe devolver un puntero al i-ésimo descriptor de clase. Por ejemplo:

__declspec(dllexport) ClassDesc *LibClassDesc(int i) { switch(i) { case 0: return &MeltCD; case 1: return &CrumpleCD; default: return 0; } }

Este ejemplo devuelve un puntero al descriptor de la clase Melt, o al descriptor de la clase Crumple.

2.3.1.5 LibDescription

Devuelve un texto que contenga el nombre descriptivo de la DLL.

__declspec( dllexport ) const TCHAR *LibDescription() { return _T("Melt Modifier. Call 1-800-PLUG-INS to obtain a copy"); }

2.3.1.6 LibVersion()

Los desarrolladores deben implementar una función que permita al sistema tratar con versiones bsoletas de plugins. Debido que la arquitectura de 3ds max mantiene una relación muy trecha con sus plugins, el sistema puede en algún punto evitar cargar algunos plugins

asiado antiguos. Para permitir que 3ds max cumpla esto, la DLL debe implementar una

oesdem

75

Page 77: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

función llamada LibVersion(). Esta función simplemente devuelve una constante indicando la versión del sistema bajo la cual fue compilada. Las versiones futuras de 3ds max podrían actualizar esta constante, incluso las DLLs mas antiguas siempre devolverán el valor. Con esta función el sistema puede comprobar si se está cargando una DLL ya obsoleta, y en ese caso mostrar un mensaje de aviso.

__declspec( dllexport ) ULONG LibVersion() { return VERSION_3DSMAX; }

El significado de VERSION_MAX ha sido mejorado en la versión 2 para incluir información sobre la versión actual de max, así como el numero de la versión actual de la API y el numero de v i

La palab a palabra tengan e

ers ón del 3ds max SDK.

ra más alta contiene el número de la versión de 3ds max multiplicado por 100, y lbaja es el número de API y la revisión del SDK. 3ds max solo cargará DLL’s que l numero de API actual.

#define VERSION_3DSMAX ((MAX_RELEASE<<16)+(MAX_API_NUM<<8)+MAX_SDK_REV)

MAX_RNum

MAX Amm Ls con el

MAX o dejen de poder cargarse.

AX_SDK_REV Esto indica la revisión del SDK para una API dada. Este numero se incrementa cuando la

ambia de manera significante (por ejemplo se añade un nuevo valor de retorno de la función GetProperty() ), pero las cabeceras no han cambiado.

ELEASE ero de versión de 3ds max multiplicado por 1000.

PI_NUM _Nu ero de API de 3ds max. Cuando un cambio en la API requiere ser recompilada, este nu ero se incrementa y MAX_SDK_REV se pone a 0. Esto hará que todas las DL

_API_NUM antigu

M

funcionalidad del SDK c

Un desarrollador puede acceder a este valor usando

DWORD Get3DSMAXVersion();

2.3.1.7 Descriptores de clases

Los descriptores de clases proporcionan al sistema informacion sobre las clases de plugin en la DLL. Un método del descriptor de clase es también responsable de reservar nuevas instancias de la clase plugin. El desarrollador crea un descriptor de clase derivando la clase ClassDesc e implementando varios de sus métodos. Debajo hay un ejemplo de un descriptor de clase y la declaración de una única instancia estática.

class MeltClassDesc : public ClassDesc { public: int IsPublic() { return TRUE; } void * Create(BOOL loading=FALSE) { return new MeltMod(); } const TCHAR * ClassName() { return _T("Melt"); } SClass_ID SuperClassID() { return OSM_CLASS_ID; } Class_ID ClassID() { return Class_ID(0xA1C8E1D1, 0xE7AA2BE5); } const TCHAR* Category() { return _T(""); } }; static MeltClassDesc MeltCD;

76

Page 78: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Los siguientes seis métodos del descriptor de clase se describen a continuación.

IsPublic()

Este método devuelve un booleano, si el plugin es accesible por el usuario, como suele ser normal, devuelve TRUE. Ciertos plugins pueden ser usados de manera privada por otros plugins, implementados en la misma DLL y no debería aparecer en listas para que los usuarios los elijan. Estos plugins devolverán FALSE.

Create(BOOL loading=false)

3ds max llama esta función cuando necesita un puntero a una nueva instancia de la clase plugin.

l

un flag indicando si la clase a crear va a ser argada de un fichero de disco. Si el flag es TRUE, el plugin probablemente no tenga que alizar ninguna inicialización del objeto ya que el proceso de carga se encajará de ello.

uando el sistema necesita eliminar una instancia de una clase plugin, usualmente llama al étodo DeleteThis(). Los desarrolladores de plugins también deben implementar este étodo. Puesto que un desarrollador usa el operador new para reservar memoria, deberá usar el

perador delete para liberarla. Por ejemplo, el desarrollador podría implementar eleteThis() de esta manera :

Por ejemplo, si 3ds max está cargando un fichero de disco conteniendo un plugin anteriormente utilizado, llamará a la función Create() del plugin. El plugin responderá reservando una nueva instancia de su clase plugin. Como en el ejemplo dedescriptor de clase anterior, tan solo implica el uso del operador new.

l parámetro opcional de la función Create(), es Ecre

CmmoD

void DeleteThis() { delete this; }

This method returns the name of the class. This name appears in the button for the plug-in in the ds max user interface. 3

SuperClassID()

Este método devuelve la constante definida por el sistema describiendo la clase de la cual deriva ste plugin. Por ejemplo, el plugin Bend revuelve OSM_CLASS_ID. Este ID se usa por todos s modificadores de objetos.

elo

ClassID()

Este método debe devolver el ID único para el objeto plugin. El SDK proporciona un programa ara generar este ClassID, es importante usar este programa para no provocar ningún conflicto e IDs.

pd

Category()

Indica la categoría del plugin. De esta manera el plugin se mostrará en una u otra lista de ategorías del interfaz de usuario. Si la categoría no existe, se crea una nueva.

os bloques de parámetros

c

L

77

Page 79: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

La clase de bloque de parámetros proporciona un mecanismo para almacenar valores para los arámetros de los plugins. Cuando se crea un bloque de parámetros, el desarrollador especifica l número de parámetros y el tipo de cada parámetro. El tipo de cada parámetro consiste en un ngo de tipos predefinidos como entonces, coma flotante, punto 3D, y color.

ara acceder a los valores del bloque de parámetros, el desarrolladores usan los métodos etValue() y SetValue().

n descriptor de bloque de parámetros se usa para describir cada parámetro. Se inicializa asando tres argumentos por parámetro.

pera

PG

Up

class ParamBlockDesc { public: ParamType type; UserType *user; BOOL animatable; };

Los valores que puede tomar ParamType son :

• TYPE_INT – valores enteros • TYPE_FLOAT – valores en coma flotante • TYPE_POINT3 – Puntos en el espacio 3D • TYPE_RGBA – Valores de color • TYPE_BOOL – Valores booleanos

uando un desarrollador necesita obtener un valor del bloque de parámetros, se usa la función etValue(). Existe una función sobrecargada para cada tipo de valor a obtener (int, float, oint y RGBA). Cada método tiene cuatro parámetros. A continuación se muestra la función ara el tipo float:

CGpp

BOOL GetValue( int i, TimeValue t, float &v, Interval &ivalid );

Cuando un desarrollador necesita almacenar un valor en el bloque de parámetros, se usa la nción SetValue(). Igual que en GetValue(), existe una función sobrecargada para

ada tipo de dato. fuc

BOOL SetValue( int i, TimeValue t, float v );

Puesto que los bloques de parámetros derivan de ReferenceTarget, los plugins pueden crear ferencias a ellos. Creando una referencia a un bloque de parámetros, el plugin puede ser

notificado siempre que alguno de sus parámetros tome un nuevo valor. Cuando cambia un valor del bloque de parámetros, el plugin necesita ser informnotificación la hace el métod

Hay dos métodos que se invocan cuando un usuario comienza y termina de modificar los arámetros de un elemento. Estos son BeginEditParams() y EndEditParams().

re

ado. Esta o NotifyDependents() de la clase ReferenceMaker.

p

78

Page 80: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

2.3.1.8 Mapas de parámetros

os mapas de parámetros en 3ds max se usan para minimizar el esfuerzo de programación que quiere mantener el interfaz de usuario de un plugin. Un simple plugin, tal como una esfera

rocedural, tiene un interfaz de usuario consistente en varios controles como spinners, radios y heck-boxes. Cada uno de estos controles tiene una correspondencia uno a uno con una variable un parámetro de un bloque de parámetros. Los mapas de parámetros se pueden usar para apear los controles del interfaz de usuario en manejadores del tipo apropiado de dato. El uso

e los mapas de parámetros tienes varias ventajas:

• El desarrollador no necesita escribir código de procesado de mensajes para manejar los eventos generados por el usuario. Por ejemplo, si un desarrollador no utiliza mapas de parámetros, debe proporcionar una función del dialogo que procese los mensajes enviados a los controles cada vez que el usuario interactúa con ellos. Por ejemplo el control spinner envía un mensaje cuando el usuario pulsa sobre las flechas de arriba y abajo o introduce nuevos valores. Los mapas de parámetros manejan estos mensajes procesándolos internamente.

• El desarrollador se libera de tratar con la complejidad de tener que manejar controladores para controlar la animación de los valores del interfaz de usuario. El tipo apropiado de controlador se asigna y se maneja por el bloque de parámetros que controla el mapa de parámetros. El desarrollador tan solo usa las funciones GetValue() y SetValue() para obtener o almacenar valores.

• El Undo y Redo se manejan automáticamente cuando el valor de un parámetro cambia. • La carga y el guardado de los parámetros a disco y desde disco se manejan

automáticamente.

Lrepcomd

2.4 Conclusiones. En este capítulo se han mostrado las diferencias entre la informática gráfica tradicional y la informática gráfica en tiempo real, mostrando la necesidad de utilización de hardware especializado en la generación de imágenes, y en consecuencia, de librerías de bajo nivel que proporcionen control sobre dicho hardware. En este sentido, se ha realizado un recorrido histórico por las distintas librerías que proporcionan un API para el renderizado de gráficos 3D, finalizando con la librería OpenGl, un standard empleado por la gran mayoría de los sistemas gráficos actuales. Se ha presentado de forma abreviada los principales aspectos que definen la forma de funcionamiento de la librería OpenGl, realizando también una introducción sobre la forma en la que opera con las matrices de transformación. Se ha descrito como las librerías de bajo nivel proporcionan buenos métodos para controlar las capacidades del hardware gráfico, pero resultan demasiado elementales si se desea implementar una escena de simulación compleja, siendo en este caso necesaria la utilización de una librería gráfica de alto nivel basada en la utilización de un Grafo de Escena. Los grafos de escena están diseñados para optimizar el proceso de dibujado y contribuir a la organización de la base de datos, resultando de especial importancia sus procesos de culling y selección de nivel de detalle, y su capacidad para actuar como soporte para la aplicación jerárquica de transformaciones afines. Se han presentado los tipos de nodos básicos empleados en la definición de estos grafos, y también la forma en la que estas librerías de alto nivel actúan en el caso de disponer de un sistema con varios procesadores. También se ha realizado un recorrido por los grafos de escena actuales, profundizando en aquellos que han tenido una mayor influencia en la evolución de esta rama de la informática gráfica (OpenGl Performer, Open Inventor y VRML). El resto de los grafos de escena presentan

79

Page 81: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

unas características básicas similares, siendo destacable que alguno de ellos presenta carencias a la hora de proporcionar un buen rendimiento en tiempo real, que muchos de ellos reproducen el comportamiento de OpenGl Performer, y que algunos de ellos están siendo distribuidos como código abierto, como es el caso de OpenSceneGraph. He os hecho del mismo modo un recorrido sobre los distintos editores 3D y su importancia en mel mundo de la informática grafica, la simulación, realidad virtual, videojuegos etc., y hemos visto como la mayor parte de los motores de videojuegos son o bien motores de visualización o bien motores completos, siendo cada vez mas estandarizados. La simulación y la visualización están fuertemente acopladas, y en las aplicaciones de realidad virtual existe una fuerte componente de simulación y exigencias elevadas de velocidad interacción con el usuario. De las aplicaciones vistas, tan solo permiten trabajar en tiempo real UnrealED y Hammer Editor. Las librerías de enlace dinámico permiten el desarrollo de plugins en las aplicaciones, las cuales no proporcionan una mayor personalización, modularidad, mantenibilidad y flexibilidad, sincluso puede prolongar la vida de nuestro software. Como ejemplo de aplicación basada en el uso de plugins hemos estudiado a 3D Studio Max, el cual hemos tomado como referencia este tipo de arquitectura para este proyecto.

80

Page 82: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

OLOGIA Y MATERIALES

PARTE III TECN

81

Page 83: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

82

Page 84: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE

PARTE III......................................................................................................

3.1 Metodología ...................................................................... ¡Error! Marcador no definido. 3.2 Materiales .......................................................................... ¡Error! Marcador no definido. 3.3 Planificación temporal....................................................... ¡Error! Marcador no definido.

3.3.1 Diagrama de Gant....................................................... ¡Error! Marcador no definido.

83

Page 85: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

3.1 Metodología er pa s implicadas en

, documentado detalladamente en la parte II de este proy momento de planificar en detalle las tareas que se

.2 Materiales

l recurso más importante para el desarrollo de este proyecto será un PC convencional. En icho PC será necesaria la instalación de un compilador de C++. Se ha elegido para esta casión el compilador Microsoft Visual Studio .NET, versión 7.1 ya que su versión anterior resentaba distintas incompatibilidades con la librería OpenSceneGraph necesaria para el esarrollo del proyecto. La licencia de uso de esta plataforma de desarrollo de aplicaciones ha ido adquirida por la Universidad de Valencia, por lo que no ha sido necesaria su compra, uesto que la universidad lo utiliza como apoyo para la docencia en las distintas asignaturas de rogramación de la carrera.

na vez instalado dicho compilador no queda más que instalar la librería OpenSceneGraph en l sistema operativo así como configurar el compilador adecuadamente para compilar decuadamente sus fuentes. l software generado será dependiente del sistema operativo (en este caso Microsoft windows), a que se hará uso de las MFCs (Microsoft Foundation Classes). ebido al motivo de uso del compilador de Microsoft el uso del software generado deberá

orrer bajo sistemas operativos de Microsoft.

.3 Planificación temporal. l proyecto, siguiendo las técnicas de desarrollo de software aprendidas en la asignatura IS2, uede dividirse en 6 fases bien definidas:

1) Búsqueda bibliográfica. En esta etapa se ha recopilado toda la información necesaria para poder saber el alcance del proyecto al que nos enfrentamos. Con esta búsqueda se documenta el proyecto para tener una base de conocimiento adecuada al problema que se aborda en este estudio. Se investigan las tecnologías existentes, trabajos realizados, y posibles soluciones ya implementadas, que sirvan de posible punto de partida en el desarrollo de este proyecto.

2) Análisis. En este punto se establecen los requisitos del sistema en general, e identificamos las partes del mismo. Una vez diferenciadas cada una de las partes, se procede al análisis por separado, viendo cual es la solución más adecuada para nuestro caso en particular. En el análisis se utilizará la notación UML apropiada para cada apartado: casos de uso, diagramas entidad-relación, etc.

3) Diseño de cada una de las partes. Una vez analizado el sistema, se especifica la arquitectura software del sistema y se ofrece una primera aproximación algorítmica al sistema global, que sea capaz de cumplir con todas las conclusiones alcanzadas en el análisis anterior. De nuevo en este apartado se utilizarán los diagramas UML que se requieran.

4) Implementación. Una vez definidos requerimientos y funcionalidades de nuestro sistema, solo queda

El prime

so en todo proyecto es la investigación del estado de las tecnologíal mismo, con el objetivo de adquirir un conocimiento sobre la tarea a realizar, encontrar otros

estudios o aplicaciones existentes que estén relacionados con el mismo campo. Tras este estudio ecto, es

van a realizar dentro del proyecto.

3 Edopdspp UeaEyDc

3Ep

84

Page 86: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

codificar el sistema convenientemente, teniendo en cuenta no solo los apartados de análisis y diseño realizados con anterioridad, sino también las decisiones tomadas en cuanto al lenguaje de programación, comunicaciones, etc.

5) Pruebas. En esta parte se comprueba que todo el trabajo desarrollado es correcto, realizando pruebas de diferentes tipos, especificas para cada parte concreta del proyecto.

6) Redacción. Es la última parte del proyecto, pero esto no indica que se realice en último lugar. La redacción del proyecto es un proceso creciente y continuo desde el comienzo del proyecto, redactando en cada momento los detalles y aspectos de interés que han aparecido en el transcurso del proyecto. Esta es la parte más tediosa del proyecto, en la que la prioridad es poder comunicar a cualquier lector interesado, el trabajo realizado, la forma en que se ha llevado a cabo, y los resultados obtenidos.

.3.1 Diagrama de Gant.

na vez explicadas las diferentes fases en las que se va a dividir este proyecto, se puede realizar na representación gráfica de la planificación temporal. Para este propósito se muestra a ontinuación el diagrama de Gant, utilizado para indicar la duración y posición en el tiempo de ada una de las tareas principales. En el diagrama se utiliza una división temporal en un total de 4 semanas, comenzando n el mes de octubre, y planificando el final del proyecto en el mes de agosto.

Documentación bibliográfica 60 días

3 Uucc4e

Análisis del sistema de información 15 días Diseño del sistema 15 días Implementación 115 días Diseño interfaz de usuario 20 días Sistema automático de generación de controles 14 días Control del grafo de escena múltiple 35 días Interacción escena/usuario 20 días Sistema undo/redo 15 días Sistema de soporte de plugins 10 días Pruebas y depuración 12 días Redacción 24 días

Documentación bibliografica60 días Analisis del sistema de informacion15 días

Diseño del sistema15 días

Implementación 115 días

Diseño interfaz de usuario20 días

Generacion automatica de controles14 días

Control del grafo de escena multiple 35 días

Interaccion escena/usuario 20 días

Sistema undo/redo 15 días

Soporte de plugins 10 días

Pruebas y depuracion 12 días Redaccion 24 días

oct '05 nov '05 dic '05 ene '06 feb '06 mar '06 abr '06 may '06 jun '06 jul '06 ago '06 sep '06 oct '06

85

Page 87: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Los materiales necesarios para el proyecto y sus costes son los siguientes: PC Pentium 4 con 1GB de memoria RAM, tarjeta gráfica aceleradora GeForce MX y tarjeta de red utilizado durante la elaboración del proyecto

700.00 €

istema Operativo Windows XP (cedido por el Instituto de Robótica). - S Herramientas de desarrollo Visual Studio .NET (cedido por el Instituto de Robótica).

-

icencia de Visual .NET 96.15 € LConexión a Internet, utilizando para ello la red de la Universidad de Valencia. -

ibrería grafica OpenSceneGraph (open source). 0 €

odo este proyecto se engloba en la nueva línea de investigación del grupo ARTEC acerca de la creación y simulación de escenarios virtuales, para simulaciones en tiempo real. Por tanto, do el material arriba mencionado, se utilizará posteriormente en otros proyectos, amortizando

icho coste en un corto periodo de tiempo. or tanto, el coste amortizado se calculará en 24 meses, habiendo utilizado para este proyecto 1 meses.

L TretodP1

CONCEPTO IMPORTE PC Pentium 4, 1GB RAM, Ge-Force MX, tarjeta red, etc. 700.00 €Licencia Visual .NET 96.15 €

Base imponible 796.15 €IVA 16% 127.39 €TOTAL: 923.54 €

Coste amortizado = (923.54 / 24) * 11 = 423.28 €

estos costes es necesario añadir el sueldo de un Ingeniero Informático. Suponiendo un sueldo e 24,050.00 €, se obtiene un salario de 2,004.00 € al mes. Habiendo trabajado durante 11

meses: Sueldo = 2,004.00 € * 11 = 22,044.00 €

Precio = Coste amort. + Sueldo = 923,54 + 20,040 = 22,967.5 Si ha este precio añadimos un 10 % para cubrir posibles imprevistos, obten

nal: TOTAL = Precio + 10 % = 25,264.3 €

Ad

4 €

emos una cantidad fi

86

Page 88: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

87

Page 89: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

88

Page 90: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

P IV ARTE

ANALISIS

89

Page 91: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

NDICE

ARTE IV......................................................................................................

4.1 Introducción ...................................................................... ¡Error! Marcador no definido. 4.2 Análisis de Requisitos. ...................................................... ¡Error! Marcador no definido.

4.2.1 Requisitos generales del sistema. ............................... ¡Error! Marcador no definido. 4.2.2 Requisitos de la representación del grafo de escena .. ¡Error! Marcador no definido. 4.2.3 Requisitos de la representación de tipos de datos en el interfaz..... ¡Error! Marcador no definido. 4.2.4 Requisitos de la manipulación sobre la representación 3D del grafo.................¡Error! Marcador no definido. 4.2.5 Requisitos del sistema de deshacer / rehacer.............. ¡Error! Marcador no definido. 4.2.5 Requisitos del sistema de plugins............................... ¡Error! Marcador no definido.

I P

90

Page 92: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.2.6 Requisitos del Manejador de Vista Activa ................. ¡Error! Marcador no definido. 4.3 Análisis.............................................................................. ¡Error! Marcador no definido.

no definido. 4.3.1.1 Grupos de parámetros.......................................... ¡Error! Marcador no definido. 4.3.1.2 Descriptores de parámetros ................................. ¡Error! Marcador no definido. 4.3.1.3 El gestor de parámetros ....................................... ¡Error! Marcador no definido. 4.3.1.4 Objects, Nodes, y AttributeTypes en OpenSceneGraph ..... ¡Error! Marcador no definido. 4.3.1.5. El Gestor de ObjectTypes, NodeTypes y AttributeTypes. . ¡Error! Marcador no definido.

4.3.2 Análisis de la representación del grafo de escena ...... ¡Error! Marcador no definido. 4.3.2.1 Crear un árbol a partir de un grafo ...................... ¡Error! Marcador no definido. 4.3.2.2 Mostrar el grafo en múltiples vistas de árbol ...... ¡Error! Marcador no definido. 4.3.2.3 Acciones sobre el árbol ....................................... ¡Error! Marcador no definido. 4.3.2.4 Mostrar la información de un nodo del grafo...... ¡Error! Marcador no definido.

4.3.3 Análisis de la interacción con el visor del editor........ ¡Error! Marcador no definido. 4.3.3.1 El gestor de selección.......................................... ¡Error! Marcador no definido. 4.3.3.2 El eje manipulador .............................................. ¡Error! Marcador no definido. 4.3.3.3 Creación automática de Matrices de Transformación ......... ¡Error! Marcador no definido. 4.3.3.4 Traslación de objetos usando el eje manipulador ¡Error! Marcador no definido. 4.3.3.5 Representación de objetos independientes a la escena del editor................¡Error! Marcador no definido.

4.3.4 Análisis del sistema deshacer / rehacer. ..................... ¡Error! Marcador no definido. 4.2.7 Análisis del sistema de plugins. ................................. ¡Error! Marcador no definido. 4.2.8 Análisis del Manejador de Vista Activa..................... ¡Error! Marcador no definido.

4.4 Casos de uso...................................................................... ¡Error! Marcador no definido. 4.4.1 Funciones del sistema................................................. ¡Error! Marcador no definido. 4.4.2 Descripción de alto nivel de los Casos de Uso........... ¡Error! Marcador no definido.

Iniciar la aplicación. ........................................................ ¡Error! Marcador no definido. Iniciar Barras. .................................................................. ¡Error! Marcador no definido. Crear barra de paneles de comandos. .............................. ¡Error! Marcador no definido. Iniciar tipos de objeto. ..................................................... ¡Error! Marcador no definido. Registrar un TabOutput. .................................................. ¡Error! Marcador no definido. Registrar un ObjectType. ................................................ ¡Error! Marcador no definido. Mapear los grupos de parámetros de un TabOutput........ ¡Error! Marcador no definido. Cargar Plugins. ................................................................ ¡Error! Marcador no definido. Cerrar aplicación. ............................................................ ¡Error! Marcador no definido. Cerrar treebar .................................................................. ¡Error! Marcador no definido. Cerrar escena. .................................................................. ¡Error! Marcador no definido. Cargar escena. ................................................................. ¡Error! Marcador no definido. Establecer un grafo sobre un elemento del árbol. ........... ¡Error! Marcador no definido. Replicar una escena de una TreeBar a otra. .................... ¡Error! Marcador no definido. Clonar un TreeCtrl a partir de otro. ................................. ¡Error! Marcador no definido. Nueva escena................................................................... ¡Error! Marcador no definido. Crear grafo por defecto. .................................................. ¡Error! Marcador no definido. Nuevo árbol. .................................................................... ¡Error! Marcador no definido. Insertar fichero. ............................................................... ¡Error! Marcador no definido. Cambiar escena activa. .................................................... ¡Error! Marcador no definido. Deshacer. ......................................................................... ¡Error! Marcador no definido. Rehacer............................................................................ ¡Error! Marcador no definido. Crear Nodo. ..................................................................... ¡Error! Marcador no definido. Crear un nodo según el nombre de su NodeType. .......... ¡Error! Marcador no definido. Crear una nueva instancia de un nodo según su nombre. ¡Error! Marcador no definido.

4.3.1 Análisis de la representación de los datos del grafo en el interfaz .. ¡Error! Marcador

91

Page 93: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Seleccionar elemento en árbol......................................... ¡Error! Marcador no definido. Seleccionar todas las instancias de un elemento. ............ ¡Error! Marcador no definido. Seleccionar todos los “mirrors” de un elemento. ............ ¡Error! Marcador no definido. Mostrar la información de un nodo ................................. ¡Error! Marcador no definido. Crear los diálogos de un TabOutput................................ ¡Error! Marcador no definido. Crear un diálogo a partir de un grupo de parámetros ...... ¡Error! Marcador no definido. Generar el contenido de un TabOutput ........................... ¡Error! Marcador no definido. Vaciar el contenido de un TabOutput.............................. ¡Error! Marcador no definido. Notificar fin de selección de un ObjectType................... ¡Error! Marcador no definido.

e un TabOutput ................................. ¡Error! Marcador no definido. visor............................................ ¡Error! Marcador no definido.

o.

ar la selección. ................................................... ¡Error! Marcador no definido. ido. ido.

.

. o. ................................................................ ¡Error! Marcador no definido.

o. o.

.................................................. ¡Error! Marcador no definido. o. o.

r no definido. do.

Acti do. o definido. o definido.

l o definido. o definido.

finido. o.

l o. Fina do. Tras cción.......................................................... ¡Error! Marcador no definido.

inido. inido.

ido. o. o.

nido. Eliminar un StateAttibute de un StateSet. ....................... ¡Error! Marcador no definido.

................................... ¡Error! Marcador no definido. .................................. ¡Error! Marcador no definido.

¡Error! Marcador no definido. el de comandos. ....... ¡Error! Marcador no

definido.

Mostrar los datos dSeleccionar nodo en el Agregar nodo a la selección del visor ............................. ¡Error! Marcador no definidCrear Matriz de Transformación como padre de un nodo............... ¡Error! Marcador nodefinido. ActualizActualizar el eje manipulador. ........................................ ¡Error! Marcador no definCopiar nodo. .................................................................... ¡Error! Marcador no definReplicar selección. .......................................................... ¡Error! Marcador no definidoMover nodo. .................................................................... ¡Error! Marcador no definidoDuplicar NodDuplicar Seleccion. ......................................................... ¡Error! Marcador no definidEliminar nodo.................................................................. ¡Error! Marcador no definidActivar modo selección.Activar modo traslación de objetos. ................................ ¡Error! Marcador no definidActivar modo escalado de objetos................................... ¡Error! Marcador no definidActivar modo rotación de objetos. .................................. ¡Error! MarcadoActivar modo rotar vista.................................................. ¡Error! Marcador no defini

var modo trasladar vista. .......................................... ¡Error! Marcador no definiEscalar selección. ............................................................ ¡Error! Marcador nComenzar escalado de selección. .................................... ¡Error! Marcador nRea izar escalado de selección. ....................................... ¡Error! Marcador nFinalizar escalado de selección. ...................................... ¡Error! Marcador nRotar selección. ............................................................... ¡Error! Marcador no deComenzar rotación de selección...................................... ¡Error! Marcador no definidRea izar rotación de selección......................................... ¡Error! Marcador no definid

lizar rotación de selección. ....................................... ¡Error! Marcador no definiladar sele

Comenzar traslación de selección. .................................. ¡Error! Marcador no defRealizar traslación de selección. ..................................... ¡Error! Marcador no defFinalizar traslación de selección. .................................... ¡Error! Marcador no definCentrar la vista en la selección. ....................................... ¡Error! Marcador no definidModificar el zoom de la vista. ......................................... ¡Error! Marcador no definidAñadir un StateAttribute a un StateSet............................ ¡Error! Marcador no defi

Añadir un Modo a un StateSet. ....Eliminar un Modo de un StateSet.Modificar un Modo de un StateSet. ................................Modificar el parámetro de un control del pan

Establecer el valor de un parámetro. ............................... ¡Error! Marcador no definido. Establecer el valor de un parámetro. ............................... ¡Error! Marcador no definido. Establecer el contenido del portapapeles......................... ¡Error! Marcador no definido. Pegar el contenido del portapapeles. ............................... ¡Error! Marcador no definido. Visualizar escena en modo de alambre. .......................... ¡Error! Marcador no definido. Visualizar escena en modo de relleno. ............................ ¡Error! Marcador no definido.

92

Page 94: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Visualizar sombreado en modo plano. ............................ ¡Error! Marcador no definido. Visualizar sombreado en modo suavizado. ..................... ¡Error! Marcador no definido. Mostrar vista superior de la escena. ................................ ¡Error! Marcador no definido. Mostrar vista inferior de la escena. ................................. ¡Error! Marcador no definido. Mostrar vista anterior de la escena. ................................. ¡Error! Marcador no definido.

..... ¡Error! Marcador no definido.

Mostrar vista posterior de la escena. ............................... ¡Error! Marcador no definido. Mostrar vista lateral izquierda de la escena..................... ¡Error! Marcador no definido. Mostrar vista lateral derecha de la escena. .................

4.4.3 Casos de Uso siguiendo la notación UML. ................ ¡Error! Marcador no definido.

93

Page 95: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

.1 Introducción

de as las características del sistema

ue se analiza.

4 Cualquier trabajo que requiere de un proceso de Ingeniería del Software, requiere una fasenálisis del problema a resolver, de forma que se obtengan toda

q

94

Page 96: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

En primer lugar se realizará un análisis general del sistema, describiendo el problema y las necesidades o requerimientos del sistema global, gracias a lo cual conoceremos qué debe

al problema, sino simplemente la rma de abordarlo.

1. Por una parte, analizaremos como plasmar la información de un grafo acíclico en

ita generar e los tipos de datos del

itir al usuario sobre la

4. Continuaremos viendo un sistema de historia de las acciones, conocido ente como deshacer / rehacer.

s como podemos dotar a nuestro software de un sistema de plugins. 6. Por último, tendremos que hacer que todo esto funcione mediante un sistema que

centralice todos los subsistemas anteriores que llamaremos Manejador de Vista Activa.

En este caso, se centrará la atención en realizar un análisis dentro de la perspectiva de los objetos, para posteriormente implementarlos en un lenguaje de programación orientado a objetos (C++). Se utilizara UML ya que reúne una colección de las mejores practicas en la ingeniería que han sido utilizadas hasta el momento, es trata de la unificación de los diversos sistemas que había hasta el momento, con las mejores características de cada uno de ellos.

4.2 Análisis de Requisitos.

4.2.1 Requisitos generales del sistema.

• Orientación a objetos: nos permite utilizar una forma de programación en base a objetos que responden a eventos, además de potenciar los conceptos de modularidad y reutilización de código consiguiendo aplicaciones que posean abstracción (representar las características esenciales de alo sin incluir antecedentes o detalles irrelevantes), encapsulamiento (desde el punto de vista de incluir dentro de un objeto todo lo que necesita, de tal forma que ningún otro objeto necesite conocer nunca su estructura interna), herencia (mecanismo por el cual somos capaces de compartir automáticamente métodos y atributos entre clases y subclases) y por último el polimorfismo (que nos da la capacidad de poder implementar múltiples formas de un mismo método, dependiendo cada una de ellas de la clase sobre la que se realice la implementación).

• Adaptabilidad: De forma que sea un sistema fácilmente adaptable tanto a nuevos cambios, como cambios sobre la estructura actual, además de ser fácilmente adaptable en cuanto a la plataforma sobre la que se implanta.

• Flexibilidad: De esta forma evitaremos tomar decisiones que queden desfasadas o que no sean útiles frente a cambios que se produzcan en un corto periodo de tiempo.

4.2.2 Requisitos de la representación del grafo de escena

hacerse para solucionarlo. Esto no implica definir la soluciónfo Al analizar el sistema en conjunto, se puede realizar una división para desglosar el sistema en distintas partes bien definidas:

una estructura manejable desde el interfaz de usuario. ue nos perm2. En segundo lugar, estudiaremos un sistema q

automáticamente controles para mostrar la información dgrafo, entre otros.

3. Deberemos definir las acciones que vamos a permrepresentación 3D de la escena.

comúnm5. Veremo

95

Page 97: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

El grafo de escena deberá estar representado en nuestro programa. Esto implica construir una estructura de datos y una imagen del grafo que permita manejar el grafo de escena de OpenSceneGraph, asociando cada uno de nuestros propios nodos con el nodo correspondiente en el grafo de escena. Otro aspecto muy importante será la posibilidad de mostrar múltiples vistas del control en el interfaz de usuario, para aquellos casos en los que trabajemos con grafos muy grandes, y necesitemos trabajar simultáneamente con distintas zonas del mismo. El árbol deberá permitir que el usuario realice distintas acciones sobre él :

• Crear nodos. • Copiar nodos (instanciarlos). • Duplicar nodos. • Mover nodos. • Eliminar nodos. • Arrastrar nodos. • Mover / Copiar / Duplicar nodos entre distintas vistas del árbol. • Posibilidad de copiar/mover/duplicar como:

o Hijo. o Hermano superior. o Hermano inferior.

• Renombrar nodos. También tendremos que tener cuidado a la hora de manipular el grafo, evitando que el usuario pueda generar bucles o colgar nodos de otros donde no esté permitido.

4.2.3 Requisitos de la representación de tipos de datos en el interfaz. Tenemos que encontrar un método sencillo, flexible y lo más genérico posible que nos permita representar la informacion de los nodos y modificarla desde el interfaz de usuario. Hemos descartado directamente crear un diálogo para cada tipo de nodo u objeto a manipular, puesto que va en contra de los principales requisitos del sistema (adaptabilidad, flexibilidad, modularidad). Esto implicará generar de m os para cada tipo de nodo, crear las estructuras de datos adecuadas para poder manipular este tipo de datos, y un

re la representación 3D del grafo.

e presenta el

de un

manipulacion del grafo de escena, este será un punto de gran importancia en el proyecto.

anera dinámica los controles que necesitem

sistema que en encargue de manipular el paso de mensajes, librando al programador de mucho trabajo innecesario, y haciendo su trabajo mas sencillo.

4.2.4 Requisitos de la manipulación sob Nuestra aplicación tendrá una ventana de representación 3D, con el aspecto final qugrafo que estamos manipulando en tiempo real. Se podría manipular el grafo completamente tan solo haciendo uso del control del árbol, no obstante, esto puede ser algo incómodo a la hora dedesplazar objetos por pantalla, por ejemplo, ya que tendríamos que editar las propiedades nodo de transformación y escribir manualmente sus coordenadas exactas donde queremos colocar el objeto en el espacio 3D. Puesto que uno de los objetivos de esta aplicación será hacer más sencillo al usuario la

96

Page 98: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Dflexibilidad puedan darle.

eberemos intentar proporcionar al usuario las herramientas que mayor comodidad y

a historia de las da

ter eces tediosas de reparar, estos sistemas se han

onvertido en una característica casi imprescindible para cualquier software medianamente aceptable, ahorrándonos mucho tiempo innecesario por el hecho de haber cometido cualquier

r

4.2.5 Requisitos del sistema de deshacer / rehacer Hoy día prácticamente cualquier aplicación posee un sistema que almacena lacciones que se van llevando a cabo, de manera que en un momento dado, el usuario pueretroceder o avanzar en esta historia. Puesto que estamos continuamente expuestos a comeerrores, algunas veces irreversibles, otras vc

tipo de error. Por tanto, tendremos que construir un sistema que almacene todas estas acciones, nos permita avanzar y retroceder en la historia, y las estructuras de datos adecuadas para almacenar cualquietipo de acción que se pueda realizar en la aplicación.

4.2 R Los u mpo de jecu ió

vos tipos de Nodo. s de Atributos de Estado.

evos tipos de Objeto. s salidas en la pestaña principal del interfaz de usuario que nos permitirá

camente cualquier aspecto de la aplicación. Nec t stema que nos permita cargar estos fragmentos de código en la memoria de nue iempo de ejecución. Para ello necesitaremos un interfaz común que perm aplicación con todas estos plugins.

.2.6 Requisitos del Manejador de Vista Activa

inar los distintos modulos de la aplicación, y permitir

Este sistema, que actúará como la columna vertebral de la aplicación, deberá ser el encargado

.5 equisitos del sistema de plugins

Pl gins dan a una aplicación la c n.

capacidad de agregar funcionalidades nuevas en tieePuesto que OpenSceneGraph es una librería en continuo desarrollo y ampliación, deberemos poder agregar plugins con nuevos tipos de datos del grafo de escena, entre otras cosas. Más concretamente deberemos de poder desarrollar plugins:

• Con nue• Con nuevos tipo• Con nu• Con nueva

manipular prácti

esi amos un sistro programa en t

ita comunicarse a la

4 Nuestro sistema deberá ser capaz de coorduna comunicación entre ellos.

de:

• Inicializar todas las estructuras de datos globales necesarias. • Inicializar los controles del interfaz de usuario. • Dar acceso a las diferentes escenas (vistas) de la aplicación. • Permitir comunicar unos módulos con otros.

Permitir invocar funciones globales de la aplicación.

97

Page 99: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.3 Análisis.

Figura 4-1. Diagrama de clases de la aplicación

.3.1 Análisis de la repre4

sentación de los datos del grafo en el interfaz

Los nodos del grafo de escena son estructuras de daser oPor ntcon le Vamos na

anera ueremos crear, y a ser posible, indicar con qué tipo de datos stamos tratando.

tos, que a su vez contienen datos que pueden dat s más simples u otras estructuras de datos. ta o vamos a tener que proporcionar un mecanismo mediante el cual generemos los tro s de interacción con el usuario de manera dinámica para cada tipo de dato.

a implementar una estructura de datos que nos permita almacenar o indicar de algulos parámetros que qm

e

98

Page 100: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Para el análisis de este problema nos hemos basado en los Parameter Blocks (bloques de parámetros) que hemos explicado anteriormente que utiliza 3ds max, y los hemos adoptado, aunque de manera modificada y adaptada mas concretamente a nuestras necesidades.

.3.1.1 Grupos de parámetros

Un Grupo de Parámetros identificará un conjunto de parámetros comunes, como puede ser el caso de los parámetros de una estructura de datos más compleja. El grupo de parámetros se representará en el interfaz de usuario como un grupo de controles agrupados, con un botón desplegable que permitirá mostrarlos u ocultarlos. Por tanto, cada uno de estos grupos de parámetros estará compuesto por un conjunto de parámetros, que vendrán identificados en el interfaz de usuario por controles Win32, que llamaremos Descriptores de Parámetros.

4.3.1.2 Descriptores de parámetros

Un descriptor de parámetro describe e identifica de manera única un parámetro, que puede pertenecer a una estructura de datos compleja que estemos manejando en nuestro editor. Cada uno de estos parámetros deberá estar compuesto por:

• El tipo de dato que m

nteros

4.3.1.3 El gestor de parámetros

Llegados a este punto vamos a necesitar un gestor que se encargue de:

• Crear cada unos de estos parámetros en su correspondiente control Win32. • Registrar cada uno de estos parámetros internamente

4

• El nombre o conjunto de nombres del parámetro. aneja.

• Su id que lo identifique de manera única. • El grupo al que pertenece.

Puesto que estamos trabajando con estructuras de datos relacionadas con la informática gráfica, deberemos dar soporte a los tipos básicos de datos y además otros más específicos de este campo. Estos son:

• Entero • Coma flotante • Texto • Booleano • Enumeraciones • Matrices • Color • Vector XYZ • Vector XYZW • Rango de E• Rango en coma flotante

99

Page 101: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Identificar de manera unívoca cada uno de los controles que se asocia a cada parámetro. • Además, este gestor será el que se encargue de procesar los mensajes que genere

Windows al manipular cada uno de los controles, y los pase a quien proceda. En la figura 4.4 podemos apreciar en qué consistiría el proceso de plasmar una estructura de datos Material , que contendría información sobre un material (tipo de color, color ambiental, difuso, especular y de emisión), en un grupo de parámetros utilizando descriptores de parámetros para obtener la salida por el interfaz de usuario.

F r

Ya tene metros en con leparametmecanis permitan consultar el valor de estos datos. Tenemos que relacionar ambas cosas de alguna

anera.

lase virtual pura, que se que

s implementar serán:

igu a 4-2. Ejemplo de un proceso de parametrización de una estructura de datos mediante el gestor de parámetros.

mos analizado un sistema que nos convierte automáticamente grupos de parátro s, y nos gestiona incluso su paso de mensajes. En la figura 4.4 anterior hemos

rizado una estructura de datos Material, no obstante, no existe todavía ningún mo mediante el cual estos parámetros se modifiquen al modificarse en el interfaz o nos

m Aquí es donde surge el concepto de TabOutput, esta clase será una cdeberá implementar para cada tipo de dato que queramos poder parametrizar. Las funcionesdeberemo

• Crear controles: en esta función deberemos indicar los grupos de parámetros que vamos a utilizar.

• Mostrar datos de la clase: Podremos establecer los valores de nuestra estructura de datos en los controles del interfaz.

100

Page 102: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Notificación de evento modificado: Se invocará a esta función cuando un valor del interfaz sea modificado, de esta manera podremos actualizar los datos de nuestra estructura de datos.

Además, nos deberá proporcionar funciones para intercambiar datos con los controles. Estas

5.

funciones de asignar u obtener valores deberán estar sobrecagadas para cada tipo de dato quesoporten los Descriptores de parámetros. De esta manera, el proceso de la figura anterior quedaría como se muestra en la figura 4.

Figura 4.3 Proceso de parametrización y utilización del gestor de parámetros para establecer y obtener

valores, así como para su paso de mensajes.

Pero con esta estructura de datos TabOutput tan solo podemos indicar qué parámetros queremos que tenga nue ra un tipo de datos en concreto, y podemos obtener notificación de que los controles han sido manipulados, y obtener el valor actual del control man omo establecer su valor, pero todavía no tenemos ninguna relación que asocie automáticamente todos estos controles con una instancia en particular del tipo de dato, para así actu z r. En e raph existen 3 clases base que nos interesa diferenciar. Estas son:

• Object: Cualquier tipo de dato que no es ni Node ni StateAttribute.

• StateAttribute: Son los atributos que pueden tener los nodos y otros tipos de datos. Así e derivar 3 tipos de TabOutput: ObjectType, NodeType y AttributeType uno para cada tipo de clase respectivamente. Part m jectType, puesto que Object es la clase base para todo objeto en Ope cEsta distinción nos interesa para poder asociar un objeto a los eventos al TabOutput, y tratar los dato n uario de manera distinta, incluso para manejar algun tipo de evento con to

stro descriptor de grupo pa

ipulado, así c

ali ar su valo

Op nSceneG

• Node: Son los nodos que pertenecen al árbol.

pu s, vamos a

ire os de ObnS eneGraph.

s e el interfaz de uscre .

101

Page 103: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 4-4. Diagrama de clases de los distintos tipos de datos a representar Así por ejemplo, ObjectType nos servirá para parametrizar objetos del tipo Object de OpenSceneGraph. Esta estructura tendrá diferentes particularidades respecto a su predecesor TabOutput, estas son:

• Posibilidad de identificar su tipo de clase padre en el árbol de herencia. Esto permitirá tan solo tener que parametrizar los elementos de una clase sin tener en cuenta su árbol de herencia. Si su padre está registrado como ObjectType y está parametrizado, entonces se mostrarán sus parámetros en la salida de interfaz de usuario, y así de manera recursiva hasta que no exista más herencia. Esto nos ahorrará memoria, y mucho trabajo a la hora de implementar todos y cada uno de los tipos de Nodo, Atributo

de

pe

erá gran flexibilidad a la hora de manipular datos de manera abstracta, y sin

necesidad de tener que saber el tipo de objeto con el que estamos tratando. • Notificacion de Fin de Selección: Esta nueva notificación le llega al ObjectType que

ostrado, para mostrar s de reset en la clase

antes de que se muestre otra.

dicar

y Objeto, puesto que nos evitará tener que parametrizar de nuevo aquellos elementosclases que ya hemos implementado anteriormente, por el hecho de tener parientes en común.

• Posibilidad de vincular / desvincular otro ObjectType para poder tener acceso a sus datos y a su paso de eventos, de esta manera podremos manipular otros tipos de dato que pertenecen a un dato concreto. Podremos mostrar u ocultar la salida del ObjectTycuando nos convenga. Esto implica recibir notificaciones de eventos del ObjectType vinculado.

• Crear una nueva instancia del tipo de dato que estamos manejando. Esta característicanos ofrec

está siendo editado para indicar que el objeto va a dejar de ser men su lugar otro ObjectType distinto. Esto permite realizar ajuste

La clase NodeType y AttributeType solo diferirán de ObjectType en su constructor (para inque es un objeto tipo NodeType o AttributeType respectivamente). La clase AttributeType permite además asignar el tipo de StateAttribute con el que estamos tratando. Ahora, cuando obtengamos una notificación de que un parámetro ha sido modificado, obtendremos también un puntero a la instancia del elemento que estamos modificando, para que nosotros actualicemos el valor en función de nuestros requisitos. Esto no permitirá desarrollar los tipos de objeto de una manera mucho más rápida, y nos facilitará el posterior proceso de adaptación a la arquitectura de plugins de la aplicación.

102

Page 104: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.3.1.4 Objects, Nodes, y AttributeTypes en OpenSceneGraph

El objetivo de las clases ObjectType, NodeType y AttributeType es parametrizar los tipos de datos necesarios para manipular los datos del grafo de escena de OpenSceneGraph desde el editor. Para cada uno de este tipo de datos, deberemos crear un ObjectType, NodeType o AttributeType según proceda. Puesto que existen gran variedad de estos datos, vamos a implementar solo los que consideramos más importantes, estos son: Nodes:

• Billboard • DOFTransfor• Emitter

• Group • Impostor • LightSource • LOD

• MatrixTransform

Projection • Sequence • Switch • Transform

StateAttribute’s :

• BlendFunc • Fog • FragmentProgram • Light • Material • TexEnv • TexGen • Texture • Texture2D

• Counter

• RandomRateCounter

• VariableRateCounter

m • Emitter • Node

• BumpMapping • Cartoon • Effect

• PagedLOD • ParticleProcessor • ParticleSystemUpdater

• SpecularHighlights • Geode

• PositionAttitudeTransform •

Object’s necesarios, utilizados por los Nodes y StateAttributes:

• ConstantRateCounter

• Drawable • StateSet

Geometry • Particle • ParticleSystem

• ShapeDrawable • Text

103

Page 105: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.3.1.5. El Gestor de ObjectTypes, NodeTypes y AttributeTypes.

Cada vez que desarrollemos un nuevo tipo de dato Object, Node ó StateAttribute deberemos gistrarlos globalmente en el sistema para saber en todo momento que tipos de datos están

ato, sin

pes.

reimplementados y cuales no lo están. Esto sirve tanto para mostrar por el interfaz de usuario un tipo de dato que queramos mostrar, como para crear nuevas instancias de este tipo de dnecesidad de conocer el dato que estamos manipulando. De aquí surgen el Gestor de ObjectTypes, el gestor de NodeTypes y el gestor de AttributeTy

Figura 4-5. Herencia de clases de una clase tipo Object, Node y StateAttribute de OpenSceneGraph.

Viendo la figura 4.7 muestra un ejemplo de la herencia de objetos en OpenSceneGraph. A la izquierda podemos ver por ejemplo la clase Geometry de OpenSceneGraph, que clasificaremos como ObjectType dentro de nuestro editor, que deriva de la clase Drawable. Si ahora queremos parametrizar esta clase, tan solo tendremos que hacerlo con los parametros propios de Geometry, e indicaremos en el constructor del ObjectType que el nombre de la clase padre es Drawable. Aquí entra en juego el gestor de ObjectTypes, comprobando que existe ya este tipo de objeto registrado y realizará una llamada a la función de mostrar datos al mostrar los de la clase Geometry.

.3.2 Análisi

aneja OpenSceneGraph es el grafo de escena, el grafo de sce d a manera que nos permita

man tura de datos y una imagen del graf u SceneGraph desde el editor, asociando cad n El p l un control de la API de Windows. Puesto que e control para poder representar este o

plementación, haremos uso de los controles que la API de win32 nos proporciona, por lo que

4 s de la representación del grafo de escena

uesto que la estructura de datos que mPe na eberá estar representado en nuestro programa de algun

ruir una estrucipularlo y trabajar con él. Esto implica consto q e permita manejar el grafo de escena de Opena u o de nuestros propios nodos con el nodo correspondiente en el grafo de escena.

rob ema surge a la hora de representar el grafo en no s uno de los objetivos principales crear un nuevo tipo de tip de estructuras en la interfaz de usuario, debido al tiempo que podría llevar su estudio e

immostraremos el grafo en forma de árbol (concretamente un TreeCtrl).

104

Page 106: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 4-6. Equivalencia entre la representación de un grafo y un árbol.

La principal diferencia entre el árbol y el grafo de escena es que un nodo puede tener más de un padre, la solución a esto es representar el nodo en un árbol duplicando estas ramas tantas veces como padres tenga. Por tanto, deberemos indicar de alguna manera al usuario en el interfaz de usuario que un nodo está instanciado de manera múltiple.

Figura 4-7. Representación de los enlaces en las estructuras del editor

Puesto que c a estar representado en varios elementos del árbol (aunqu o del grafo) necesitamos tener el grafo dup d os “Nodo”, que llamaremos Tre

a manera o nodo.

enSceneGraph.

Del s r. Esto lo

4.3.2.1 Crear un árbol a partir de un grafo

ad uno de los nodos del grafo puedtificado con un solo nodo

ee s lo esté iden

lica o en nuestro editor, usando nuestra propia estructura de dateNodeInfo, y que contendrá:

• Enlaces a sus padres y a sus hijos Enlaces a los distintos elementos del árbol (su• s múltiples instancias). De estsabremos inmediatamente las distintas instancias de un mism

• Enlace a su nodo equivalente en el grafo de escena de Op• Enlace al NodeType correspondiente a ese tipo de nodo.

mi mo modo, cada elemento del árbol mantendrá un puntero a su nodo del grafo del edito

podemos ver reflejado en la figura 4.3.

105

Page 107: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Ya clonado construy OpenSceneGraph define la clase NodeVisitor que nos permite recorrer completamente un grafo siguiendo ciertos criterios. En nuestro caso construiremos un NodeVisitor que recorra absolutamente todos los nodos del grafo es escena, guardando un vector con la información de cada uno de los nodos que hemos encontrado encapsulados en nuestra propia estructura de datos, y su relación de sus padres e hijos.

1. Recorrer el grafo completamente y obtener información de todos sus nodos usando un NodeVisitor a la vez que vamos insertando elementos en el arbol. Esto es posible gracias a que NodeVisitor realiza un recorrido recursivo, siguiendo el orden de los nodos.

2. A partir de este vector de elem a los padre lonado).

en las vistas TreeCtrl conteniendo el árbol del grafo de escena el e to

hemos analizado las estructuras de datos adecuadas para tener nuestro grafo de escenay relacionado con su representación de árbol, ahora necesitamos un método que a dicho grafo y dicho árbol.

entos obtenido asignamos los punteros apropiadoss y a los hijos, obteniendo asi una estructura de grafo (nuestro grafo c

4.3.2.2 Mostrar el grafo en múltiples vistas de árbol

Aunque puede parecer sencillo, esta no es una tarea trivial. Para ello crearemos una nueva estructura de datos, que llamaremos MultiTreeBar, que será como un gestor de ventanas de tipo

reeBar, que son las que contienTd di r (uno por cada escena, ver Figura 4.8).

Figura 4-8. Diagrama de clases relacionado con la vista múltiple del grafo

MultiTreeBar nos debe permitir :

• Crear (clonar) una nueva imagen del árbol (TreeBar). • Establecer y obtener el TreeBar activo.

escena activa. • Obtener el número de TreeBar de cada árbol.

a árbol. cualquier TreeBar.

a de cualquier TreeBar sobre un nodo de cualquier otro. Cab c e diferenciar entre escenas y TreeBars. Una escena identifica un grafo de escena, equivaldría a un TreeCtrl. Un TreeBar identifica un conjunto de

• Establecer y obtener la

• Obtener el número de escenas de cad• Copiar al portapapeles una rama de • Pegar del portapapeles una ram

e a larar una cosa, y es que tenemos qu

106

Page 108: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

escenas más de una, sería imágenes clonadas las escenas de otra TreeBar. Así e s TreeBars.

, que, en caso de haber pu s, una escena puede estar clonada en vario

Figura 4-9. Ejemplo de MultiTreeBar para con dos escenas y tres vistas simultáneas.

La figura 4.9 Muest n licando la relación de MultiTreeBar con TreeBar y las distintas escenas que puede contener en el editor.

.3.2.3 Acciones o

• Cambiar el nombre de un elemento

fo) desde el portapapeles sobre cualquier nodo grupo de cualquier TreeBar (instanciado o duplicado).

• Seleccionar múltiples elementos del árbol simultáneamente

ptos que ya hemos utilizado:

o por todos sus padres.

ra u gráfico exp

4 s bre el árbol

Vamos a poder permitir distintas acciones directamente sobre el árbol:

• Eliminar un elemento • Crear un nuevo elemento de los tipos registrados por el Gestor de NodeTypes. • Crear un nuevo elemento a partir de un fichero guardado en disco. • Arrastrar un elemento moviéndolo o copiándolo (nodo instanciado)

o Como hermano superior de otro o Como hermano inferior de otro o Como hijo

Crear un nodo duplicado en lugar de un nodo instanciado. • Copiar o cortar una rama al portapapeles • Pegar un nodo (y su subgra

Debemos aquí introducir dos conce

• Nodo instanciado: Consiste en añadir un nodo a múltiples padres. Cuando un nodo tiene dos o más padres lo denominaremos instanciado compartido. Si un nodo está instanciado, todo su subgrafo lo estará también. Puesto que cada padre comparte el mismo nodo, cualquier cambio hecho al nodo, será apreciable del mismo mod

107

Page 109: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Nodo duplicado: consiste en duplicar el contenido del nodo, de manera que sea de cada uno de estos nodos duplicados será asignado a un solo padre. El contenido

independiente de los demás.

Figura 4-10. Los dos métodos de instanciado y duplicado posibles en el editor.

4.3.2.4 Mostrar la información de un nodo del grafo

sos:

mos los

tro

el diálogo (su Grupo de parámetros) asociado al NodeType.

odeType y mostramos los valores de sus parámetros en los controles del diálogo.

4.3.3 Análisis de la interacción con el visor del editor Ya hemos analizado la representación en árbol del grafo, y como mostrar y poder manipular los parámetros de los nodos y de otros tipos de datos. También dispondremos de un visor con el resultado en tiempo real del grafo de escena. Es decir, cualquier cambio realizado sobre los parámetros de los nodos, o sobre la estructura del grafo en sí (manipulando el árbol), se verá automáticamente reflejado en el visor. El visor nos debería permitir:

• Seleccionar objetos usando el ratón. • Desplazar objetos usando el ratón. • Rotar objetos usando el ratón. • Escalar objetos usando el ratón. • Duplicar objetos usando el ratón.

Cuando un usuario seleccione un nodo del control de árbol, se mostrará en el interfaz de usuario siguiendo los siguientes pa

1. Si el NodeType del nodo a mostrar no ha creado todavia sus diálogos, indicamos al gestor de parámetros que los cree recursivamente (recorriendo su árbol de herencia).

2. Si existía ya un nodo mostrado en pantalla a. Si el tipo de nodo a mostrar es distinto que el que existía, oculta

controles del antiguo NodeType y mostramos los del nuevo. b. Además, si los nodos asociados a los respectivos NodeTypes son distintos,

notificamos Fin de Selección al NodeType, puesto que vamos a mostrar onodo distinto.

3. Sinó, simplemente mostramos el contenido d

4. Asignamos este nodo como el nodo actual asociado al N

108

Page 110: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Enfocar a un objeto. • Mover / Rotar la cámara usando el ratón. • Mostrar la vista anterior y posterior de una escena. • Mostrar la vista superior e inferior de una escena. • Mostrar la vista izquierda y derecha de una escena. • Mostrar una representación en alambre de la escena. • Mostrar una representación sólida de lo objetos. • Mostrar un sombreado plano de la escena. • Mostrar un sombreado suavizado de la escena.

4.3.3.1 El gestor de selección

El gestor de selección será una estructura que gestione los objetos que hay visualmente seleccionados en el visor, y presentará distintas funcionalidades:

o Encontrar los objetos que intersecten con el puntero o Establecer la selección actual o Consultar elementos seleccionados. o Se encargará de actualizar las cajas de selección. o Se encargará de actualizar el eje manipulador. o Procesará los eventos del ratón sobre el visor. o Gestionará las operaciones aplicables a una selección:

Traslación Rotación Escalado Duplicado Borrado

Puesto que un objeto puede identificarse como múltiples instancias en un mismo nodo del grafo os elementos del árbol

que ocupen.

uelve

neGraph de identificar de manera única un nodo instanciado.

El e ue permitir illa e intu a modelado 3D.

del ratón.

de escena, los objetos de la selección vendrán identificados por los distint

Cuando pulsemos en pantalla para seleccionar un objeto, tendremos que hallar el nodo seleccionado del grafo. La clase IntersectVisitor de OpenSceneGraph nos da la posibilidad de hallar la intersección de una linea con los distintos objetos de la escena. Esta clase nos devuna lista de los NodePath objetos intersectados en orden de proximidad al observador. Un NodePath es un vector de nodos, representando el camino que se ha seguido por el grafodesde la raíz hasta llegar al un nodo descendiente, en este caso un nodo hoja. El NodePath es la manera que tiene OpenSce Por tanto, tendremos q crear un método por el cual obtengamos un elemento del árbol a partir del NodePath del grafo de escena.

4.3.3.2 El eje manipulador

je manipulador no es más que una representación visual de los tres ejes de coordenadas, q

án al usuario realizar transformaciones sobre los objetos de manera muy sencitiv . Este manipulador es muy común en los últimos editores de

109

Page 111: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

De esta transfor

4.3.3.3 Creación automática de Matrices de Transformación

En OpenSceneGraph son necesarias las matrices de transformación (MatrixTransform) para aplicar cualquier transformación a un objeto del grafo. Para ello, la matriz debe estar por encima del objeto a transformar. Por tanto, en el caso de que pulsemos un objeto y lo seleccionemos, e intentemos aplicarle alguna transformación, en el objeto no se apreciará ningun cambio a no ser que exista alguna matriz de transformación asociada al nodo. La solución pues, consiste en crear automáticamente una matriz de transformación como padre del objeto que acabamos de seleccionar. El problema surje cuando, al seleccionar un objeto y crear automáticamente su MatrixTransform, añadimos otro hijo a esta matriz. En ese caso, cuando intentemos transformar el primero objeto de nuevo, la transformación afectará al segundo objeto que he os añadido.

transformación como padre del objeto y además

manera se agiliza a la hora de realizar maciones sobre uno o dos ejes simultáneamente.

Este eje se mostrará siempre en el centro de la selección, y será el gestor de selección el encargado de actualizarlo.

Figura 4-11. Eje manipulador en 3ds max (conocido como translate guizmo).

mLa solución a esto es comprobar siempre, al seleccionar un objeto, si existe la matriz de

solo tiene un hijo. En caso contrario, tendremos ue crear una matriz nueva justo encima del objeto.

q La figura 4-12 explica visualmente la solución a este problema.

110

Page 112: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 4-12. Creación automatica de la Matriz de Transformación para la selección de objetos.

1. Tenemos dos objetos sin nimguna matriz de transformacion.

2. Seleccionamos la piramide, entonces se crear una matriz

como su

4.3.3.4 Traslación de o

odificar la traslación de un objeto, tan solo toman las coord

3. n plano imaginario en función de los ejes

de transformacionpadre (MT1).

bjetos usando el eje man

Vamos a hacer un análisis profundo sobre la traslación de obpuesto que queremos que esta sea lo más intuitiva posible. Amaplican al eje que estemos modificando. Esto da como resultarealista, incluso desde algunos puntos de vista de la cámara ppuede hasta ocurrir que el desplazamiento del objeto en el visdesplazamiento del ratón. Sin embargo la mayoría de editores comerciales se han preococurra. Si queremos desplazar un objeto, el objeto irá justo dPuesto que el eje manipulador solo permite seleccionar comosimultáneamente, sabremos exactamente donde desplazar el oimaginario formado por estos dos ejes y la intersección entreratón con la perpendicular a la pantalla, y dicho plano.

1. Partimos de un punto de la pantalla que representa laratón, este punto representará el punto donde querem

2. Debemos convertir ese punto en una línea en el espacHallamos upase por el centro del objeto que queremos modificar

3. Copiamos el cubo como hijo

de este nodo MT1.

4. Al seleccionar el cubo, comprobamos que existe una Matriz de Transformacion como padre del mismo, pero no es el único hijo, por tanto repetimos la misma operación que en el paso 2. Y lo mismo ocurrirá cuando seleccionemos la pirámide.

or

jetos usando el eje manipulador, lgunos de los editores que permiten enadas X e Y del ratón y las

co eces

l

o

.

que estamos modificando, que

ipulad

do un comportamiento pouede ser incómodo, y a vor sea justamente el contrario de

upado bastante más en que esto nonde vaya el puntero del ratón. máximo dos ejes bjeto a lo largo de un plano

la linea que forma el puntero del

posición actual del puntero del os desplazar el objetoio 3D

.

111

Page 113: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4. Hallaremos la intersección de esa línea con el plano imaginario que acabamos de endo un punto en el espacio 3D.

5. Moveremos el objeto seleccionado hasta ese punto.

o el objeto exactamente donde uiere. En la figura 4-13 podemos ver una imagen que representa visualmente el algoritmo xplicado.

calcular, obteni

De esta manera el usuario tendrá la sensación de estar moviendqe

Figura 4-13. Cálculo de la posición 3D de un objeto en el plano ZY en función de las coordenadas de pantalla.

.3.3.5 Representación de objetos independientes a la escena del editor

l objetivo del editor es construir un grafo de escena con todas las herramientas que el editor

en el grafo, ya que son necesarios por el editor, el usuario no ebe de ser consciente de tales elementos existen, y su grafo tan solo está compuesto por

Existen dos posibilidades a esta situación, la primera consistiría en insertar estos elementos en nuestro grafo duplicado, anadiendo un identificativo de que son datos auxiliares, es decir, utilizados por el editor, y de los cuales el usuario no debe ser consciente. De esta manera, al procesar los datos, o al mostrarlos en el árbol del editor, estos no se deberán mostrar. Esta solución presenta diversos problemas, ya que, existen algunas funciones propias de OpenSceneGraph, como puede ser el recorrido que realiza el NodeVisitor, que no nos permite acceder a estos datos, puesto que el recorrido se realiza en el propio grafo que posee internamente OpenSceneGraph, y no sobre nuestro grafo duplicado, que es el que contendría la informacion que necesitamos. Esto se podria solucionar implementando nuestra propia clase NodeVisitor, pero supondría un coste bastante alto.

4

Eproporciona, cualquier elemento que vayamos añadiendo o modificando en el grafo se verá automáticamente reflejado en el visor, sin embargo, al seleccionar objetos en pantalla, o al introducir elementos auxiliares (como puede ser el Eje Manipulador), hay que insertar elementos en el grafo. Estos elementos deben ser transparentes al usuario, de manera que, aunque estos elementos existandaquellos nodos que él ha decidido.

112

Page 114: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Además, todas las funciones de copiado de nodos, que se realizan de manera recursiva, tendrian que ser modificadas, complicandose bastante. La otra solución que será la que adoptemos, consistirá en dividir la raiz del grafo de escena en dos grupos, el primero será el grupo de datos auxiliares, de donde colgará toda la información que necesitemos para representar datos auxiliares, y en otro grupo que será él grafo de escena que el usuario verá. Por tanto, el editor, en lugar de mostrar el grafo entero en la vista del árbol, mostrará solo el nodo de la escena, que será el que contenga todos los datos que esté manipulando el usuario. La figura 4-14 muestra la estructura que tomará el grafo para esta segunda solución.

Figura 4-14. Estructura del grafo del editor.

4.3.4 Análisis del sistema deshacer / rehacer. Nec t lmacene todas las posibles acciones inve b avanzar y retroceder en la historia. Este b uier tipo de acción, de manera flexible. Por t s adecuadas para ello. El c cUsarem modificaciones en los datos de nuestra aplicación que se realizan agrupados como uno solo, es decir, de manera única e indi iPor ejem a acción, pero mover 15 objetos simultáneamente es tam implique realizar 15 movimientos de dist Sabiendo es c s:

• Eje a nera indivisible la acción. • Obtene : devolver una cadena con el nombre representativo de

la a• Deshacer: Aquí irá el código que invierta la acción ejecutada.

esi amos construir un sistema de historia que arti les de nuestra aplicación, que nos permita de e ser un sistema que permita almacenar cualq

ato tan o deberemos analizar unas estructuras de d

on epto de Acción os este término para referirnos al conjunto de comandos o

vis ble. plo, mover un objeto puede ser un

bién una acción indivisible, aunque internamenteintos objetos.

to, rearemos una clase virtual pura con las siguientes funciones virtuales puracut r: Aquí irá el código que ejecute de ma

r el nombre de la accióncción.

113

Page 115: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

El gestor de Hi Será el enca d s y/o rehacerlas. Esta clase deberá man ción actual de la historia.

4.2.7 Aná i

omo ya hemos mencionado anteriormente, basaremos este sistema en el sistema que utiliza ds max, con algunas modificaciones.

el plugin y el sistema. La clase que utilizaremos para los plugins erá TabOutput, que la cual hemos analizado anteriormente. Por tanto, en un plugin podremos

implementar tanto TabOutputs como ObjectTypes, AttributeTypes y NodeTypes.

Las siguientes funciones deben ser implementadas por los desarrolladores de plugins del editor. Todas las funciones deberán estar precedeidas de la directiva __declspec(dllexport). Estas funciones son invocadas por el gestor de plugins y proporcionan información sobre la DLL cargada y las distintas clases del plugin que contiene. Estas funciones son:

LibNumClasses(): Devuelve el numero de clases que hay implementadas dentro del plugin.

LibClassInstance(i): Devuelve una instancia de la clase i-ésima que hemos implementado.

LibDescription(): Devuelve una cadena descriptiva sobre la DLL.

LibVersion(): Constante que identifique la version del editor sobre la que se ha realizado el plugin, esto permitirá al editor identificar plugins obsoletos.

Aquí no necesitamos implementar la funcion DllMain() que usaba 3ds max, puesto que estamos creando DLLs de MFC y esta se realiza internamente. El gestor de plugins Es el encargado de cargar los plugins del directorio de plugins. Se encarga de establecer la comunicación con la DLL, comprobar su versión, y obtener una instancia de cada una de las clases implementadas, almacenandola según su nombre, y guardando una asociacion al manejador de la DLL de la cual proviene, y procesándolas para mandarlas al Gestor del tipo de clase apropiado según su tipo. La figura 4-15 ilustra gráficamente el funcionamiento del gestor de plugins.

storia

rga o de almacenar las acciones, ejecutarlas, deshacerlatener un puntero a la posi

lis s del sistema de plugins. C3Escribir un plugin implica crear objetos a partir de las clases e implementar métodos para permitir la comunicación entre s

114

Page 116: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 4-15. Funcionamiento del gestor de plugins.

nális

os d nte, para que todo esto funcione de manera conjunta, necesitamos ma que s distintos modulos de la aplicación, y permcación ializar los datos necesarios en el editor, asi e

escena. istema ac lumna vertebral de la aplicación.

ontendrá

Una in estor de historia. na inna inna in ypes. na inna inna inna inna inna rena reefere . uncioo datos pertinentes al abrir una eso una escena o o

4.2.8 A is del Manejador de Vista Activa

hemComo icho anteriormeun siste

ni sea capaz de coordinar lo

i como inicitir una

comucada

entre ellos, as como los d

Este s túará como la co Este c :

• stancia del G• U stancia del Gestor de TabOutputs. • U

Ustancia del Gestor de Parámetros.

• stancia del Gestor de AttributeT• U stancia del Gestor de ObjectTypes. • U•

stancia del Gestor de NodeTypes. ables (Bars). U

• Ustancia del Gestor de ventanas dockstancia del Gestor de plugins.

• U stancia de MultiTreeBar. • U ferencia a la escena activa. • U ferencia al visor de la escena activa. • R ncia a la raíz del grafo de escena activo• F nes de ámbito global:

Crear e inicializar las estructuras de cena Liberar memoria al cerrarCambiar la vista activa Guardar la escena actual en disco

115

Page 117: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

o pes, Nodetypes y AttributeTypes iniciales en

o plugins. o anas dockables de la aplicación. o . o o el arbol o o rmación de un Nodo del grafo.

igura 4-1 senta la funcionalidad del manejador de vista (Active

Inicializar los ObjectTy la aplicación. Inicializar losInicializar las vent

l árbolInicializar eInsertar nodos en el arbol Copiar nodos dEjecutar una acciónMostrar la info

En la f 6 se puede ver un dibujo que re

View Handler). pre

activa

Figura 4-16. Esquema general de la arquitectura del sistema.

116

Page 118: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.4 sos d

s de ma.

Ca e uso

.4.1 Funcione l siste4 Referencia Nombre función Categoría F.1 plicación Iniciar a Evidente F.1.1 Iniciar Barras Oculta F.1.2 Crear barra de paneles de comandos Oculta F.1.3 Iniciar Tipos de objeto Oculta F.1.4 Registrar un TabOutput Oculta F.1.5 Registrar un ObjectType Oculta F.1.6 Mapear los grupos de parámetros de un TabOutput Oculta F.1.7 Cargar Plugins Oculta F.2 Cerrar aplicación Evidente F.2.1 Cerrar TreeBar Evidente F.3 Cerrar Escena Evidente F.4 Cargar E e scena EvidentF.4.1 Establecer un grafo sobre un elemento del árbol Oculta F.4.2 Replicar una escena de una TreeBar a otra Oculta F.4 C a partir de otro Oculta .3 lonar un TreeCtrl F.5 Nueva Escen Evidente a F.5.1 Cr afo por ear gr defecto Oculta F.6 Nuevo árbol Evidente F.7 Insertar fichero Evidente F.8 Cambiar escena activa Evidente F.9 Deshacer Evidente F.10 R Evidentehacer e F.11 Crear Nodo Evidente F.11.1 Crear un deType Oculta nodo según el nombre de su NoF.11.2 Crear nueva instancia de un nodo según su nombre Oculta F.12 Seleccionar elemento en árbol Evidente F.12.1 Seleccionar todas las instancias de un elemento Oculta F.1 S Oculta 2.2 eleccionar todos los “mirrors” de un elemento F.12.3 Mostrar la información de un nodo Evidente F.12.4 Cr diálogear los os de un TabOutput Oculta F.12.5 Crear u dialogo an partir de un grupo de parámetros Oculta F.12.6 Generar el contenido de un TabOutput Oculta F.12.7 Vaciar el contenido de un TabOutput Oculta F.12.8 Notificar fin de selección de un ObjectType Oculta F.12.9 Mostrar los datos de un TabOutput Oculta F.13 Seleccio nar nodo en visor EvidenteF.13.1 Agregar nodo a la selección del visor Evidente F.13.2 Crear Matriz de Transformación como padre de un nodo Oculta

117

Page 119: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.13.3 Actualizar la selección Oculta F.13.4 Actualiz Oculta ar el eje manipulador F.14 Copiar nodo Evidente F.14.1 Replicar selección Evidente F.1 M Evidente 5 over nodo F.1 Duplicar nod Evidente 6 o F.16 Duplicar selección Evidente F.17 inar nodo Evidente ElimF.18 Activar modo selección Evidente F.19 Activar modo traslación de objetos Evidente F.20 odo escActivar m alado de objetos Evidente F.21 Activar odo rotación objetos Evidente mF.22 A odo rotar vista Evidente ctivar mF.23 Activar modo trasladar vista Evidente F.24 Escalar selección Evidente F.24.1 Comenzar escalado de selección Oculta F.24.2 Realizar escalado de selección Oculta F.24.3 Finalizar escalado de selección Oculta F.2 R Evidente 5 otar selección F.25.1 Comenzar rotación de selección Oculta F.25.2 Re rotacióalizar n de selección Oculta F.25.3 Finaliza rotación r de selección Oculta F.26 Trasladar selección Evidente F.26.1 ar traslac Comenz ión de selección Oculta F.26.2 Realizar traslación de selección Oculta F.26.3 Finalizar traslación de selección Oculta F.27 Centrar vista en selección Evidente F.28 Modificar el zoom de la vista Evidente F.29 Añadir StateAttribute a StateSet Evidente F.30 Eliminar un StateAttribute de un StateSet Evidente F.31 Añadir un Modo a un StateSet Evidente F.3 E t Evidente 2 liminar un Modo de un StateSeF.3 Modificar Evidente 3 un Modo de un StateSet F.34 Mo r parámdifica etro de un control del panel de comandos Evidente F.34.1 Establecer el valor de un parámetro Oculta F.34.2 Obtener el valor de un parámetro Oculta F.35 Establecer el contenido del portapapeles Evidente F.36 Pegar el contenido del portapapeles Evidente F.37 Visualizar escena en modo de alambre Evidente F.38 Visualizar escena en modo relleno Evidente F.39 Visualizar sombreado en modo plano Evidente F.40 Visualizar sombreado en modo suavizado Evidente F.41 Mostrar vista superior de la escena Evidente F.42 Mostrar vista inferior de la escena Evidente F.43 Mostrar vista anterior de la escena Evidente F.4 Mostrar vista posterior de la esc Evidente 4 ena F.4 M Evidente 5 ostrar vista lateral izquierda de la escena F.46 Mo vista latstrar eral derecha de la escena Evidente

118

Page 120: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.4.2 Descripción de alto nivel de los Casos de Uso.

F.1 Iniciar la aplicación. Caso de uso: Inicio

Usuario.

Evidente.

Actores:

ipo:

escripción: Se realiza esta función o secuencia de funciones, cuando el usuario único objeto global de la

ctiveViewHandler), y generará una vista vacía, la cual

el ActiveViewHandler arranque iniciará todos los gestores de la crearan las barras de herramientas (la principal y la de

e nodos) iniciará la barra principal de paneles de comandos y el árbol que contendrá la representación del grafo, y además iniciará los

datos que soporta la aplicación añadiéndolos a sus respectivos

T D

arranca la aplicación, la cual iniciará el aplicación (Ainiciará los datos del grafo por defecto.Cuandoaplicación, secreación d

tipos de gestores. Es en esta fase donde se realizará también la carga de los plugins.

F.1.1 Iniciar Barras. Caso de uso: Inicio

Usuar

ctores: io.

ipo: Oculta.

a aplicación, crea la barra aneles de comandos, la barra de depuración,

e escena.

A T Descripción:

principal que contiene los py el árbol del grafo d

Esta es la función que invoca al iniciar l

F.1.2 Crear paneles de comandos. barra de Caso de uso: Inicio

Usuario.

Oculta.

Actores: Tipo:

escripción: Esta función es invocada por la función de iniciar las barras. En concreto inicia el panel principal de comandos que consta de cinco pestañas, cada una con una funcionalidad característica en la aplicación, asignando un icono representativo a cada una de ellas. Inicialmente el contenido de estas páginas será propertysheets vacíos,

D

119

Page 121: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

que mas adelante serán rellenados con diálogos desplegables q serán los que contendrán los controles.

F.1.3 Iniciar tipos de objeto. Caso de uso: Inicio

Actores: Tipo: Descripción: ntre

se cargan al iniciarse, así como los tipos de objeto soportados por el editor, los tipos de nodo y los StateAttributes.

Usuario.

Oculta.

En esta función se crean las instancias de los TabOutput iniciales, elos que se encuentra el panel de plugins, los cuales

F.1.4 Registrar un TabOutput.

Caso de uso: Inicio Actore Usuario. s:

Descripción:

o.

Tipo: Oculta.

Esta función registra un objeto tipo TabOutput en la aplicación. Esta función añade a sus tablas internas la referencia a esta nueva instancia a registrar, y la indexa por su nombre, y por ultimo realiza una llamada a la función de mapeo de los grupos de parámetros que tenga el objet

F.1.5 Registrar un ObjectType. Caso uso: de Inicio

ctores: Usuario.

ipo: Oculta.

escripción: Esta función registra un objeto tipo ObjectType en la aplicación. Añade internas la referencia a esta nueva instancia a registrar, y la

indexa por su nombre, además averigua el ObjectType de su padre (si a

A T D

a sus tablas

lo tiene) y le asigna el enlace pertinente. Por ultimo realiza una llamada la función de mapeo de los grupos de parámetros que tenga el objeto.

F.1.6 Mapear los grupos de parámetros de un TabOutput. Caso de uso: Inicio

120

Page 122: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Actores: Tipo: Descripción:

ámetros asociando como clave en descriptor en sí. De esta manera tenemos una tabla hash que asocia Ids de parámetros con sus respectivos descriptores.

Usuario.

Oculta.

Esta función se invoca al registrar un TabOutput, ObjectType, NodeType o AtributeType. Realiza la llamada a la creación de los grupos de parámetros del TabOutput en cuestión. Una vez hecha, se mapea en la tablas hash el id de cada uno de sus descriptores de los grupos de par

F.1.7 Cargar Plugins.

Caso de uso: Inicio Actore Usuario.s:

Descripción:

ión

otro es la pestaña de visualización de plugins. Este o de

ne cada

Tipo: Oculta.

Al iniciar la aplicación se realiza una llamada a Iniciar los tipos de objeto, entre ellos los TabOutput con los que cuenta la aplicacinicialmente. Uno de ellos es el creador de nodos, disponible en la primera pestaña, yTabOutput es quien, al iniciar, realiza el “escaneo” del directoriplugins, el gestor de plugins los guarda en sus tablas y se encarga de cargarlos en memoria, una vez cargados, los objetos que contieplugin las distribuye entre sus distintos gestores de elementos, según sutipo.

F.2 Cerrar aplicación. Cas uso: Cerrar aplicacióno de

ctores: Usuario.

ipo: Evidente.

escripción: Al cerrar la aplicación se realizan llamadas a Cerrar para todos los TreeBar contiene el árbol del

grafo de escena de una o varias escenas, se cierran estas escenas, que s

dos

A T D

TreeBar del programa. Puesto que cada

implican liberar sus recursos, así como se vacía toda la historia de todalas escenas. Del mismo modo, se liberan todos los recursos adquiripor la librería OpenSceneGraph.

121

Page 123: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.2.1 Cerrar treebar

aso de uso: Cerrar aplicaciónC

ctores: Usuario.

ipo: Oculta

escripción: Al cerrar un único TreeBar tendremos que liberar tan solo la memoria r que

S

A T D

referente a los mirror de las escenas actuales. Dado que la TreeBaestamos cerrando no es más que una copia de la original, todas sus escenas lo son, por tanto, deberemos eliminar tan solo las referencias que contiene cada nodo del grafo de la aplicación a los HTREEITEMcorrespondientes, puesto que ya no van a existir más. Por ultimo, deberemos eliminarla de la lista de MultiTreeBar

F.3 Cerrar escena.

aso de uso: Cerrar escenaC

ctores: Usuario.

ipo: Evidente.

escripción: Esta función se invoca al cerrar una vista de la escena. Por tanto, a de

el

A T D

deberemos vaciar la selección actual, liberar los recursos de la escenOpenSceneGraph que todavía queden sin liberar, vaciar la historia deesta escena (cada escena tiene su propia historia). Al cerrar la escena se deberán eliminar todos los árboles de esta escena pertenecientes a cada una de las TreeBar, así como limpiar cualquier información deúltimo nodo que se seleccionó y pueda estar representado en pantalla para evitar que el usuario intente modificarlo después de haberse liberado de la memoria.

F.4 Cargar escena. Caso de uso: Cargar escena

ctores: Usuario.

ipo: Evidente.

escripción: Cargar una escena implica seleccionar un fichero del disco duro. Una o, se realizará la carga del fichero mediante las funciones que

proporciona OpenSceneGraph de carga de ficheros. Seguidamente se

colgaremos el fichero que acabamos de cargar, y en la segunda

A T D

vez hech

iniciará un grafo por defecto para colgar esta información. El grafo no deberá ser el fichero en sí, puesto que el editor necesita más elementos para visualizar de manera axiliar. Por tanto, el grafo inicial estará dividido en dos ramas principales, la primera será la escena donde

122

Page 124: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

almacenaremos aquellos nodos que nos serán útiles en el editor para manipular otros nodos, como puede ser el eje manipulador, las cajas de selección de objetos, e incluso la rejilla. Una vez hecho esto, deberemos añadir una nueva escena al editor, esto implica crear nuestro propio grafo de escena (copia del de

eGraph), y añadir un nuevo control de árbol en cada una de las TreeBar, clonando su contenido tantas veces como sea necesario.

será donde inicialicemos los datos de la selección, y el StateSet global, que nos servirá para cambiar el modo de visualización

na.

OpenScen

También aquí

de la esce

F.4.1 Establecer un grafo sobre un elemento del árbol. Caso de uso: Cargar escena

Usuario. Actores:

ipo: Oculta.

Descripción: lecer un grafo colgando de un elemento de un árbol. Este elemento puede ser la raíz del árbol, por lo que el árbol no debe

tener algún elemento. Esta función internamente a sobre una de las vistas del árbol

do que haya varias simultáneas) y realiza réplicas del mismo más.

er el grafo y construir el árbol se utiliza la estructura proporcionada por OpenSceneGraph que nos permite

o

T

Permite estab

necesariamente conestablece el grafo de escen(suponiensobre las dePara recorrNodeVisitorseguir un orden en los nodos del grafo, de esta manera iremos construyendo el subárbol sobre el árbol que queremos y completandnuestro grafo interno. Esta función solo permitirá insertar nodos dentro del elemento que queramos, si este elemento pertenece a un nodo derivado de la clase Group de OpenSceneGraph.

F.4.2 Replicar una escena de una TreeBar a otra.

aso uso: Cargar escenaC de

ipción: dentifica un grafo de escena. En una sola TreeBar puede

el

ctores: Usuario. A

ipo: Oculta. T

escr Una escena iD

haber varias escenas distintas, cada una de ellas esta representada mediante un árbol. Por tanto, replicar una escena desde un TreeBar a otro consistirá en clonar el árbol. A la vez que se clona el contenido dárbol, se deberá de añadir la información necesaria al grafo de escena del editor para identificar los elementos del árbol por sus nodos. Esto serealizará con la ayuda de un NodeVisitor.

123

Page 125: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.4.3 Clonar un TreeCtrl a partir de otro.

Caso de uso: r escena Carga

pción: n clona un árbol a partir de otro. Este árbol puede ser clonado solo a partir de una rama del árbol origen, en cuyo caso, su

.

el grafo del editor contiene enlaces a los ítems de las distintas instancias del nodo en el árbol, así como sus distintos mirrors.

Actores: Usuario. Tipo: Oculta. Descri Esta funció

padre deberá existir en el árbol destino como ítem equivalente o mirrorLa replica o clonación se realiza elemento a elemento, respetando el orden de los nodos, y actualizando los datos de los nodos del grafo del editor, puesto que

F.5 Nueva escena. Caso de uso: Nueva escena

ctores: Usuario.

ipo: Evidente.

Descripción:

las estructuras de datos necesarias para una escena (al igual que al cargar una escena). Se iniciará un grafo por defecto para colgar esta información. Una vez hecho esto, deberemos añadir una nueva escena al editor. Esto implica crear nuestro

rafo de escena (copia del de OpenSceneGraph), y añadir un nuevo control de árbol en cada una de las TreeBar, clonando su

as veces como sea necesario. También aquí será donde inicialicemos los datos de la selección, y el StateSet global, que nos

ra cambiar el modo de visualización de la escena.

A T

Cuando el usuario desea crear una nueva escena vacía puede pulsar sobre el botón de nueva escena o acceder al menú y crear una nueva escena. Es entonces cuando se inician

propio g

contenido tant

servirá pa

F.5.1 Crear grafo por defecto. Caso de uso: Nueva escena

ctores: Usuario.

ipo: Oculto.

escripción: El grafo no deberá ser la escena en sí, puesto que el editor necesita más a visualizar de manera axiliar. Por tanto, el grafo inicial

(raíz) estará dividido en dos ramas principales, la primera será la escena s a crear, y en la segunda colgaremos aquellos nodos que nos

A T

Delementos par

que vamo

124

Page 126: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

serán útiles en el editor para manipular otros nodos, como puede ser el eje manipulador, las cajas de selección de objetos, e incluso la rejilla.

F.6 Nuevo árbol. Caso de uso: Nuevo árbol

Usuario. Actores:

ipo: Evidente.

Descripción: a vista de árbol que representa el grafo de escena. Lo que esta función hace es

a TreeBar, inicialmente vacía, y replicar todos y cada uno de las escenas que contiene esta TreeBar en la que acabamos de crear.

n para replicar esto ya la hemos analizado en F.4.2.

T

Esta función se invoca cuando el usuario desea crear una nuev

crear una nuev

La funció

F.7 Insertar fichero. Caso de uso: Insertar Fichero

Usuario.

Evidente.

Actores: Tipo:

escripción: Cuando el usuario desea colgar de una rama un grafo completo, almacenado en el disco duro, entonces se invocará esta función. El usuario seleccionará del disco duro un fichero compatible con la

sub-grafo de escena, que colgará del nodo seleccionado actualmente en el árbol. Esto se consigue con una

permite establecer un grafo sobre cualquier elemento de un árbol.

D

aplicación, que dará paso a un

simple llamada a F4.1 ya que nos

F.8 Cambiar escena activa. Caso de uso: Cambiar Escena Activa

Usuario.

Evidente.

Se produce esta llamada a esta función cuando el usuario realiza un cambio de la escena activa, ya sea mediante alguna combinación teclado o usando el menú de selección de ventanas. Al cambiar de escena activa se deben de actualizar las referencias la superficie de render, la historia actual, el grafo de escena y los datos de la selecciópuesto que son independientes en cada escena, y

Actores: Tipo: Descripción:

del

n, cada escena tiene las

suyas.

125

Page 127: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.9 Deshacer. Caso de uso: Deshacer

s:

Descripción:

a ión

Actore Usuario. Tipo: Evidente.

El usuario realiza esta acción cuando quiere deshacer la última acción ejecutada. El gestor de historia será en encargado de realizar la llamada deshacer sobre la última acción y de retroceder el cursor de posicsobre la historia.

F.10 Rehacer. Caso de uso: Rehacer Actores: Usuario. Tipo: Evidente. Descripción: El usuario realiza esta acción cuando quiere rehacer la última acción

deshecha. El gestor de historia será en encargado de realizar la llamada a rehacer sobre la última acción y de avanzar el cursor de posición sobrla historia.

e

F.11 Crear Nodo.

aso de uso: Crear NodoC

ctores: Usuario.

ipo: Evidente.

escripción: El usuario podrá crear un nodo sobre el elemento que está actualmente

A T D

seleccionado en el árbol del grafo de escena, seleccionándolo desde unalista de nodos del panel de comandos, o pulsando un botón en forma de icono que identifica tal nodo.

F.11.1 Crear un nodo según el nombre de su NodeType. Caso de uso: Crear Nodo

Usuario. Actores:

126

Page 128: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Tipo:

escripción: Esta función se invoca desde el caso de uso anterior. Al seleccionar el tipo de nodo, el Gestor de nodos busca un NodeType con el nombre especificado, y llama a la función que devuelva una nueva instancia del

eType en cuestión. Este nodo deberemos añadirlo al grafo de escena del editor y de OpenSceneGraph,

as que haya abiertas en el editor y añadir la información necesaria en las tablas de índices de las

s de datos del grafo y de los árboles.

Oculta.

D

tipo de nodo que devuelve en Nod

así como añadirlo a todas las vist

estructura

F.11.2 Crear una nueva instancia de un nodo según su nombre. Caso de uso: Crear Nodo

Usuario.

Oculta.

Cada NodeType debe de tener implementada la función NewInstance,que debe de devolver una nueva instancia del tipo de nodo qrepresentando. Cuando el gestor de NodeTypes quiere obtener una nueva instancia de un tipo de nodo a partir de su nombre (por ejemplocuando el usuario quiere crear un tipo de nodo al seleccionarlo dlista, por su nombre), busca entre sus índices si existe el NodeType según el nombre, y en

Actores: Tipo: Descripción:

ue está

e la

ese caso, invoca a la función NewInstance, que devolverá el objeto deseado.

F.12 Seleccionar elemento en árbol. Caso de uso: Seleccionar elemento en árbol

ctores: Usuario.

ipo: Evidente.

Descripción: ento del árbol

u

iamente los del nodo anteriormente seleccionado, y rellenaremos la información de salida con la información del nodo en cuestión.

A T

Un usuario puede seleccionar un ítem del árbol tan solo pulsando sobreél para mostrar sus propiedades. Al seleccionar un elemel editor tiene acceso directamente al ítem del árbol seleccionado. Puesto que el árbol mantiene una correspondencia de cada ítem con snodo del grafo del editor, podremos saber qué nodo, y en consecuenciaqué tipo de nodo (NodeType) hemos seleccionado. Es entonces cuando marcaremos en cierto color todas las instancias de ese mismo nodo, y enrojo las equivalencias de esas mismas instancias en los demás TreeBars. Además, ya disponiendo del tipo de nodo que estamos tratando, pasaremos a visualizar en el panel de comandos, todos los grupos de parámetros asociados a ese tipo de nodo, ocultando prev

127

Page 129: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.12.1 Seleccionar todas las instancias de un elemento.

Caso de uso: Seleccionar elemento en árbol

ctores: Usuario.

ipo: Evidente.

Descripción:

de

A T

Esta funcion simplemente sirve como ayuda visual para que el usuariopueda identificar de una manera sencilla e intuitiva las distintas instancias del árbol que pertenecen a un mismo nodo. De esta manera el usuario será consciente de que cualquier parámetro que modifiqueeste elemento del árbol, afectará a todas sus instancias, que podrá apreciar marcadas de distinto color.

F.12.2 Seleccionar todos los “mirrors” de un elemento.

aso de uso: Seleccionar elemento en árbolC

ctores: Usuario.

ipo: Evidente.

escripción: Esta función simplemente sirve como ayuda visual para que el usuario

A T D

pueda identificar de una manera sencilla e intuitiva la correspondenciade un elemento de un árbol con su equivalente en las demás vistas del mismo árbol.

F.12.3 Mostrar la información de un nodo

Caso de uso: Seleccionar elemento en árbol Actores: Usuario. Tipo: Evidente.

pción: ión se invoca cuando hemos seleccionado un nodo del árbol. Para mostrar la información de un nodo necesitamos su NodeType. Una

a ar

ima de su hijo. Del mismo nodo, si hemos cambiado el NodeType deberemos lanzar una notificación de fin

Descri Esta func

vez adquiridos ambos, podemos comenzar a mostrar la salida. Si es la primera vez que un NodeType se muestra, se realiza la llamadagenerar sus diálogos en tiempo real. Esto se hace para intentar ahorrrecursos y no crear aquellos diálogos que no se lleguen a utilizar durante la ejecución del programa. Si existía algún NodeType anterior mostrado, y distinto al actual, entonces lo ocultamos y mostramos el nuestro. Al mostrar el NodeType mostraremos de manera recursiva elcontenido de los controles de este, y el de su padre, de manera que el pare siempre se muestre por enc

128

Page 130: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

de selección, y por último, rellenaremos los controles con los datos del nodo que queremos mostrar.

F.12.4 Crear los diálogos de un TabOutput Caso de uso: Seleccionar elemento en árbol

ctores: Usuario.

Tipo: Descripción: ar

re su tipo padre, si así lo requiere. Para ello, se accede al vector del grupo de parámetros que debe de contener el NodeType por la función 1.6. Este vector contiene información de los distintos grupos o agrupaciones de parámetros que puede tener un nodo.

un grupo, podrá indicar de manera opcional en que pestaña del panel de comandos aparecerá, y cada grupo estará

descriptores de parámetros. Por tanto, para cada grupo crearemos un diálogo que irá contenido

lo que llamaremos una página desplegable (o Rollup Page, puesto que tendrá un botón que permitirá plegar o desplegar el

que se mostrará en alguna de las pestañas del panel de comandos.

A

Oculta.

Como hemos comentado en F12.3 la primera vez que se llama a mostrun NodeType se crean dinámicamente los diálogos que contendrán los controles que mostrarán los datos del nodo. Esta función es recursiva y se llamará del mismo modo sob

Normalmente solo tendrá

compuesto por un conjunto de

dentro de

contenido del diálogo)

F.12.5 Crear un diálogo a partir de un grupo de parámetros Caso de uso: Seleccionar elemento en árbol

Usuario.

Oculta.

Actores: Tipo:

escripción: Esta función se invoca al crear los diálogos de un TabOutput. Cada uno de los grupos de parámetros que forman un TabOutput está formado a su vez por un conjunto de descriptores de parámetros.

r el diálogo que se va a construir dinámicamente. Entre esta información encontraremos, el nombre del

es editable o no, por ejemplo. Por tanto, en cada tipo de descriptor realizaremos una llamada distinta para crear

control distinto. Por último, realizaremos una últimos ajustes a los controles, como por ejemplo ajustar el numero máximo de

en los campos de texto, o si deshabilitaremos el control inicialmente en caso de que así lo indique el descriptor.

D

Cada uno de estos descriptores contendrá información sobre cada uno de los controles que deberá contene

control, el tipo de control, y si

un tipo de

caracteres

129

Page 131: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.12.6 Generar el contenido de un TabOutput Caso de uso: Seleccionar elemento en árbol Actores: Usuario. Tipo: Oculta. Descri Esta funcpción: ión es invocada directamente por la función de mostrar un

TabOutput. Cuando hablamos del contenido, hablamos del contenido e

que

final que aparecerá en el interfaz, mas concretamente sobre el panel dcomandos. Consiste en generar una página desplegable o Rollup a partirde un diálogo ya generado. Una vez hecho esto, el diálogo estará contenido en un deplegable que el usuario podrá plegar siempre quiera tan solo pulsando un botón, para ahorrar espacio en el interfaz, ydesplegar cuando quiera mostrar su contenido de nuevo.

F.12.7 Vaciar el contenido de un TabOutput Caso de uso: Seleccionar elemento en árbol

c Usuario.

ipo: Oculta.

escripción: Es la función inversa a la anterior. Suele invocarse cuando queremos salida del panel de comandos, bien para dejarlo vacío, bien

para dar paso a generar el contenido de otro TabOutput. Esta llamada la el diálogo que identifica en grupo de parámetros del Rollup

en el que está contenido, pero no destruye en diálogo que hemos creado

A tores:

T D

limpiar la

desvincu

de la memoria.

F.12.8 Notificar fin de selección de un ObjectType Caso de uso: Seleccionar elemento en árbol

Usuario.

Oculta.

Actores:

escripción: El ObjectType tiene la particularidad de que es notificado cuando su ostrado por pantalla va a ser

otro, ya sea del mismo tipo o de un tipo distinto, pero de contenido distinto. Esta función se invoca de manera

icación llegará tanto el ObjectType como a sus precedentes en la jerarquía de herencia que se haya establecido.

icación se realiza para que el desarrollador de ObjectTypes pueda realizar los ajustes que crea convenientes al ser consciente de que

va a dejar de editarse.

Tipo: D

contenido que está actualmente siendo meliminado y sustituido por

recursiva, de modo que la notif

Esta notif

el objeto

130

Page 132: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.12.9 Mostrar los datos de un TabOutput Caso de uso: Seleccionar elemento en árbol

Usuario. Actores:

ipo: Oculta.

escripción: Esta es la función culminante en el proceso de mostrar el contenido de Al igual que las anteriores, si se trata de un ObjectType se

realiza de manera recursiva en caso de tener un tipo de padre. Esta ue realizará la llamada a la función que implemente el

desarrollador para mostrar los datos del nodo. El comportamiento de tal ependerá de la implementación que el desarrollador haya dado

al TabOutput o el ObjectType.

T D

un nodo.

función es la q

función d

F.13 Seleccionar nodo en el visor Caso de uso: Seleccionar nodo en el visor

Usuario.

Evidente.

Se llama a esta función cuando queremos seleccionar un nodo en el visor. Este nodo, generalmente un Geode,

Actores: Tipo: Descripción:

se puede seleccionar pulsando directamente sobre el elemento en la pantalla, o seleccionándolo en el árbol e indicando explícitamente que queremos

el visor. Al seleccionar un objeto del visor tendremos que generar una información del objeto seleccionado, y crear una caja

e nos indique la posición del objeto y el área que ocupa. Este objeto que contiene información de selección se añadirá a una lista,

stirá en una lista de las informaciones de todos los objetos seleccionados. Puesto que se trata de una selección única, deberemos

e vaciar la selección existente.

seleccionarlo en

de selección qu

que consi

previament

F.13.1 Agregar nodo a la selección del visor Caso de uso: Seleccionar nodo en el visor

cto

es equivalente a la anterior, solo que en este caso, en lugar nar solo el elemento que queremos, lo añadiremos a la ctual.

A

ipo: Evidente.

res: Usuario.

T

escripción: Esta función Dde seleccioselección a

131

Page 133: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.13.2 Crear un nodo. Matriz de Transformación como padre de Caso de uso: Seleccionar nodo en el visor

Act

ón se llama automáticamente al seleccionar un objeto. La razón de ello es que al seleccionar un objeto, el usuario está indicando

odo su intención de aplicarle alguna transformación. Esta transformación solo se puede llevar a cabo sobre una Matriz de

triz

ores: Usuario.

Tipo: Oculta. Descripción: Esta funci

en cierto m

Transformación que contenga al nodo como uno de sus descendientes. Por tanto, lo que hará esta función será comprobar si existe una made transformación como padre del nodo, y además, que esa transformación solo tenga a ese nodo como hijo. En caso contrario, creamos un nuevo nodo tipo Matriz de Transformación y lo “intercalamos” entre el nodo que queremos transformar y su padre actual.

F.13.3 Actualizar la selección.

aso de uso: Seleccionar nodo en el visorC

ctores: Usuario.

ipo: Oculta.

escripción: Lo que esta función hace realmente es actualizar el cursor según su el eje manipulador, además del estado del cursor. El estado

del cursor define si el cursor está encima de algún objeto, o encima de

colisión del cursor con tal eje. Si el cursor no esta encima de ningún elemento del eje manipulador entonces se comprueba si existe colisión con alguno de los objetos, actualizando

el estado del cursor en función de si el eje está o no seleccionado, y de la transformación que estemos llevando a cabo.

A T D

posición, o

algún otro elemento, como puede ser el eje manipulador. En primer lugar se comprueba si existe algún objeto seleccionado en la escena, en ese caso sabremos que el eje manipulador estará mostrado por tanto obtenemos si existe alguna

el cursor y

F.13.4 Actualizar el eje manipulador. Caso de uso: Seleccionar nodo en el visor

Actores: Tipo:

Usuario.

Oculta.

132

Page 134: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Descripción:

ador, obteniendo exactamente con qué elemento del eje intersecciona y actualizando el estado del mismo, y su apariencia (por ejemplo, resaltando con más brillo el eje o el plano que estamos seleccionando en el eje manipulador). De esta manera podremos

r momento qué ejes se encuentran seleccionados en cada momento.

Esta función realiza las mismas comprobaciones que la anterior, pero únicamente comprueba si existe alguna intersección del cursor del ratón con el eje manipul

consultar en cualquie

F.14 Copiar nodo. Caso de uso: Copiar nodo

Actores:

ipo: Evidente.

escripción: Esta función se encarga de copiar un elemento del árbol a otro elemento destino. Este nodo se podrá copiar como hijo del nodo destino o como

ás, el elemento podrá copiarse desde un árbol hasta otro distinto, siempre que pertenezcan al mismo grafo.

e copiar un elemento, lo que realmente estaremos haciendo será instanciarlo, es decir, crearemos una

tancia en el árbol, y en el grafo lo que únicamente haremos será añadir un nuevo padre al nodo que estamos copiando.

peración deberá repetirse (excepto la modificación la vinculación de los elementos del grafo) para todas las vistas que existan

Usuario.

T D

hermano del nodo destino. Adem

En esta aplicación, cuando hablamos d

nueva ins

Esta misma o

duplicadas del árbol del grafo de escena.

F.14.1 Replicar selección. Caso de uso: Copiar nodo

Act

a réplica del nodo haciendo uso de la función copiar nodo, creando su propia matriz de transformación y desplazando el objeto

ia respecto del objeto a copiar y tomando como nodo padre el mismo nodo padre del nodo origen.

ores: Usuario.

Tipo: Evidente. Descripción: Realiza un

una distanc

F.15 Mover nodo.

aso de uso: Mover nodoC

ctores: Usuario.

ipo: Evidente.

A T

133

Page 135: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Descripción: al que la anterior, con la única diferencia que después de copiar el nodo, el nodo origen se elimina,

padre.

Esta función es exactamente igu

tanto del árbol, como el enlace de su

F.16 Duplicar Nodo. Caso de uso: Duplicar nodo

Usuario. Actores:

ipo: Evidente.

escripción: Al igual que la función Copiar Nodo, esta función se encarga de copiar l a otro elemento destino. Este nodo se podrá

copiar como hijo del nodo destino o como hermano del nodo destino. rmino Duplicar, para decir que no vamos a

instanciar el nodo, sino que vamos a duplicar por completo el nodo y descendientes, de manera que la rama que hayamos duplicado

será complemente independiente de la rama origen y cualquier ón sobre cualquier nodo de cualquier elemento duplicado no

tendrá ningún efecto sobre los originales.

T D

un elemento del árbo

En esta ocasión usamos el te

todos sus

modificaci

El procedimiento es el mismo, solo que al copiar los elementos del árbol, además, copiaremos los elementos del grafo también (en el caso de copiar nodo, tan solo agregábamos un padre más).

F.16.1 Duplicar Seleccion.

Caso de uso: Duplicar nodo

ctores: Usuario.

ipo: Evidente.

ión: Realiza una réplica del nodo haciendo uso de la función duplicar nodo, propia matriz de transformación y desplazando el objeto una

distancia respecto del objeto a duplicar y tomando como nodo padre el

A T

escripcDcreando su

mismo nodo padre del nodo origen.

F.17 Eliminar nodo. Caso de uso: Eliminar nodo

Act

ón elimina un elemento o instancia de un elemento del grafo. Para ello deberá deseleccionarlo del visor en caso de que se encuentre

o, y eliminarlo de todas las vistas de árbol que haya abiertas. Además deberá actualizar la información del grafo del editor puesto que contiene referencias a los ítems del árbol, eliminando las referencias

ores: Usuario.

Tipo: Evidente. Descripción: Esta funci

seleccionad

134

Page 136: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

que debamos. Si hemos eliminado todas las distintas instancias de un nodo, y ya no quedan referencias a él, entonces el nodo del grafo podrá ser desvinculado.

F.18 Activar modo selección. Caso de uso: iónActivar modo selecc

ctores: Usuario.

Tip

ión cuando el usuario quiere activar el modo de selección de objetos. En este modo simplemente podrá seleccionar

el visor, sin aplicarles ningún tipo de transformación.

A

o: Evidente. Descripción: Se invoca esta func

objetos en

F.19 Activar modo traslación de objetos. Caso de uso: Activar modo traslación de objetos

Usuario. Actores:

ipo: Evidente.

escripción: Se invoca esta función cuando el usuario quiere activar el modo de traslación de objetos. Cuando este modo esté activado el usuario podrá

aslación sobre todos los objetos seleccionados en pantalla.

T D

aplicar transformaciones de tr

F.20 Activar modo escalado de objetos. Caso de uso: Activar modo escalado de objetos

Actores: Tipo: Descripción: el usuario quiere activar el modo de

podrá

Usuario.

Evidente.

Se invoca esta función cuandoescalado de objetos. Cuando este modo esté activado el usuario aplicar transformaciones de escalado sobre todos los objetos seleccionados en pantalla.

135

Page 137: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.21 Activar modo rotación de objetos. Caso de uso: Activar modo rotación de objetos

.

Actores: Usuario. Tipo: Evidente Descripción: Se invoca esta función cuando el usuario quiere activar el modo de

rotación de objetos. Cuando este modo esté activado el usuario podrá aplicar transformaciones de rotación sobre todos los objetos seleccionados en pantalla.

F.22 Activar modo rotar vista.

Caso de uso: do rotar vista Activar mo

pción: sta función cuando el usuario quiere activar el modo de

Actores: Usuario. Tipo: Evidente. Descri Se invoca e

rotar la vista. Cuando este modo esté activado el usuario podrá girar la vista como desee para visualizar cualquier objeto en pantalla.

F.23 Activar modo trasladar vista. Caso de uso: Activar modo trasladar vista Actores: Usuario.

ip

ndo el usuario quiere activar el modo de Cuando este modo esté activado el usuario podrá

sta como desee para visualizar cualquier objeto en

T o: Evidente. Descripción: Se invoca esta función cua

trasladar la vista. trasladar la vipantalla.

F.24 Escalar selección. Caso de uso: Escalar selección

Usuario.

Evidente.

Actores:

ipo: T

136

Page 138: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Descripción: ón, nos referimos a un conjunto de nodos. Por tanto no es más que repetir la misma operación para cada uno de los

ón realiza una transformación de escalado sobre un objeto. Para ello, el objeto debe de cumplir ciertos requisitos, en primer

de ser un Geode, y en segundo lugar su padre debe de ser una matriz de transformación pero de ello ya nos hemos asegurado al

ar el objeto. Esta función realmente se divide en tres sub-funciones, el comienzo, el

Cuando hablamos de selecci

nodos. Esta funci

lugar debe

seleccion

transcurso y el final.

F.24.1 Comenzar escalado de selección. Caso de uso: Escalar selección

Usuario. Actores:

ipo: Oculta.

escripción: Es como el Setup o la puesta a punto del escalado. Se llama a esta tes o actualizaciones necesarias o consultar

los datos necesarios para prepararse para comenzar la transformación. recalcularemos la BoundingBox de la selección y

deberemos guardar la posición del centro geométrico de la selección, lo ervirá mas adelante para almacenar correctamente la

transformación como una función invertible.

T D

función para realizar los ajus

Por ejemplo, aquí

cual nos s

F.24.2 Realizar escalado de selección. Caso de uso: Escalar selección

ctores: Usuario.

ipo: Oculta.

escripción: Esta es la función que realiza el escalado, aunque realmente la acción como terminada hasta que soltemos el ratón. En

este paso se aplica la misma transformación a todos los objetos de la en función del desplazamiento del cursor sobre la pantalla, y

siempre aplicándola sobre el centro geométrico de cada objeto colocado de coordenadas.

Una vez hecho esto, deberemos también actualizar las cajas de

A T

Dno se podrá considerar

selección

en el origen

selección de los objetos seleccionados, puesto que las transformacionesdeben afectarles por igual, así como actualizar su BoundingBox y la posición del eje manipulador.

137

Page 139: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.24.3 Finalizar escalado de selección.

aso de uso: Escalar selecciónC

ctores: Usuario.

ipo: Oculta.

escripción: Este es el paso que da por finalizado el escalado de la selección. Es aquí actualiza la información de la selección, como por ejemplo

los valores de las matrices auxiliares que se utilizan para almacenar ión que luego servirán para almacenar la acción invertible de la

transformación. También aquí actualizaremos la BoundingBox de la

A

T D

donde se

informac

selección y actualizaremos la posición del eje manipulador.

F.25 Rotar selección. Caso de uso: Rotar selección Actores: Usuario.

Tip

elección, nos referimos a un conjunto de nodos. etir la misma operación para cada uno de los

ta función realiza una transformación de rotación sobre un debe de cumplir ciertos requisitos, en primer

e de ser un Geode, y en segundo lugar su padre debe de ser ación pero de ello ya nos hemos asegurado al

o: Evidente.

Descripción: Cuando hablamos de s

Por tanto no es más que repnodos. Esobjeto. Para ello, el objeto lugar debuna matriz de transformseleccionar el objeto. Esta función realmente se divide en tres sub-funciones, el comienzo, el transcurso y el final.

F.25.1 Comenzar rotación de selección. Caso de uso: Rotar selección

Usuario.

Oculta.

Es como el Setup o la puesta a punto de la rotación. Se llama a esta función para realizar los ajuste

Actores: Tipo: Descripción:

s o actualizaciones necesarias o consultar los datos necesarios para prepararse para comenzar la transformación. Por ejemplo, aquí recalcularemos la BoundingBox de la selección y deberemos guardar la posición del centro geométrico de la selección, lo

ara almacenar correctamente la transformación como una función invertible. cual nos servirá mas adelante p

138

Page 140: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.25.2 Realizar rotación de selección. Caso de uso: lecciónRotar se

Tipo: Descripción: ión no

n este la misma transformación a todos los objetos de la

selección en función del desplazamiento del cursor sobre la pantalla, y siempre aplicándola sobre el centro geométrico de cada objeto colocado en el origen de coordenadas.

os también actualizar las cajas de selección de los objetos seleccionados, puesto que las transformaciones

o actualizar su BoundingBox y la posición del eje manipulador.

Actores: Usuario.

Oculta.

Esta es la función que realiza la rotación, aunque realmente la accse podrá considerar como terminada hasta que soltemos el ratón. Epaso se aplica

Una vez hecho esto, deberem

deben afectarles por igual, así com

F.25.3 Finalizar rotación de selección. Caso de uso: Rotar selección

ctores: Usuario.

ipo: Oculta.

escripción: Este es el paso que da por finalizada la rotación de la selección. Es aquí de la selección, como por ejemplo

los valores de las matrices auxiliares que se utilizan para almacenar ón que luego servirán para almacenar la acción invertible de la

transformación. También aquí actualizaremos la BoundingBox de la actualizaremos la posición del eje manipulador.

A T

Ddonde se actualiza la información

informaci

selección y

F.26 Trasladar selección. Caso de uso: Trasladar selección Actores: Usuario. Tipo: Evidente.

pción: blamos de selección, nos referimos a un conjunto de nodos. Por tanto no es más que repetir la misma operación para cada uno de los

Descri Cuando ha

nodos. Esta función realiza una transformación de traslación sobre un objeto. Para ello, el objeto debe de cumplir ciertos requisitos, en primer lugar debe de ser un Geode, y en segundo lugar su padre debe de ser una matriz de transformación pero de ello ya nos hemos asegurado al seleccionar el objeto.

139

Page 141: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Esta función realmente se divide en tres sub-funciones, el comienzo, el transcurso y el final.

F.26.1 Comenzar traslación de selección. Caso de uso: Trasladar selección

ctores: Usuario.

Tipo: Descripción:

cesarias o consultar los datos necesarios para prepararse para comenzar la transformación. Por ejemplo, aquí recalcularemos la BoundingBox de la selección y deberemos guardar la posición del centro geométrico de la selección, lo

macenar correctamente la transformación como una función invertible.

A

Oculta.

Es como el Setup o la puesta a punto de la traslación. Se llama a esta función para realizar los ajustes o actualizaciones ne

cual nos servirá mas adelante para al

F.26.2 Realizar traslación de selección. Caso de uso: Trasladar selección

Actores: Tipo:

escripción: Esta es la función que realiza la traslación, aunque realmente la acción no se podrá considerar como terminada hasta que soltemos el ratón. En

nsformación a todos los objetos de la selección en función del desplazamiento del cursor sobre la pantalla.

ularidad de que requiere algunos cálculos extraordinarios para calcular el incremento que vamos a aplicar

ción, ya que calcularemos un plano imaginario que sea paralelo al plano seleccionado en el eje manipulador, y que pase por el

selección, de esta manera, intersectando una línea imaginaria desde el cursor hacia este plano obtendremos el punto donde

licar

selección de los objetos seleccionados, puesto que las transformaciones deben afectarles por igual, así como actualizar su BoundingBox y la posición del eje manipulador.

Usuario.

Oculta. D

este paso se aplica la misma tra

Esta transformación tiene la partic

a la trasla

centro de la

queremos desplazar el objeto, y así calcularemos el incremento a apcomo traslación. Una vez hecho esto, deberemos también actualizar las cajas de

F.26.3 F ar traslación de selección. inaliz

Caso de uso: Trasladar selección

140

Page 142: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Actores: Usuario.

Tipo:

escripción: Este es el paso que da por finalizada la traslación de la selección. Es aquí donde se actualiza la información de la selección, como por

ara almacenar información que luego servirán para almacenar la acción

BoundingBox de la selección y actualizaremos la posición del eje or.

Oculta.

D

ejemplo los valores de las matrices auxiliares que se utilizan p

invertible de la transformación. También aquí actualizaremos la

manipulad

F.27 Centrar la vista en la selección. Caso de uso: Centrar la vista en la selección

Usuario.

Evidente.

Cuando el usuario quiera visualizar un objeto en el centro geométrico de la pantalla, podrá hacer uso de esta opci

Actores: Tipo: Descripción:

ón. Esta función tan solo hace que la cámara enfoque al centro geométrico de la selección actual.

F.28 Modificar el zoom de la vista. Caso de uso: Centrar la vista en la selección

ctores: Usuario.

ipo: Evidente.

Descripción:

A T

Esta función permite acercar o alejar la cámara o visor de su foco.

F.29 Añadir un StateAttribute a un StateSet. Caso de uso: Añadir un StateAttribute a un StateSet

c

ón permite añadir un StateAttibute a un StateSet de un nodo leccionar el StateAttribute de la

tateAttributes que la aplicación soporte. Esta lista se obtiene

A Tipo: Evidente.

tores: Usuario.

Descripción: Esta funci

del grafo de escena. El usuario deberá selista de Sdel gestor de objetos, y es el mismo gestor de objetos el que devolverá una nueva instancia del StateAttribute que elijamos.

141

Page 143: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.30 Eliminar un StateAttibute de un StateSet.

aso de uso: Eliminar un StateAttribute de un StateSetC

cto

ipo: Evidente.

escripción: Si el usuario así lo desea, podrá eliminar los StateAttributes del StateSet o, seleccionando de la lista aquel que quiera. Del mismo

modo, dispondremos del nombre del StateAttribute a eliminar, y el bjectTypes nos devolverá el tipo de StateAttribute, lo cual

nos permitirá directamente eliminarlo del StateSet.

A res: Usuario.

T D

de un nod

gestor de O

F.31 Añadir un Modo a un StateSet.

Añadir un Modo a un StateSet Caso de uso: A

ctores: Usuario.

ipo: Evidente.

do a un StateSet de un nodo del grafo de escena. El usuario deberá seleccionar el Modo de la lista de Modos

s está relacionada con los modos que OpenGL soporta.

T Descripción:

que la aplicación soporte. Esta lista de modo

Esta función permite añadir un Mo

F.32 Eliminar un Modo de un StateSet. Caso de uso: Añadir un Modo a un StateSet

Usuario.

Evidente.

Esta función permite eliminar un Modo o un valor del Modo de un

Actores: Tipo:

escripción: . El usuario deberá seleccionar

ateSet tenga actualmente.

DStateSet de un nodo del grafo de escenael Modo de la lista de Modos que el St

F.33 Modif car un Moi do de un StateSet. Caso de uso: un Modo a un StateSetModificar

ipo: Evidente.

Actores: Usuario. T

142

Page 144: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Descripción: ra que puede contener varios flags,

por tanto un usuario podrá añadir o eliminar estos flags a un modo ya El modo de un StateSet es una másca

existente de un StateSet.

F.34 Modificar el parámetro de un control del panel de comandos. Caso de uso: Modificar el parámetro de un control del panel de comandos

ctores: Usuario.

ipo: Evidente.

escripción: Cuando un usuario manipula alguno de los controles del panel de parámetros referentes a un

nodo, a un objeto, o incluso un TabOutput, se realiza una llamada e hace que se modifiquen algunos valores (por ejemplo, un

spinner con un descriptor tipo float asociado hará que al pulsar la flecha coja el contenido de la caja de texto asociada al spinner e

incremente en una décima su valor) y después se realice una llamada a anera el

desarrollador de TabOutputs podrá hacer las gestiones necesarias para modificar la estructura de datos asociada.

A T

Dcomandos donde aparecen los grupos de

interna, qu

superior re

la notificación de parámetro modificado. De esta m

F.34.1 Establecer el valor de un parámetro.

Caso de uso: Modificar el parámetro de un control del panel de comandos

s:

escripción: El desarrollador de TabOutputs podrá establecer una interacción con los controles asociados a los grupos de parámetros y forzar a establecer los

ontroles. Para ello se dispondrá de ciertos tipos de datos conocidos

aplicación en los controles de

Actore Usuario. Tipo: Oculta. D

valores que deberán contener los cuna función que permitirá establecer por el desarrollador y soportados por lalos paneles de comandos.

F.34.2 Estab lor de un parámetro. lecer el va Caso de uso: Modificar el parámetro de un control del panel de comandos A

ctores: Usuario.

ipo

establecer una interacción con los asociados a los grupos de parámetros y obtener en cualquier el valor que el control está almacenando, guardándolo en una

T Descripción: El desarrollador de TabOutputs podrá

: Oculta.

controles momento

143

Page 145: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

estructura de datos conocida por el desarrollador. Para ello se dispondrá ión que permitirá acceder a estos valores según el

identificador del parámetro que el desarrollador habrá asignado

de una func

previamente.

F.35 Establecer el contenido del portapapeles. Caso de uso: Establecer el contenido del portapapeles

peles del propio editor. Dependiendo de la operación que llevemos a cabo, la operación de pegar podrá realizarse como una operación de mover, copiar o de duplicar.

os el tipo de operación de copia, y el nodo, o conjunto de nodos afectados.

Actores: Usuario. Tipo: Evidente. Descripción: Al seleccionar elementos del árbol podremos copiarlos y pegarlos en el

portapa

Por tanto al realizar cualquier operación de portapapeles almacenarem

F.36 Pegar el co portapapeles. ntenido del Caso de uso: Establecer el contenido del portapapeles

Act

la operación previa almacenada en el portapapeles, sabremos peración tendremos que llevar a cabo al pegar. Puesto que

listado de items origen, y tenemos seleccionado el ítem dremos levar a cabo la operación que proceda. Si la

ión

iento de nodos, y si era una operación de duplicado, duplicaremos la lista de nodos seleccionados sobre el item destino.

ores: Usuario.

Tipo: Evidente. Descripción: Sabiendo

que tipo de otenemos undestino, pooperación del portapapeles era de copia, llevaremos a cabo la operacde copia, si era una operación de movimiento, llevaremos a cabo la operación de movim

F.37 Visualizar escena en modo de alambre.

aso de uso: Visualizar escena en modo de alambre C

Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la informacion geométrica de la escena en modo de rejil

alambre. la de

144

Page 146: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

F.38 Visualizar escena en modo de relleno.

Caso de uso: Visualizar escena en modo de relleno Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la informacion geométrica de la escena en modo relleno.

F.39 Visualizar sombreado en modo plano. Caso de uso: Visualizar sombreado en modo plano Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la escena en modo de sombreado plano.

F.40 Visualizar sombreado en modo suavizado. Caso de uso: Visualizar escena en modo suavizado Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la escena en modo de sombreado suavizado.

F.41 Mostrar vista superior de la escena. Caso de uso: Mostrar vista superior de la escena Actores: Usuario. Tipo: Evidente.

escripción: Visualiza la escena desde un punto superior al centro de la selección actual.

D

F.42 Mostrar vista inferior de la escena. Caso de uso: Mostrar vista inferior de la escena Actores: Usuario.

145

Page 147: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Tipo: Evidente. Descripción: Visualiza la escena desde un punto inferior al centro de la selección

actual

F.43 Mostrar vista anterior de la escena. Caso de uso: Mostrar vista anterior de la escena Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la escena desde un punto anterior al centro de la selección

actual

F.44 Mostrar vista posterior de la escena. Caso de uso: Mostrar vista posterior de la escena Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la escena desde un punto posterior al centro de la selección

actual

F.45 Mostrar vista lateral izquierda de la escena. Caso de uso: Mostrar vista lateral izquierda de la escena Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la escena desde un punto lateral izquierdo al centro de la

selección actual

F.46 Mostrar vista lateral derecha de la escena.

Caso de uso: Mostrar vista lateral derecha de la escena Actores: Usuario. Tipo: Evidente. Descripción: Visualiza la escena desde un punto lateral derecho al centro de la

selección actual

146

Page 148: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4.4.3 Casos de Uso siguiendo la notación UML. A continuación se muestra el diagrama de uso general del sistema. Dado el gran numero de casos de uso, lo mostraremos en cuatro diagramas separados, para una mayor claridad. En ellos, como podemos observar, no aparecen las funcionalidades anteriormente mencionadas de forma específica sino que se consideran agrupadas en casos de uso más generales. Una vez vistos los casos de uso en general (es decir, que pueden incluir varias funcionalidades agrupadas), se procederá a la especificación de algunos de ellos de forma detallada. No se especifican todos los casos de uso, ya que se considera que con la especificación de las funciones (de alto nivel), realizada en el apartado anterior, quedan explicadas las acciones que serán necesarias realizar para llevar a cabo una determinada tarea.

147

Page 149: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

148

Page 150: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

149

Page 151: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

CASO DE USO: “Iniciar”

Acción de los Actores Respuesta del sistema 1. El usuari 2. La aplica bjeto

ia , etc. es

inicialmente.

as

o arranca la aplicacion. ción crea una vista y el oglobal ActiveViewHandler que su vez iniclos gestores de objetos, nodos, parametrosy registra los tipos de datos que los gestorcontendrán 3. Se crea el grafo inicial, conteniendo los datos auxiliares como la rejilla o el eje manipulador. 4. Se Inician las estructuras de datos necesaripara iniciar una escena en OpenSceneGraph. 5. Se crea la barra de herramientas de creacionde nodos, la barra de depuración y la barra de paneles de comandos.

150

Page 152: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

6. Se crea un nuevo árbol para representar elgrafo inicial.

. Se establece le pasa el nodo raiz del grafo al

tra su

9. Se cargan los plugins del programa, que a su vez registran los objetos de los plugins en sus respectivos gestores.

7arbol para que se inicie la representación en árbol del nodo. 8. Se inician los TabOutput y se muescontenido en el panel de comandos.

CASO DE USO: “Nueva Escena”

Acción de los Actores Respuesta del sistema

ulsando el botón apropiado o seleccionando la opcion desde el menú principal.

sta. Al la

s, como la rejilla o el eje anipulador, y un nodo de selección de

ción

h.

as omo vistas existan abiertas en la

plicación.

8. Se inicia un nuevo objeto de selección con el eje manipulador. 9. Se establece la raíz de la representación en árbol de la escena como el nodo raíz de nuestro graf

1. El usuario decide iniciar una nueva escena en el editor p

2. La aplicación crea una nueva viiniciar la vista se crea el grafo inicial deaplicación, conteniendo los datos auxiliares necesariomobjetos donde colgarán las cajas de selecde los mismos. 3. Se Inician las estructuras de datos necesarias para iniciar una escena en OpenSceneGrap 5. Se crea una nueva escena vacía en la Barrade árbol (sin grafo asociado), agregando portanto un nuevo árbol para representar el grafo inicial. Este arbol deberá ser replicado tantveces ca 6. Se establece esta escena como la escena activa.

o inicial. CASO DE USO: “Finalizar aplicación”

Acción de los Actores Respuesta del sistema

151

Page 153: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

1. El usuario cierra la aplicación desde el botón de cerrar, o desde el menu principal.

. La aplicación realiza una llamada a cerrar

de las escenas que cada TreeBar

macena, y que se vacíe la historia de la

ena. 4. Se libera la memoria almacenada por los controles de windows usados para representar el árbol.

2todas las TreeBar. 3. Esto provoca que se libere la informacionde cada una alescena. 3. Se liberan los recursos OSG de cada esc

CASO DE USO: “Modificar un parámetro

Acción de los Actores Respuesta del sistema

arámetros de un nodo del grafo de escena

Spinner.

sado.

e envia

n caso afirmativo envía tal otificación al adjuntador.

CASO DE USO: “Seleccionar un objeto en el v

1. El usuario interactúa con algun control del panel de comandos, por ejemplo de losppulsando sobre la flecha superior de un

2. La aplicación envia una notificación al Gestor de parámetros para avisarle de que un control ha sido modificado o pul 3. El gestor de parámetros comprueba si la notificacion pertenece a algún parámetro existente en sus tablas y en ese caso se lla notificación al ObjectType asociado a tal control. 4. Del mismo modo, se comprueba si el ObjectType está siendo adjuntado por algun otro ObjectType y en

isor”

Acción de los Actores Respuesta del sistema . El usuario coloca el cursor sobre un objeto el visor y pulsa el botón para seleccionar el

2. La aplicación recoje la notificacion de pulsación del ratón y se la pasa al objeto selección. 3. El objeto s ción del ratón co bar sobre

. Puesto que el cursor está encima de un

”, datos

s como argumentos

1dobjeto.

elección obtiene la intersecn la escena, para compro

qué está el cursor. 4objeto y no está seleccionado vamos a crear una nueva accion de “cambio de selecciónpor tanto guardaremos en dos tablas losde la selección para pasarla

152

Page 154: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

de la nueva accion. De esta manera el sistema

abo. 5. Ejecutamos la acción. El gestor de historia almacenará la acción internamente. 6. Actualiza

dispondrá de la información necesaria para deshacer la acción que acabamos de llevar a c

mos el eje manipulador, olo en el centro de la selposicionand ección.

CASO DE USO: “Insertar un fichero”

Acción de los Actores Respuesta del sistema 1. El usuario decide insertar un fichero como hijo del nodo seleccionado en el árbol.

. El usuario elige el fichero que quiere añadir la escena.

4. Mediante funciones propias de OpenSceneGraph cargamos el fichero,

niendo el nodo raiz del grafo de escena del fichero.

n y no

ra berá recorrer el nuevo grafo, creando

os crear una réplica de nueva rama generada en todas las demás

CASO DE USO: “Nuevo árbol”

2. El sistema muestra un diálogo de selección de archivos.

3a

obte

4. Obtenemos el objeto seleccionado actualmente en el árbol y comprobamos si su nodo asociado es un nodo que permita contener hijos, en caso de que no se pueda, no se puede llevar a cabo la operacióhacemos nada. 5. Establecemos el grafo como hijo del nodo que tenemos seleccionado en el árbol. Paello se depara cada nodo los ítems necesarios en el árbol. 6. Por último, deberemlavistas del árbol que haya abiertas.

Acción de los Actores Respuesta del sistema 1. El usuario pulsa el botón de visualizar nuevo árbol en la barra de herramientas, o selecciona la opción del menú principal.

El objeto que gestiona todas las TreeBar,

or de las TreeBar añade esta nueva

2.crea una nueva ventana que contendrá los distintos árboles de las distintas escenas. 3. El gestbarra a sus índices.

153

Page 155: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4. Se añade una nueva escena a la nueva TreeBar, por cada escena de las que ya

cena representa el control de árbol en si. 5. Se realiza una réplica de cada una de las escenas (es decir, del árbol completo de cada

en la nueva TreeBar.

existen. La es

una de las escenas)

CASO DE USO: “Crear Nodo”

Acción de los Actores Respuesta del sistema 1. El usuario selecciona un elemento del árbolpreferiblemente un ítem que esté asociado a un nod

,

o que admita tener hijos (derivado de roup).

2. El usuario selecciona el primer panel de comandos, y selecciona un elemento de la lista de nodos disponibles en la aplicación. 3. El usuario pulsa sobre Crear Como Hijo

ccionado ctualmente en el árbol.

ear

cual deberá colgar.

. El gestor de nodos busca un NodeType y

Graph que soporta el NodeType btenido.

andler crea un nuevo nodo del editor y le asocia el nodo OpenSceneGraph que acaba de crear.

ler crea una nueva accion CrearNodo y la ejecuta.

ion

CASO DE USO: “Deshacer”

4. El TabOutput obtiene el nombre del nodoseleccionado de la lista de selección. 5. El TabOutput consulta el item selea

G

6. Se invoca al ActiveViewHandler para crun nodo a partir de su nombre, especificando el padre del 7entre sus índices según el nombre indicado,obtiene una nueva instancia de la clase OpenSceneo 8. ActiveViewH

9. ActiveViewHand

10. Al ejecutar la nueva acción se crea el elemento del árbol y se añade la informacnecesaria en el nodo del editor.

Acción de los Actores Respuesta del sistema 1. El usuario realiza una acción el en editor, por ejemplo desplazar un objeto en la pantalla. 2. El usuario decide deshacer esta acción

ulsando en el botón Deshacer.

Undo

. El gestor de historia realiza una llamada a la funcion Undo de la acción y retrocede la posicion del índice de la última accion ejecutada.

3. La vista activa realiza una llamada adel gestor de historia. 4

p

154

Page 156: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5. La vista ualmente

CASO DE USO: “Rehacer”

activa obtiene el item actseleccionado, y actualiza la salida del interfaz.

Acción de los Actores Respuesta del sistema 3. La vista activa realiza una llamad

1. El usuario deshace una acción. 2. El usuario decide que no queria deshacer esa accion y pulsa en el boton Rehacer para recuperarla.

da a Redo el gestor de historia.

a la n

az.

ASO DE USO: “Seleccionar un item del arbol”

4. El gestor de historia realiza una llamadafuncion Redo de la acción y avanza la posiciodel índice de la última accion ejecutada. 5. La vista activa obtiene el item actualmente seleccionado, y actualiza la salida del interf

C

Acción de los Actores Respuesta del sistema El usuario ol.

2. Se seleccioinstancias d quellos

. Se pide al ActiveViewHandler que muestre

. Para ello, si es la primera vez que se va a

ntenido de cualquier nodo anterior en caso

rán los diálogos de este tipo de nodo y se mostrará el contenido de los datos del nodo en los controles que acabamos de mostrar.

1. pulsa sobre un ítem del árb nan en negrita todas las el mismo item, es decir, a

elementos del árbol que se identifiquen con el mismo nodo del grafo de escena. 3. Se seleccionan en otro color los items equivalentes al que acabamos de seleccionar en las demás vistas de árbol que existan abiertas. 4la información del nodo asociado al ítem quehemos seleccionado. 5mostrar ese tipo de nodo, se crean dinámicamente los diálogos que contendranlos parámetros del nodo. 6. Seguidamente, se ocultará cualquier code existir. 7. Se mostra

155

Page 157: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

8. Almacen l último

CASO DE USO: “Seleccionar un elemento del

aremos este nodo como enodo mostrado y como nodo actualmente seleccionado.

árbol en el visor”

Acción de los Actores Respuesta del sistema 3. El árbol obtiene la lista de los items seleccionados, sin sus descendientes. 4

1. El usuario pulsa sobre un ítem o varios items del árbol y lo selecciona. 2. El usuario pulsa el boton derecho sobre tal selección y elige la opcion de Seleccionar en visor.

. Puesto que los elementos seleccionados ada

s

la

6. Se crea una nueva accion de cambio de selección con la selección anterior y la posterior. 7. Se le pas Handler

del

pueden pertenecer a cualquier vista, para cuno de los elementos seleccionados hallamosu equivalente en el árbol principal. 5. Se comprueba si los items cumplen condicion de la Matriz de Transformación padre, y en caso de que sea necesario, creamos tal matriz.

a la accion a ActiveViewpara ejecutarla.

visor en el árbol”

CASO DE USO: “Seleccionar un elemento

Acción de los Actores Respuesta del sistema 21. El usuario realiza un doble click s

elemento del visor 3D. obre . El sistema comprueba si existe algún

nto

os

los como sus instancias.

en árbol.

CASO DE USO: “Copiar un nodo”

elemento seleccionado. Para este caso sepodría deducir que solo habrá un elemeseleccionado, por tanto tan solo obtendremel primero de la lista. 3. El árbol selecciona el elemento en todosarboles, asi 4. El ActiveView Handler muestra la información del nodo del mismo modo que el caso de uso Seleccionar un ítem del

156

Page 158: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Acción de los Actores Respuesta del sistema

2. El árbol sobre el que estamos realizando la operación dispone de dos referencias a do

ems, el item que estam

1. El usuario arrastra un item del árbol y lo suelta dentro de otro manteniendo pulsada la tecla CTRL.

s os arrastrando y el

nto

e del nodo origen

a que vamos a mover, y del

árbol s

ra de las iteraciones, realizamos editor.

CASO DE USO: “Mover un nodo”

ititem sobre el que hemos soltado. Por taobtiene el nodo del editor asociado a cada uno de estos items y comprueba que el nodo

estino no sea descendientdpara que no se produzcan bucles. 3. El árbol obtiene el índice que ocupa en la lista de TreeBars para obtener el índice l

stancia del iteminitem destino. 4. Para cada una de las réplicas delexistentes realizamos la copia de los itemdesde el origen hacia el destino, y solamente n la primee

tambien la copia del nodo del grafo del

Acción de los Actores Respuesta del sistema 1. El usuario arrastra un item del árbol y lo suelta dentro de otro manteniendo pulsada la tecla CTRL. l

gen para que no se produzcan bucles. 3. El árbol obtiene el índice que ocupa en la lista de TreeBars para obtener el índice la instancia del item que vamos a mover, y del item destino

ol

e

os

CASO DE USO: “Duplicar un nodo”

2. El árbol sobre el que estamos realizando la operación dispone de dos referencias a dos tems, el item que estamos arrastrando y ei

item sobre el que hemos soltado. Por tanto obtiene el nodo del editor asociado a cada uno de estos items y comprueba que el nodo destino no sea descendiente del nodo ori

. 4. Para cada una de las réplicas del árbexistentes realizamos la copia de los items desde el origen hacia el destino, y solamenten la primera de las iteraciones, realizamos tambien la copia del nodo del grafo del editor. 5. Se realiza una llamada Eliminar Nodo sobre el elemento origen (el que habiamarrastrado).

157

Page 159: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Acción de los Actores Respuesta del sistema 2. El árbol sobre el que estamos realizando la operación dispone de dos referencias a dos items, el item que estamos arrastrando

1. Copia al portapapeles un item del árbol utilizando la combinación de teclas CTRL+D.

. El usuario posiciona la selección sobre otro y el

item sobre el que hemos soltado. Por tanto

destino no se gen para que no

m que vamos a mover, y del

em destino.

rigen hacia el destino. Además, en el rimero de los árboles, en cada item del árbol

ento haciendo uso el gestor de nodos, y enlazando estos nuevos

n el

CASO DE USO: “Trasladar una selección”

2item y utiliza la combinacion de teclas

TRL+V para pegar el nodo. obtiene el nodo del editor asociado a cada uno de estos items y comprueba que el nodoC

a descendiente del nodo ori se produzcan bucles.

3. El árbol obtiene el índice que ocupa en la lista de TreeBars para obtener el índice lainstancia del iteit 4. Para cada una de las réplicas del árbol existentes realizamos la copia de los items desde el opque recorramos, crearemos una nueva instancia de copia del elemdnodos tanto en el grafo del editor como egrafo de OpenSceneGraph.

Acción de los Actores Respuesta del sistema . Con el modo trasladar activo, y con uno o ás objetos seleccionados, el usuario coloca

ratón, sin lle

2. Se realiza una llamada a Comenzar Traslación. En ella se calcula la normal al

o en el eje manipulador y se

3. Se actual ón actual

la pantalla asando por la posicion del cursor y el plano

or con centro en el centro de la lección.

una

calcular el posterior incremento de la traslación.

l del plano seleccionado en el eje manipulador.

1mel cursor sobre alguno de estos objetos eleccionados o sobre el eje manipulador y

plano seleccionadalmacena en una variable. s

realiza una pulsación del botón izquierdo del gar a soltarlo.

6. Con el botón izquierdo pulsado, comenzamos a arrastrar la selección por el visor. 14. El usuario suelta el botón izquierdo del ratón.

iza el centro de la selecciy se obtiene en una variable. 4. Se calcula la intersección de la linea imaginaria que formaría una linea que atravesase perpendicularmentepimaginario que formaría el plano del eje manipuladse 5. Se guarda el punto de interseccion en variable que nos servirá de referencia para

7. Se obtiene la norma

158

Page 160: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

tando la

ón

elección.

13. Se actualiza la BoundingBox de la

15. Se almacena un vector de información de los element

uardada.

n

matrices. CASO DE USO: “Eliminar un nodo”

8. Igual que antes, calculamos el punto de interseccion del cursor con el plano imaginariocuya normal hemos calculado en el paso anterior. 9. Se calcula el incremento resposicion calculada en el punto 5 a la posicion de la insersección actual. 10. Para cada uno de los elementos de la selección construimos una matriz de traslacique se multiplicará a la actual matriz de transformación. 11. Se actualiza el centro de la s 12. Se actualiza la posición del eje manipulador en función del centro de la selección.

selección.

os seleccionados. 16. Para cada uno de los objetos de información de seleccion, se actualiza el valor

e la matriz de transformación gd 17. Se crea una nueva acción de modificacióde transformación, almacenando los valoresnteriores y posteriores de las a

Acción de los Actores Respuesta del sistema 3. El árbol obtiene la lista de los items1.

it El usuario pulsa sobre un ítem o varios ems del árbol y los selecciona.

. El usuario pulsa el boton suprimir del

seleccionados, sin sus descendientes. 4. Puesto que los elementos seleccionados pueden pertenecer a cualquier vista, para cada uno de los elementos seleccionados hallamos su equivalente en el árbol principal y los almacenam

tems, os items a

n

2teclado.

os en un vector. 5. Se crea una nueva acción de Borrar I

onde se indican en una lista ldeliminar y se ejecuta.

. La ejecución de esta acción consiste e6

159

Page 161: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

obtener el elemento del grafo de cada itemqueremos eliminar para guardar

que su referencia

caso de un Redo, y eliminar los items de

CASO DE USO: “Añadir un StateAttribute a

entodos sus descendientes en el árbol.

un StateSet de un nodo”

Acción de los Actores Respuesta del sistema . El usuario pulsa el botón Añadir tateAttribute del tercer panel de comandos el (panel de StateSet), habiendo ya un nodo leccionado en el árbol.

. El usuario pulsa aceptar en el diálogo de

confirmación.

5. El usuario elegirá un nombre de un tateAttribute y pulsará Aceptar.

2. En este caso, el nodo no contendrá ningun StateSet por tanto se preguntará al usuario si desea crear uno mediante un diálogo de confirmación. 4. Aparecerá otro diálogo con el listado de los nombres StateAttributes que están registrados en el sistema, obteniendolos del gestor de Objetos. 6. Se comprobará que este StateAttribute no exista ya en este StateSet. 7. Se obtendrá una nueva instancia del StateAttribute, pidiendosela al gestor de Objetos. 8. Se creará una nueva acción de Agregar StateAttribute que agregará esta nueva instancia del StateAttribute al StateSet del nodo seleccionado actualmente.

ASO DE USO: “Añadir un Modo a un StateSet de un nodo”

1Sdse

3

S

C

Acción de los Actores Respuesta del sistema 1. El usuario pulsa el botón Añadir Modo del

rcer panel de comandos del (panel de tateSet), habiendo ya un nodo seleccionado el árbol.

El usuario elegirá un nombre de un Modo y ulsará Aceptar.

2. Aparecerá un diálogo con el listado de los nombres de los Modos que están registrados en el sistema. Este listado será un listado estático puesto que está relacionado con los modos que soporta OpenGL. 4. Se creará un nuevo valor por defecto para el modo. 5. Se creará una nueva acción de Agregar Modo que agregará este nuevo modo al StateSet del nodo seleccionado actualmente.

ASO DE USO: “Modificar un Modo de un StateSet de un nodo”

teSen 3.p

C

160

Page 162: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Acción de los Actores Respuesta del sistema . El usuario pulsa el botón Añadir Modo del rcer panel de comandos del (panel de

), habiendo ya un nodo seleccionado el árbol.

3. El usuario elegirá un nombre de un Modo y pulsará Aceptar.

2. Aparecerá un diálogo con el listado de los nombres de los Modos que están registrados en el sistema. Este listado será un listado estático puesto que está relacionado con los modos que soporta OpenGL. 4. Puesto que el modo ya existe, y tiene un valor o más de flag asignado, lo que haremos será obtener el valor de esta mascara y añadir un nuevo flag, que será el flag por defecto. 5. Obtendremos una lista de los flags que existen ahora en modo, y regeneraremos el listado de modos del StateSet. 6. Se creará una nueva acción de Modificar Modo que establecerá un nuevo valor de la máscara de un modo de un StateSet.

CASO DE USO: “Modificar un Modo de un StateSet de un nodo (Opcion 2)”

1teStateSeten

Acción de los Actores Respuesta del sistema 1. El usuario selecciona uno de los comboboxes que acompañana a cada uno de los nombres de los modos que contiene el StateSet y modifica su valor.

2. Puesto que el modo ya tiene un valor o más de flag asignado, lo que haremos será obtener el valor de esta mascara. 3. Crearemos un nuevo valor de máscara, , eliminando el flag anterior y añadiendo el nuevo flag. 4. Obtendremos una lista de los flags que existen ahora en modo, y regeneraremos el listado de modos del StateSet. 5. Se creará una nueva acción de Modificar Modo que establecerá un nuevo valor de la máscara de un modo de un StateSet.

CASO DE USO: “Cambiar la escena activa”

Acción de los Actores Respuesta del sistema 1. El usuario tiene abiertas varias escenas de manera simultánea en la aplicación y realiza un cambio de escena mediante la combinación de teclado CTRL+TABULADOR.

2. La Vista MFC recibe un mensaje de windows WM_SETFOCUS. 3. Se envia un mensaje a la antigua ventana para que detenga su proceso de render.

161

Page 163: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

4. Se establece el árbol de escena activo indicandole la ID de esta vista. 5. Se le pasa al ActiveViewHandler la informacion sobre los nuevos punteros de la vista actualmente activa, la surface de OpenSceneGraph, la historia, la selección, etc.

162

Page 164: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

PARTE V DISEÑO

163

Page 165: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

164

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Page 166: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE PARTE V........................................................................................................

5.1. Introducción. .................................................................... ¡Error! Marcador no definido. 5.2 Diagrama de componentes del sistema. ............................ ¡Error! Marcador no definido. 5.3 Diseño de las funciones del sistema mediante diagramas de secuencia y colaboración.................................................................................................. ¡Error! Marcador no definido.

5.3.1 Inicio. ......................................................................... ¡Error! Marcador no definido. 5.3.2 Finalizar aplicación .................................................... ¡Error! Marcador no definido. 5.3.3 Nueva Escena ............................................................. ¡Error! Marcador no definido. 5.3.4 Insertar fichero. .......................................................... ¡Error! Marcador no definido. 5.3.5 Modificar Parámetro .................................................. ¡Error! Marcador no definido. 5.3.6 Nuevo árbol ................................................................ ¡Error! Marcador no definido. 5.3.7 Seleccionar elemento en visor.................................... ¡Error! Marcador no definido. 5.3.8 Crear Nodo ................................................................. ¡Error! Marcador no definido. 5.3.9 Seleccionar Elemento en árbol ................................... ¡Error! Marcador no definido. 5.3.10 Undo......................................................................... ¡Error! Marcador no definido. 5.3.11 Seleccionar elementos del árbol en el visor ............. ¡Error! Marcador no definido. 5.3.12 Seleccionar elementos del visor en el árbol ............. ¡Error! Marcador no definido. 5.3.13 Copiar elemento de árbol ......................................... ¡Error! Marcador no definido. 5.3.14 Copiar ítem de un único árbol. ................................. ¡Error! Marcador no definido. 5.3.15 SelectAllInstances .................................................... ¡Error! Marcador no definido. 5.3.16 SelectAllMirrors....................................................... ¡Error! Marcador no definido. 5.3.17 CreateParentMatrixTransform ................................. ¡Error! Marcador no definido. 5.3.18 StartTranslation ........................................................ ¡Error! Marcador no definido. 5.3.19 DoTranslate .............................................................. ¡Error! Marcador no definido. 5.3.20 EndTranslate............................................................. ¡Error! Marcador no definido. 5.3.21 RemoveSceneTree.................................................... ¡Error! Marcador no definido. 5.3.22 Exec.......................................................................... ¡Error! Marcador no definido. 5.3.23 RecursiveCreateDialogs ........................................... ¡Error! Marcador no definido. 5.3.24 CreateDialogs. .......................................................... ¡Error! Marcador no definido. 5.3.25 CreateDialogFromGroup.......................................... ¡Error! Marcador no definido. 5.3.26 RegisterTabOutput (TabOutputManager) ................ ¡Error! Marcador no definido. 5.3.27 RegisterType (ObjectTypeManager)........................ ¡Error! Marcador no definido. 5.3.28 NewInstance ............................................................. ¡Error! Marcador no definido. 5.3.29 CreateTreeNode ....................................................... ¡Error! Marcador no definido. 5.3.30 CargarPlugins ........................................................... ¡Error! Marcador no definido. 5.3.31 Update (Selection)................................................... ¡Error! Marcador no definido. 5.3.32 UpdateAxis............................................................... ¡Error! Marcador no definido. 5.3.33 MapIOControls......................................................... ¡Error! Marcador no definido. 5.3.34 RecursiveOnEndSelection........................................ ¡Error! Marcador no definido. 5.3.35 RecursiveGenerateRollupContent (ObjectType)...... ¡Error! Marcador no definido. 5.3.36 RecursiveClearRollupContent (ObjectType) ........... ¡Error! Marcador no definido. 5.3.37 GenerateRollupContent (TabOutput) ....................... ¡Error! Marcador no definido. 5.3.38 ClearRollupContent (TabOutput)............................. ¡Error! Marcador no definido. 5.3.39 GetParamValue (TabOutput) ................................... ¡Error! Marcador no definido. 5.3.40 SetParamValue (TabOutput) .................................... ¡Error! Marcador no definido. 5.3.41 LookAtSelection....................................................... ¡Error! Marcador no definido. 5.3.42 SetRootNode (ActiveViewHandler)......................... ¡Error! Marcador no definido. 5.3.43 SetRootNode (MultiTreeBar)................................... ¡Error! Marcador no definido.

165

Page 167: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.44 ReplicateSceneTree (MultiTreeBar) ........................ ¡Error! Marcador no definido. 5.3.45 CloneFrom (OSGTreeCtrl) ...................................... ¡Error! Marcador no definido. 5.3.46 DeleteNode (OSGTreeCtrl)...................................... ¡Error! Marcador no definido.

biar escena activa.............................................. ¡Error! Marcador no definido. de estados del sistema...................................... ¡Error! Marcador no definido.

5.4.1 Estado del cursor ........................................................ ¡Error! Marcador no definido.

5.3.47 ActDeleteMultiItem (Action) ................................... ¡Error! Marcador no definido. 5.3.48 DeleteNode (ActiveViewHandler) ........................... ¡Error! Marcador no definido. 5.3.49 Cam

5.4. Diagrama

166

Page 168: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.1. Introducción. Para realizar cualquier software, una vez reconocidos los requisitos, y realizado un estudio de las necesidades del sistema, no es recomendable en ningún caso comenzar la implementación sin realizar primero un diseño que cumpla con las características obtenidas en la fase de análisis. En la fase de diseño, se especifica la arquitectura software del sistema y se ofrece una primera aproximación algorítmica al sistema global, la cual sea capaz de cumplir con todas las conclusiones alcanzadas en el análisis anterior. Para ayudar en esta tarea, y hacer comprensibles las decisiones y conclusiones obtenidas, se utilizaran los diagramas UML que correspondan a cada parte del diseño. Siguiendo las conclusiones de la fase de análisis, se realizará el diseño de las funciones más importantes del sistema, y no todas ellas debido a que podríamos extendernos excesivamente, explicando detalladamente los pasos a seguir para llevarlas a cabo en los casos que sean necesarios. Al finalizar la fase de diseño, ya estarán definidas todas las funciones, clases, y directrices necesarias para realizar la implementación.

5.2 Diagrama de componentes del sistema.

Figura 5-1. Diagrama de componentes del sistema

En este diagrama podemos apreciar una vista global de la arquitectura de la aplicación y de su conexión con los demás componentes. El fichero ejecutable está generado mediante el uso de la librería MFC (Microsoft Foundation Classes), y hace uso de la librería gráfica OpenSceneGraph, que a su vez está basada en la librería OpenGL. Además, la aplicación se complementa con la carga en memoria de fragmentos de código añadidos en tiempo de ejecución, que son las DLLs, que a su vez pueden acceder a la aplicación.

167

Page 169: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3 Diseño de las funciones del sistema mediante diagramas de secuencia y colaboración.

5.3.1 Inicio. Es la función que inicia todos los datos del programa. Al arrancar la aplicación se iniciará el único objeto global de la aplicación (ActiveViewHandler), y se generará una vista vacía, la cual iniciará los datos del grafo por defecto. Cuando el ActiveViewHandler arranque iniciará todos los gestores de la aplicación, se crearan las barras de herramientas (la principal y la de creación de nodos) iniciará la barra principal de paneles de comandos y el árbol que contendrá la representación del grafo, y además iniciará los tipos de datos que soporta la aplicación añadiéndolos a sus respectivos gestores. Es en esta fase donde se realizará también la carga de los plugins. Al cargar los plugins la aplicación buscará en el directorio de plugins ficheros dll, estos ficheros los intentará cargar uno por uno, extrayendo información necesaria de cada uno de ellos, y registrando en el sistema los objetos que en cada plugin encuentre. Los tipos de Objeto que iniciará la aplicación serán los siguientes:

• ObjTypeStateSet • ObjTypeDrwStateSet • ObjTypeCounter • ObjTypeVariableRateCounter • ObjTypeRandomRateCounter • ObjTypeConstantRateCounter • ObjTypeDrawable • ObjTypeShapeDrawable • ObjTypeGeometry • ObjTypeParticle • ObjTypeParticleSystem • ObjTypeText

Los tipos de StateAttribute que iniciará la aplicación:

• AttTypeFog • AttTypeMaterial • AttTypeBlendFunc • AttTypeLight • AttTypeTexEnv • AttTypeTexGen • AttTypeTexture • AttTypeTexture2D • AttTypeVertexProgram • AttTypeFragmentProgram

Y por último, los tipos de nodo que iniciará serán:

• TypeNode • TypeGroup • TypeLOD

168

Page 170: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• TypePagedLOD • TypeSwitch • TypeGeode • TypeSequence • TypeBillboard • TypeTransform • TypeDOFTransform • TypePositionAttitudeTransform • TypeMatrixTransform • TypeAutoTransform • TypeLightSource • TypeParticleSystemUpdater • TypeParticleProcessor • TypeEmitter • TypeModularEmitter • TypeFXEffect • TypeFXCartoon • TypeFXSpecularHighlights • TypeFXBumpMapping

169

Page 171: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.2 Finalizar aplicación Cuando el usuario salga de la aplicación, esta generará un mensaje de cierre, que llegará a su vez a todas las vistas MFC abiertas. Cuando una vista va a ser cerrada, se liberan los recursos reservados por OpenSceneGraph para la vista, así como se vacía el contenido de la Historia y se avisa al ActiveViewHandler que tal vista va a ser cerrada para que realice también sus operaciones. Aquí es donde se avisa al MultiTreeBar que libere toda su memoria, puesto que cada TreeBar contiene la información del grafo que hay cargado, incluso tablas hash que contenía cada una de ellas.

170

Page 172: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.3 Nueva Escena Al iniciar una nueva escena, la aplicación crea una nueva Vista y su respectiva clase Documento de MFC. Esta vista es la que inicia las estructuras de datos necesarias para una escena (al igual que al cargar una escena). Se iniciará un grafo por defecto para colgar esta información. El grafo no deberá ser la escena en sí, puesto que el editor necesita más elementos para visualizar de manera auxiliar. Por tanto, el grafo inicial (raíz) estará dividido en dos ramas principales, la primera será la escena que vamos a crear, y en la segunda colgaremos aquellos nodos que nos serán útiles en el editor para manipular otros nodos, como puede ser el eje manipulador, las cajas de selección de objetos, e incluso la rejilla. Una vez hecho esto, deberemos añadir una nueva escena al editor. Esto implica crear nuestro propio grafo de escena (copia del de OpenSceneGraph), y añadir un nuevo control de árbol en cada una de las TreeBar abiertas en la aplicación, clonando su contenido tantas veces como sea necesario. También aquí será donde inicialicemos los datos de la selección, y el StateSet global, que nos servirá para cambiar el modo de visualización de la escena.

171

Page 173: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.4 Insertar fichero. Cuando el usuario desea colgar de una rama un grafo completo, almacenado en el disco duro, entonces se invocará esta función. El usuario seleccionará del disco duro un fichero compatible con la aplicación, que dará paso a un sub-grafo de escena, que colgará del nodo seleccionado actualmente en el árbol. Esto se consigue con una simple llamada a SetRootNode, que nos permite establecer un grafo colgando de cualquier elemento de un árbol.

172

Page 174: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.5 Modificar Parámetro Cuando un usuario manipula alguno de los controles del panel de comandos donde aparecen los grupos de parámetros referentes a un ObjectType, a un NodeType, o incluso un TabOutput, se realiza una llamada interna, que hace que se modifiquen algunos valores (por ejemplo, un spinner con un descriptor tipo float asociado hará que al pulsar la flecha superior recoja el contenido de la caja de texto asociada al spinner e incremente en una décima su valor) y después se realice una llamada a la notificación de parámetro modificado. De esta manera el desarrollador de TabOutputs podrá hacer las gestiones necesarias para modificar la estructura de datos asociada. Del mismo modo, si el ObjectType está siendo adjuntado por otro, se enviará una notificación al elemento adjuntador de que uno de sus elementos adjuntos acaba de modificar un dato.

5.3.6 Nuevo árbol Esta función crea una réplica de la barra del árbol. Lo que esta función hace es crear una nueva TreeBar, inicialmente vacía, y replicar todos y cada uno de las escenas que contiene esta TreeBar en la que acabamos de crear.

173

Page 175: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.7 Seleccionar elemento en visor. Para seleccionar un elemento en el visor tendremos que obtener la intersección del ratón con la escena. Esto se hará mediante un objeto de OpenSceneGraph llamado IntersectVisitor que nos devolverá un listado de las colisiones encontradas entre una línea y en el grafo que le indiquemos. Esta intersección tan solo la comprobaremos desde la rama de la escena (recordemos que teníamos otra sub-rama principal con la información auxiliar del editor). Puesto que solo nos interesa la más cercana al usuario, elegiremos la primera. Este objeto lo obtendremos en forma de NodePath. Un NodePath es una lista de nodos que define un camino único en el grafo desde un nodo origen hasta una hoja. De este modo obtendremos el ítem que queremos seleccionar, e invocaremos la función Seleccionar, que insertará una nueva acción de cambio de selección en la historia.

174

Page 176: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.8 Crear Nodo Esta función crea un nodo a partir de un elemento seleccionado en el interfaz. El creador de nodos es un objeto derivado de TabOutput, por tanto, cuando el usuario pulse el botón de crear el nodo, se invocará la función de ParamModified de TabOutput. De este modo sabremos que se ha pulsado el botón Crear, y podremos obtener el valor del elemento seleccionado de manera sencilla con una simple llamada al GetValue que nos proporciona esta clase. Por tanto, puesto que ya tenemos el nombre del nodo que queremos crear, le asignaremos esta tarea al ActiveViewHandler, que se pondrá en contacto con el gestor de Nodos para que le facilite una nueva instancia del nodo que nos interesa. La inserción del nuevo nodo pasará por medio de una acción que quedará registrada en el sistema para su posterior posible inversión.

175

Page 177: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.9 Seleccionar Elemento en árbol Está función se invoca cuando se selecciona un elemento en el árbol, o su selección cambia. Al seleccionar un objeto en el árbol se seleccionan todas las instancias de ese mismo elemento, es decir, todos aquellos ítems del árbol que pertenecen al mismo nodo del grafo poniendo el texto de esos ítems en negrita. Seguidamente, se seleccionan todos los ítems equivalentes al ítem seleccionado, en todas las demás TreeBar abiertas, en color rojo. De esta manera el usuario podrá identificar rápidamente el ítem que acaba de seleccionar en cualquier otra vista abierta del árbol. Acto seguido, pasaremos a mostrar la información del nodo asociado a tal ítem en el panel del comandos. Para ello, si es la primera vez que se muestra el tipo de nodo, se crean sus diálogos, si existía algún otro mostrado se oculta y después se muestran los diálogos del tipo seleccionado. Almacenaremos en una variable un puntero al nodo del grafo del editor seleccionado, y un puntero al último nodo, y mostraremos sus datos en los controles.

176

Page 178: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.10 Undo. La función Undo o Deshacer se invoca desde la vista activa. Esta realiza una llamada directa a la función Undo de gestor de Historia, que a su vez realiza una llamada a la función Undo de la acción actual apuntada por el gestor. Después de ello, actualiza la posición del cursor, retrocediéndola un lugar, pero conservando las acciones posteriores. Puesto que la función undo puede haber modificado datos de la salida del interfaz, forzaremos una llamada a mostrar los datos del nodo actualmente seleccionado en el árbol.

5.3.11 Seleccionar elementos del árbol en el visor Esta función es invocada desde el árbol desde el que se llama a esta función. Lo que hacemos es obtener una lista de los ítems seleccionados en el árbol (sin sus descendientes). Después obtenemos un puntero al primero de los árboles de la escena, para trabajar sobre él. Esto lo hacemos así porque en la información de selección de objetos siempre haremos referencia a

177

Page 179: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

objetos del primer árbol, puesto que un mismo ítem en árboles distintos tendrá referencias distintas. Por último, indicaremos al gestor de selección la lista de los objetos que queremos seleccionar. Este gestor comprobará previamente si los objetos que vamos a seleccionar contienen Matrices de Transformación como alguno de sus padres, y en caso de que sea necesario, creará una MatrixTransform de OpenSceneGraph. Esta es una medida que adoptamos para poder aplicar transformaciones a los objetos una vez seleccionados.

5.3.12 Seleccionar elementos del visor en el árbol Esta función es complementaria a la anterior. En este caso tenemos un objeto seleccionado en el visor (por tanto, nos despreocupamos de si existe o no su matriz de transformación, puesto que esa comprobación ya se hizo al seleccionar el objeto), y queremos seleccionarlo en el árbol. En primer lugar obtenemos la lista de selección de objetos del visor, este será un vector de elementos, pero en este proceso nosotros solo vamos a permitir seleccionar un elemento en el árbol, para mostrar sus propiedades en el panel de comandos, por lo que tan solo obtendremos en primer elemento de la lista. Esto implica el cambio de selección de un objeto en el árbol, que ya hemos explicado anteriormente: se seleccionan todas las instancias del objeto, así como sus equivalentes en los demás árboles y se muestra la información del nodo en el panel de comandos. Por último, hacemos que se muestre automáticamente la segunda pestaña del panel de comandos, que es la que muestra la información de los parámetros del nodo seleccionado en el árbol.

178

Page 180: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.13 Copiar elemento de árbol Esta función toma un elemento origen y un elemento destino y copia el elemento origen como hijo del elemento destino. Para ello en primer lugar obtiene el nodo del grafo del editor, tanto del ítem origen como el destino. Después obtiene el índice de la TreeBar sobre la que estamos realizando la operación, para así obtener el índice de la instancia del elemento origen, así como el índice del la instancia del elemento destino. Este índice de instancias nos servirá para identificar la misma instancia en todas las TreeBar, puesto que tendremos que repetir la misma operación de copiar para cada una de ellas.

5.3.14 Copiar ítem de un único árbol. La función anterior hacía uso de esta función para copiar el ítem en cada árbol replicado. En primer lugar lo que hacemos es obtener el nombre del ítem origen, y crear el nuevo ítem con tal nombre, colgando del padre indicado. Obtendremos el nodo asociado al ítem origen y al destino, y le daremos al ActiveViewHandler la tarea de realizar la copia a nivel del grafo. En este caso puesto que estamos haciendo una instanciación, esta copia solo consistirá en añadir un nuevo padre al nodo que queremos copiar. Por último deberemos añadir a las tablas hash del árbol el nuevo ítem, para asociarlo al nodo del grafo del editor. Si el nodo origen tiene descendientes, deberemos realizar una llamada recursiva a esta misma función para cada uno de ellos, estableciendo como padre en la llamada el nodo origen de la función actual.

179

Page 181: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.15 SelectAllInstances Esta función es llamada desde el mismo árbol que contiene una escena, y resalta en negrita todas las instancias de un nodo. Puesto que el nodo del editor contiene referencias a las distintas instancias, así como sus mirrors, accederemos a este listado inmediatamente, entrando en un bucle que para cada una de las instancias, cambie el texto a negrita.

5.3.16 SelectAllMirrors Esta función la invoca el propio árbol, pero accede a todas las demás réplicas del árbol en el editor. A partir del nodo del editor sobre el que queremos aplicar la función, debemos obtener el índice de la instancia. Con este índice identificaremos automáticamente en cada uno de los árboles el ítem equivalente, que colorearemos de rojo.

180

Page 182: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.17 CreateParentMatrixTransform Esta función se llama automáticamente al seleccionar un objeto. La razón de ello es que al seleccionar un objeto, el usuario está indicando en cierto modo su intención de aplicarle alguna transformación. Esta transformación solo se puede llevar a cabo sobre una Matriz de Transformación que contenga al nodo como uno de sus descendientes. Por tanto, lo que hará esta función será comprobar si existe una matriz de transformación como padre del nodo, y además, que esa transformación solo tenga a ese nodo como hijo. En caso contrario, creamos un nuevo nodo tipo Matriz de Transformación y lo “intercalamos” entre el nodo que queremos transformar y su padre actual.

5.3.18 StartTranslation Esta función y las dos siguientes solo las explicaremos para la Traslación, pues que para el escalado y la rotación siguen comportamientos similares. Esta función es como el Setup o la puesta a punto de la traslación. Se llama a esta función para realizar los ajustes o actualizaciones necesarias o consultar los datos necesarios para prepararse para comenzar la transformación. Por ejemplo, aquí recalcularemos la BoundingBox de la selección y deberemos guardar la posición del centro geométrico de la selección, lo cual nos servirá mas adelante para almacenar correctamente la transformación como una función invertible en la Historia.

181

Page 183: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.19 DoTranslate Es el proceso de trasladar en sí. Esta es la función que realiza la traslación a medida que vamos desplazando el ratón, aunque realmente la acción no se podrá considerar como terminada hasta que soltemos el ratón. Esta es la función que realiza la traslación, aunque realmente la acción no se podrá considerar como terminada hasta que soltemos el ratón. En este paso se aplica la misma transformación a todos los objetos de la selección en función del desplazamiento del cursor sobre la pantalla. Esta transformación tiene la particularidad de que requiere algunos cálculos extraordinarios para calcular el incremento que vamos a aplicar a la traslación, ya que calcularemos un plano imaginario que sea paralelo al plano seleccionado en el eje manipulador, y que pase por el centro de la selección, de esta manera, intersectando una línea imaginaria desde el cursor hacia este plano obtendremos el punto donde queremos desplazar el objeto, y así calcularemos el incremento a aplicar como traslación. Una vez hecho esto, deberemos también actualizar las cajas de selección de los objetos seleccionados, puesto que las transformaciones deben afectarles por igual, así como actualizar su BoundingBox y la posición del eje manipulador.

5.3.20 EndTranslate Este es el paso que da por finalizada la traslación de la selección. Es aquí donde se actualiza la información de la selección, como por ejemplo los valores de las matrices auxiliares que se utilizan para almacenar información que luego servirán para almacenar la acción invertible de la transformación. También aquí actualizaremos la BoundingBox de la selección y actualizaremos la posición del eje manipulador.

182

Page 184: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.21 RemoveSceneTree Esta llamada la realiza el objeto MultiTree. Se invoca al cerrar una escena. Este objeto lo que hace es recorrer todas las TreeBar abiertas, eliminando el objeto del árbol, y liberando así su memoria.

5.3.22 Exec Esta función la proporciona el ActiveViewHandler, y se utiliza para ejecutar cualquier acción en el sistema. Lo que esta función hace es ejecutar la acción pasada por referencia, y pasársela al gestor de historia para añadirla. El gestor de historia comprobará si la posición actual de la historia está colocada al final, y en caso afirmativo, insertará la acción, incrementando esta posición. En caso de no ser así, todas las acciones posteriores a las de la posición actual, deberán ser eliminadas, y después de ello, se insertará la acción, incrementando la posición actual en uno.

183

Page 185: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.23 RecursiveCreateDialogs Esta función se invoca la primera vez que queremos mostrar un ObjectType por el interfaz, y es invocada por el gestor de parámetros. Esta acción simplemente crea en memoria los diálogos que formarán esta estructura. La primera acción a realizar es crear los diálogos del ObjectType a partir de su grupo de parámetros, ya definido, realizando una llamada recursiva en caso de que existe un ObjectType padre definido y este no haya creado tampoco sus diálogos. Después de esto, se comprueba si existen ObjectTypes adjuntos, y se realiza la misma llamada a esta misma función para cada uno de ellos.

5.3.24 CreateDialogs. Es la función que invoca la función recursiva anterior. Aquí se obtiene el vector de grupos de parámetros del objeto, y para cada uno d ellos, se crea un diálogo independiente, indicando el Rollup en el que lo mostraremos. Cada pestaña del panel de comandos tiene un Rollup asociado, por lo que el Rollup equivale a la pestaña del panel de comandos donde queremos que se creen los diálogos.

184

Page 186: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.25 CreateDialogFromGroup. Esta función es invocada por la función anterior y es la que crea realmente el diálogo. En un principio se crea un diálogo dinámicamente, inicialmente vacío, y vamos recorriendo cada uno de los descriptores de grupo del grupo de parámetros. Cada uno de estos descriptores tendrá unas características por lo que podremos crear distintos controles en función del tipo de descriptor. Así pues, donde en el diagrama de colaboración podemos apreciar CrearControl, deberá estar sustituido por una llamada a la función Crear del control pertinente. Vamos a nombrar todas estas funciones, pero no entraremos en detalles de ninguna de ellas:

• CreateButton

• CreateStatic

• CreateTextbox

• CreateEditbox

• CreateSpinner

• CreateCheckbox

• CreateCheckButton

• CreateCombobox

• CreateRadio

• CreateRange

• CreateVector3

• CreateVector4

• CreateColorSwatch

• CreateListbox

• CreateGridCtrl

185

Page 187: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.26 RegisterTabOutput (TabOutputManager) Esta función es invocada por el gestor de TabOutputs. El gestor mantendrá un vector de los objetos registrados, así como una tabla hash que relacione el nombre del objeto con su instancia. Por último, realizará una llamada a MapearParamGroups, que generará los vectores de grupos de parámetros que habrá implementados en la clase TabOutput.

5.3.27 RegisterType (ObjectTypeManager) Esta función la invoca el gestor de ObjectTypes. La función RegisterNodeType es similar y no hará falta explicarla. Al registrar un ObjectType lo primero que haremos será obtener el nombre del ObjectType padre. Si existe tal, buscamos si está registrado, y establecemos el puntero de su tipo padre. Por último, al igual que en RegisterTabOutput, realizamos una llamada a MapearParamGroups, y añadimos el objeto a los índices del gestor, para poder realizar búsquedas rápidas por su nombre.

186

Page 188: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.28 NewInstance Esta función es propia del gestor de ObjectTypes (aunque también del gestor de NodeTypes, pero solo explicaremos este caso). Cuando tengamos un ObjectType registrado y queramos obtener una nueva instancia del objeto al que representa, podremos solicitarle una indicándole el nombre del tipo de objeto.

5.3.29 CreateTreeNode Esta función permite crear un nuevo nodo en el grafo de la escena activa, indicando el nombre del nodo. Para ello necesitaremos una nueva instancia del nodo OpenSceneGraph. Haremos uso de la llamada a NewInstance que nos proporciona el gestor de Nodos para obtener una nueva instancia del nodo, y crearemos un nuevo nodo para nuestro grafo del editor (TreeNodeInfo). Esta estructura contendrá información como un puntero al nodo OpenSceneGraph que acabamos de crear, y un puntero al NodeType que identifica al nodo.

187

Page 189: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.30 CargarPlugins Esta función es invocada al iniciar el TabOutput de plugins, que es iniciado a su vez al iniciar la aplicación. En primer lugar cargamos el fichero DLL, obteniendo el manejador del mismo. Creamos una nueva estructura de datos (PluginInfo) que contendrá la información del plugin que carguemos, para que el gestor de plugins la almacene. Consultaremos el número de clases del plugin, así como la descripción del plugin y obtendremos una instancia de cada una de las clases implementadas en el plugin. Toda esta información se guardará en el objeto PluginInfo, que guardaremos en una tabla hash, para posteriormente poder consultar mediante el nombre del fichero.

5.3.31 Update (Selection).

188

Page 190: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Lo que esta función hace realmente es actualizar el cursor según su posición, o el eje manipulador, además del estado del cursor. El estado del cursor define si el cursor está encima de algún objeto, o encima de algún otro elemento, como puede ser el eje manipulador. En primer lugar se comprueba si existe algún objeto seleccionado en la escena, en ese caso sabremos que el eje manipulador estará mostrado, por tanto obtenemos si existe alguna colisión del cursor con tal eje. Si el cursor no esta encima de ningún elemento del eje manipulador entonces se comprueba si existe colisión con alguno de los objetos, actualizando el cursor y el estado del cursor en función de si el eje está o no seleccionado, y de la transformación que estemos llevando a cabo.

5.3.32 UpdateAxis Esta función es invocada por la selección. Esta función realiza las mismas comprobaciones que la anterior, pero únicamente comprueba si existe alguna intersección del cursor del ratón con el eje manipulador, obteniendo exactamente con qué elemento del eje intersecciona y actualizando el estado del mismo, y su apariencia (por ejemplo, resaltando con más brillo el eje o el plano que estamos seleccionando en el eje manipulador). De esta manera podremos consultar en cualquier momento qué ejes se encuentran seleccionados en cada momento.

189

Page 191: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.33 MapIOControls Esta función (nombrada anteriormente como MapearParamGroups) propia de la clase TabOutput, y se invoca al registrar un TabOutput, ObjectType, NodeType o AtributeType. Realiza la llamada CreateIOControls del TabOutput en cuestión. Esta función es una función virtual pura que deber Una vez hecha la llamada a CreateIOControls, se mapea en la tablas hash el id de cada uno de sus descriptores de los grupos de parámetros asociando como clave en descriptor en sí. De esta manera tenemos una tabla hash que asocia Ids de parámetros con sus respectivos descriptores.

5.3.34 RecursiveOnEndSelection Esta función se invoca como notificación a un ObjectType para indicar que sus datos van a dejar de motrarse en el panel de comandos del interfaz. Primero de todo, se realiza una llamada recursiva sobre su padre, en caso de existir.

190

Page 192: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Para cada uno de los objetos, también se realizará una notificación recursiva a cada uno de los objetos adjuntos. Para finalizar, se desvincula el objeto de cualquier adjuntador (que no adjunto), y se establece el objeto al q representa como null.

5.3.35 RecursiveGenerateRollupContent (ObjectType) Esta función se llama cuando se necesita mostrar el contenido del diálogo de un ObjectType en el panel de comandos. Lo único que hace esta función es llamarse recursivamente para sus parientes, y generar el contenido del Rollup (un diálogo desplazable).

5.3.36 RecursiveClearRollupContent (ObjectType) Realiza el proceso inverso a la función anterior, es decir, elimina los Rollups del panel de comandos del interfaz, pero además también realiza la misma llamada para cada uno de los adjuntos y se desvincula del adjuntador actual.

191

Page 193: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.37 GenerateRollupContent (TabOutput) Esta función es invocada directamente por la función de mostrar un TabOutput. Cuando hablamos del contenido, hablamos del contenido final que aparecerá en el interfaz, mas concretamente sobre el panel de comandos. Consiste en generar una página desplegable o Rollup a partir de un diálogo ya generado. Una vez hecho esto, el diálogo estará contenido en un desplegable que el usuario podrá plegar siempre que quiera tan solo pulsando un botón, para ahorrar espacio en el interfaz, y desplegar cuando quiera mostrar su contenido de nuevo. De entre la información necesaria para generar un grupo desplegable está el diálogo, el nombre que identificará al grupo, y además si el grupo podrá ser o no desplegable, puesto que es opcional, y si se mostrará inicialmente expandido o contraído.

5.3.38 ClearRollupContent (TabOutput) Es la función inversa a la anterior. Suele invocarse cuando queremos limpiar la salida del panel de comandos, bien para dejarlo vacío, bien para dar paso a generar el contenido de otro TabOutput. Esta llamada desvincula el diálogo que identifica en grupo de parámetros del Rollup en el que está contenido, pero no destruye en diálogo que hemos creado de la memoria. El primer paso es marcar el TabOutput como oculto, y además marcar que sus datos no están mostrados. Para cada uno de los grupos de parámetros que contiene el TabOutput obtendremos el tab que ocupa en el panel de comandos, y obtendremos el puntero al diálogo dinámico del grupo. Con el tab, obtendremos el Rollup asociado al tab, y así sabremos si el diálogo está o no expandido, para almacenar este estado. Después eliminaremos la página del Rollup para que deje de mostrarse su diálogo.

192

Page 194: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.39 GetParamValue (TabOutput) Esta es la función que proporciona TabOutput para que los desarrolladores puedan establecer un contacto con los controles generados en el panel de comandos. A esta función se le pasan dos parámetros, uno con el ID del parámetro a consultar, y un segundo parámetro que es una variable donde almacenaremos el valor de tal parámetro. En este caso vamos a mostrar el comportamiento de la función para obtener el valor de un parámetro almacenándolo en una variable entera. En primer lugar obtendremos el descriptor del parámetro asociado al ID del parámetro que queremos, sabiendo esto, obtendremos el grupo de parámetros al que pertenece el descriptor, y a su vez podremos obtener un puntero al diálogo que lo representa. Puesto que el descriptor del parámetro también guarda el ID del control asociado en el diálogo, podremos obtener el valor que almacena el control mediante la llamada a GetDlgItemInt(id).

5.3.40 SetParamValue (TabOutput) Esta es la función que proporciona TabOutput para que los desarrolladores puedan establecer un contacto con los controles generados en el panel de comandos.

193

Page 195: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

A esta función se le pasan dos parámetros, uno con el ID del parámetro a modificar, y un segundo parámetro que es una variable con el valor del parámetro. En este caso vamos a mostrar el comportamiento de la función para establecer el valor de un parámetro mediante una variable entera. En primer lugar obtendremos el descriptor del parámetro asociado al ID del parámetro que queremos, sabiendo esto, obtendremos el grupo de parámetros al que pertenece el descriptor, y a su vez podremos obtener un puntero al diálogo que lo representa. Puesto que el descriptor del parámetro también guarda el ID del control asociado en el diálogo, podremos establecer el valor que almacena el control mediante la llamada a SetDlgItemInt(id, value).

5.3.41 LookAtSelection Esta función la invoca el objeto KeyboardMouse, ya que es el objeto que contiene el TrackBall de OpenSceneGraph. El TrackBall es el objeto que nos permite modificar la cámara del visor. LookAtSelection centra la vista en el centro geométrico de la selección actual del visor. Para ello obtenemos el punto central de la selección, y los valores de eye, center y up que actualmente contiene el TrackBall. Con estos valores construimos una matriz usando el mismo valor de eye, y up, pero con el valor de centro como valor del punto central de la selección. Por último establecemos esta matriz como la matriz del TrackBall.

5.3.42 SetRootNode (ActiveViewHandler) Permite establecer el nodo raíz es una escena en todas las vistas de árbol abiertas. La única tarea de ActiveViewHandler es realizar la conversión del ID de la escena a su índice. Esta conversión es necesaria ya que cada escena está almacenada en un índice de un vector, que puede ir cambiando a medida que se van insertando o eliminando escenas de la aplicación.

194

Page 196: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Por último, se realiza la llamada SetRootNode al objeto MultiTree, indicando que vamos a establecer el nodo como nodo raíz (parámetro NULL).

5.3.43 SetRootNode (MultiTreeBar) Esta llamada puede provenir tanto de ActiveViewHandler, como de la inserción de un subgrafo desde un fichero. Es por ello que aquí se establece como parámetro de entrada el ítem sobre el que debemos establecer el grafo (no necesariamente el raíz). Permite establecer un grafo colgando de un elemento de un árbol. Este elemento puede ser la raíz del árbol, por lo que el árbol no debe necesariamente contener algún elemento. Esta función internamente establece el grafo de escena sobre una de las vistas del árbol (suponiendo que haya varias simultáneas) y realiza réplicas del mismo sobre las demás. En la subsiguiente llamada a SetRootNode de TreeBar, para recorrer el grafo y construir el árbol se utiliza la estructura NodeVisitor proporcionada por OpenSceneGraph que nos permite seguir un orden en los nodos del grafo, de esta manera iremos construyendo el subárbol sobre el árbol que queremos y completando nuestro grafo interno. Esta función solo permitirá insertar nodos dentro del elemento que queramos, si este elemento pertenece a un nodo derivado de la clase Group de OpenSceneGraph.

195

Page 197: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.44 ReplicateSceneTree (MultiTreeBar) Una escena identifica un grafo de escena. En una sola TreeBar puede haber varias escenas distintas, cada una de ellas esta representada mediante un árbol. Por tanto, replicar una escena desde un TreeBar a otro consistirá en clonar el árbol. A la vez que se clona el contenido del árbol, se deberá de añadir la información necesaria al grafo de escena del editor para identificar los elementos del árbol por sus nodos. Esto se realizará con la ayuda de un NodeVisitor.

5.3.45 CloneFrom (OSGTreeCtrl) Esta función clona un árbol a partir de otro. Este árbol puede ser clonado sólo a partir de una rama del árbol origen, en cuyo caso, su padre deberá existir en el árbol destino como ítem equivalente o mirror. La replica o clonación se realiza elemento a elemento, respetando el orden de los nodos, y actualizando los datos de los nodos del grafo del editor, puesto que el grafo del editor contiene enlaces a los ítems de las distintas instancias del nodo en el árbol, así como sus distintos mirrors.

196

Page 198: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.46 DeleteNode (OSGTreeCtrl) Para eliminar uno o varios ítems del árbol lo haremos mediante una acción. Esta acción necesita una lista de los ítems de la primera de las vistas de árbol que queremos eliminar. Por tanto, para cada elemento de la lista de ítems a eliminar, obtenemos su mirror (su equivalente) en el primero de los árboles, y así generamos esta nueva lista. Es ahora cuando podemos crear y ejecutar esta nueva acción, ActDeleteMultiItem, facilitándole esta nueva lista de ítems a eliminar.

5.3.47 ActDeleteMultiItem (Action) Es la acción que ejecuta la función anterior. La acción almacena internamente una lista de los TreeNodeInfo (nodo del grafo del editor) que vamos a eliminar, para mantenerlos en memoria mientras la acción pueda deshacerse.

197

Page 199: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Después, invocamos a la función eliminar sobre cada uno de los elementos del árbol, propia la de clase OSGTreeCtrl.

5.3.48 DeleteNode (ActiveViewHandler) Esta función elimina un nodo y sus descendientes a partir de una referencia a un ítem de un árbol, y el índice del TreeBar al que pertenece. En primer lugar deberemos deseleccionar todos los mirrors del ítem y todas sus instancias del árbol, puesto que va a ser eliminado. Después obtendremos su nodo asociado, tanto del ítem como de su padre, y estableceremos que el TreeNodeInfo seleccionado (el nodo del grafo del editor) sea NULL. Por tanto deberemos de limpiar el panel de comandos para eliminar cualquier contenido que se esté mostrando del nodo que vamos a eliminar. Por último tendremos que desvincularlo de su padre, eliminar el nodo del grafo OpenSceneGraph, y eliminar cada unos de los hijos. Y en caso de que el ítem sea la última instancia disponible en el grafo, eliminar el nodo del grafo del editor.

198

Page 200: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

5.3.49 Cambiar escena activa Se produce esta llamada a esta función cuando el usuario realiza un cambio de la escena activa, ya sea mediante alguna combinación del teclado o usando el menú de selección de ventanas. Al cambiar de escena activa se deben de actualizar las referencias la superficie de render, la historia actual, el grafo de escena y los datos de la selección, puesto que son independientes en cada escena, y cada escena tiene las suyas. La función nos llegará a la vista activa como un SetFocus, y un puntero a la ventana de la que proviene. Nosotros entonces Enviaremos un mensaje a la anterior ventana para que detenga su proceso de Render, y avisaremos al ActiveViewHandler de que la escena que va a pasar a estar activa es esta, facilitándole los punteros necesarios.

5.4. Diagrama de estados del sistema

5.4.1 Estado del cursor El cursor puede tomar cuatro distintos estados en función del objeto sobre el que se encuentre, puede ser un objeto seleccionado, un objeto no seleccionado, el eje manipulador, y el vacío. En

199

Page 201: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

primer lugar el sistema comprueba si se está colisionando con el eje manipulador, y en caso de no estarlo, se pasa a comprobar el resto del la escena.

200

Page 202: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

PARTE VI IMPLEMENTACION

201

Page 203: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

202

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Page 204: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE PARTE VI...................................................................................................... 6.1 Introducción ..............................................¡Error! Marcador no definido.

6.2 Parametrización de datos................................................... ¡Error! Marcador no definido. 6.2.1 El descriptor de parámetros (OSGParamGroupDesc). .............. ¡Error! Marcador no definido. 6.2.2 Los grupos de parámetros (OSGParamGroup) .......... ¡Error! Marcador no definido. 6.2.3 El gestor de parámetros (OSGParamManager) ......... ¡Error! Marcador no definido. 6.2.4 El control ColorSwatch .............................................. ¡Error! Marcador no definido. 6.2.5 Las clases OSGTabOutput y OSGTabOutputManager.............. ¡Error! Marcador no definido. 6.2.6 Un ejemplo de OSGTabOutput : la clase OutCreateNodes........ ¡Error! Marcador no definido. 6.2.7 Las clases OSGObjectType y OSGObjectTypeManager........... ¡Error! Marcador no definido. 6.2.8 Un ejemplo de OSGObjectType: TypeDrawable....... ¡Error! Marcador no definido.

6.3 Implementación del árbol del grafo de escena. ................. ¡Error! Marcador no definido. 6.3.1 La clase TreeNodeInfo .............................................. ¡Error! Marcador no definido. 6.3.2 La clase CEditTreeCtrl............................................... ¡Error! Marcador no definido. 6.3.3 La clase CEditTreeCtrlEx .......................................... ¡Error! Marcador no definido. 6.3.4 La clase COSGTreeCtrl ............................................. ¡Error! Marcador no definido. 6.3.5 CTreeBar y CmultiTreeBar. ....................................... ¡Error! Marcador no definido.

6.4 Interacción con el visor 3D ............................................... ¡Error! Marcador no definido. 6.4.1 La clase OSGSelection............................................... ¡Error! Marcador no definido. 6.4.2 La clase OSGAxisManipulator ................................. ¡Error! Marcador no definido. 6.4.3 La clase MFCKeyboardMouseCallback .................... ¡Error! Marcador no definido.

6.5 El sistema de deshacer / rehacer........................................ ¡Error! Marcador no definido. 6.5.1 La clase OSGAction................................................... ¡Error! Marcador no definido. 6.5.2 La clase OSGHistory.................................................. ¡Error! Marcador no definido.

6.6 El sistema gestor de plugins .............................................. ¡Error! Marcador no definido. 6.6.1 El plugin Cartoon ....................................................... ¡Error! Marcador no definido. 6.6.2 La clase OSGPluginManager ..................................... ¡Error! Marcador no definido. 6.6.3 La clase OutPlugins.................................................... ¡Error! Marcador no definido.

6.7 El manejador de la vista activa y las clases MFC ............. ¡Error! Marcador no definido. 6.7.1 La clase OSGActiveViewHandler.............................. ¡Error! Marcador no definido. 6.7.2 La clase COSGWorldView ........................................ ¡Error! Marcador no definido.

6.8 Problemas y “tips” de implementación ............................. ¡Error! Marcador no definido. 6.8.1 La actualización de OpenSceneGraph 0.9 a 1.0 ......... ¡Error! Marcador no definido. 6.8.2 La clase RefParticle.................................................... ¡Error! Marcador no definido. 6.8.3 La función clone......................................................... ¡Error! Marcador no definido. 6.8.4 La función DoFrame()................................................ ¡Error! Marcador no definido. 6.8.5 Eliminar un nodo, deshacer y rehacer. ....................... ¡Error! Marcador no definido.

203

Page 205: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

204

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Page 206: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

6.1 Introducción Hasta ahora se han definido los requisitos que deben cumplir cada uno de los subsistemas de los cuales está compuesta la aplicación. Conociendo estos requisitos que marcan lo que se debe hacer, se realizó un análisis para alcanzar una primera aproximación lógica de cada sistema. Posteriormente se realizo la fase de diseño en la que se establece una primera solución, la cuál se describe solo de forma global. Por tanto en este momento se conoce todo lo que debe hacerse, y los esquemas generales para hacerlo, con lo cual solo queda implementar la solución siguiendo la estructura creada en los apartados anteriores. La implementación es la parte de más bajo nivel del yecto, donde se crean soluciones a problemas concretos planteados en el diseño. Esta parte la dividiremos en 6 apartados, explicando las partes relevantes de la implementación de cada uno:

• Parametri ación de datos. Aquí se presentarán todas las estructuras de datos relacionadas con los grupos de parámetros y los descriptores de parámetros, los TabOutput, ObjectType, NodeType y AttributeType y sus respectivos Gestores, el gestor de parámetros y las funciones más importantes de cada uno.

• Implementación del árbol del grafo de escena. Aquí se explicará el árbol y sus funciones, así como el método a seguir en su duplicado y la gestión de eventos de teclado.

• Interacción con el visor 3D. Veremos las acciones a llevar a cabo sobre la selección de objetos , como se gestionan, y como está estructurada la clase del eje manipulador.

• Sistema deshacer / rehacer. Veremos como funciona el sistema de deshacer / rehacer y como se implementan nuevas acciones en el sistema.

• Sistema gestor de plugins. En este apartado explicaremos el código del sistema gestor de plugins, asi como el código necesario para generar un plugin.

• Manejador de Vista Activa y clases MFC. En este apartado se explicará todo la parte de implementacion del ActiveViewHandler y el código referente a las clases MFC’s.

Y por último añadiremos un apartado extra, que llamaremos Problemas de implementación , donde explicaremos algunos de los problemas encontrados durante la implementación, y las soluciones adoptadas. Toda la implementación se realizará utilizando el lenguaje de programación C++, ya que es el lenguaje utilizado por la librería OpenSceneGraph. El entorno de desarrollo de las aplicaciones es el Visual C++ de Microsoft. Se ha elegido este sistema porque las aplicaciones de prueba se van a realizar haciendo uso de las Microsoft Foundation Classes. Nota: Algunos de los listados de código fuente mostrados a continuación han sido truncados, mostrando solo la información considerada como relevante para la explicación.

pro

z

205

Page 207: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

6.2 Parametrización de datos

6.2.1 El descriptor de parámetros (OSGParamGroupDesc). Como ya hemos visto, el descriptor de parámetros sirve para describir nombres y tipos de datos que mas tarde serán representados como controles de un diálogo. La estructura de la clase es la siguiente: class OSGParamGroupDesc { public: OSGParamGroupDesc(void); ~OSGParamGroupDesc(void); OSGParamGroupDesc(int _index,ParamType type, std::string name, int id); OSGParamGroupDesc(int _index,ParamType type,std::vector<std::string> names, int*); void Set(int _index, ParamType _type, std::string _name, int _flags=DESC_EDITABLE); void Add(std::string _name, int _value=-1) void AddCtrlID(int ctrl, int link_ctrl=-1); CTRLID_INF GetCtrlID(int _index=0); CTRLID_INF GetCtrlIDFromValue(int _value=0); int GetValueFromControl(int _ctrlid) int GetIndexFromValue(int _value) std::string* GetName(int _index=0) int GetValue(int _index=0) void SetEditable(bool Editable); bool IsEditable(); void AddFlag(int _flag); void RemoveFlag(int _flag); int GetNumNames() int GetNumControls() void SetGroup(OSGParamGroup *_gr) OSGParamGroup *GetGroup() int param_id; // index/orden q ocupa dentro del PARAMGROUP ParamType type; protected: std::vector<CTRLID_INF> ctrl_ids; int flags; // el primer elemento define el nombre del parametro // los demas se utilizan basicamente para los controles // tipo radio, cada name siguiente define una opcion del radio. // del mismo modo seria aplicable al combo box. // por tanto para saber el numero de elementos de un parametro // tipo radio, seria (names.size()-1) std::vector<DESC_INF> names; OSGParamGroup *gr;

206

Page 208: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

CRect rect; };

Como podemos ver, la clase proporciona mecanismos para obtener los datos del control que representa. Nos permite modificar su valor, así como modificar si se trata de un control editable o no. #define DESC_EDITABLE 0 #define DESC_READONLY 1

El parámetro type define el tipo de parámetro que estamos definiendo, y puede tomar cualquier de los siguientes valores: typedef enum { TYPE_BUTTON=1, TYPE_SPINNER, TYPE_RADIO, TYPE_CHECKBOX, TYPE_CHECKBUTTON, TYPE_STATIC, TYPE_MULTICHECKBOX, TYPE_COLORSWATCH, TYPE_LISTBOX, TYPE_COMBOBOX, TYPE_TEXTBOX, TYPE_GRIDCTRL, TYPE_STRING, TYPE_INT, TYPE_FLOAT, TYPE_VEC3_FLOAT, TYPE_VEC4_FLOAT, TYPE_RANGE_INT, TYPE_RANGE_FLOAT } ParamType;

Cada uno de ellos se corresponderá con uno o un conjunto de controles de la API de Win32.

6.2.2 Los grupos de pará Los grupos de parámetros, como su nombre indican tan solo agrupan parámetros y se identifican por un nombre. Representan un grupo en la barra deslizable del la barra de pestañas (Tabs) del editor, se asignaran a un Tab concreto de la barra de Tabs que no es más que un diálogo, que puede agrupar varios parámetros distintos de una misma categoría referentes a un mismo objeto. Contendrá opcionalmente un botón que permitirá plegar y desplegar el contenido de los controles que pertenecen a ese grupo de parámetros (rollable).

metros (OSGParamGroup)

class OSGPara mGroupDesc*> mGroup : public std::vector<OSGPara{ public: OSGParamGroup(std::string name, bool _rollable); OSGParamGroup(void); void push_back(OSGParamGroupDesc *desc); inline void SetTabIndex(int idx){tab_index=idx;} inline int GetTabIndex(){return tab_index;}

207

Page 209: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

inline bool IsRollable(){return rollable;} inline void SetExpanded(bool bexp){expanded=bexp;} inline bool IsExpanded(){ return expanded;} inline void SetGroupPage(RC_PAGEINFO *pg){page=pg;} inline RC_PAGEINFO * GetGroupPage(){return page;} inline CDynDialogEx *GetDialog(){return dialog;} inline void SetDialog(CDynDialogEx *dlg){dialog=dlg;} ~OSGParamGroup(void); int tab_index; RC_PAGEINFO *page; std::string group_name; bool rollable; bool expanded; CDynDialogEx *dialog; };

6.2.3 El gestor de parámetros (OSGParamManager) Esta clase proporciona mecanismos para crear todos y cada uno de los controles asociados a cada tipos de descriptor de parámetro de forma dinámica, y en tiempo de ejecución. También se encarga de registrar los controles internamente manteniendo unas tablas hash para identificar los descriptores de parámetros con su grupo de parámetros asi como con el OSGTabOutput del que proviene. class OSGParamManager { public: OSGParamManager(void); ~OSGParamManager(void); void RegisterCtrlID( OSGTabOutput *nt, OSGParamGroupDesc *desc, int id, int link_id=-1); void CreateDialogs(OSGTabOutput *nt); void RecursiveCreateDialogs(OSGObjectType *nt); CDialog* CreateDialogFromGroup(OSGTabOutput *nt, OSGParamGroup *gr, CWnd *parent_wnd, CWnd *notify_wnd); void CreateButton(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateStatic(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateTextbox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateEditbox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateSpinner(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateRadio(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateRange(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateVector3(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateVector4(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateListbox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateColorSwatch(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateCombobox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateGridCtrl(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateCheckbox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); void CreateCheckButton(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc);void AdjustControls(OSGParamGroup *gr); void NotifyObjectType(WPARAM wParam, LPARAM lParam, int notify_type=0); protected: int last_id; std::map<int, OSGTabOutput*> hash_idoutput; std::map<int, OSGParamGroupDesc*> hash_idparamgroupdesc;

208

Page 210: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

CRect curr_rect; };

La función NotifyObjectType se invoca por el sistema cuando el un parámetro se ha modificado, y el gestor de parám se encarga de notificar al OSGTabOutput que lo contiene del evento.

etros

void OSGParamManager::NotifyObjectType(WPARAM wParam, LPARAM lParam, int notify_type) { bool send_notify = false; WORD wControlID = LOWORD(wParam); WORD wMessageID = HIWORD(wParam); OSGTabOutput *nt = hash_idoutput[wControlID]; OSGParamGroupDesc *desc = hash_idparamgroupdesc[wControlID]; if(!desc || !nt) return; OSGParamGroup *gr = desc->GetGroup(); if(!nt->IsDataShown()) return; if(notify_type==0) // FROM WM_COMMAND { switch(desc->type) { case TYPE_TEXTBOX: case EDITTYPE_STRING: case TYPE_SPINNER: case EDITTYPE_INT: case EDITTYPE_FLOAT: case EDITTYPE_VEC3_FLOAT: case EDITTYPE_VEC4_FLOAT: case EDITTYPE_RANGE_FLOAT: case EDITTYPE_RANGE_INT: if(wMessageID == EN_KILLFOCUS) send_notify = true; break; case TYPE_RADIO: case TYPE_BUTTON: case TYPE_CHECKBOX: case TYPE_CHECKBUTTON: send_notify = true; break; case TYPE_COLORSWATCH: // cuando llega un evento de colorwatch es porque // hemos pulsado OK sobre el dialogo send_notify = true; break; case TYPE_LISTBOX: if(wMessageID == LBN_SELCHANGE) send_notify = true; break; case TYPE_COMBOBOX: if(wMessageID == CBN_SELCHANGE) send_notify = true; break; } } else // FROM WM_NOTIFY (Solo SpinCtrl) { // informacion de la pulsacion LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam; switch(desc->type) { case TYPE_SPINNER: case EDITTYPE_FLOAT:

209

Page 211: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

case EDITTYPE_INT: case EDITTYPE_VEC3_FLOAT: case EDITTYPE_VEC4_FLOAT: case EDITTYPE_RANGE_FLOAT: case EDITTYPE_RANGE_INT: if(lpnmud->hdr.code == UDN_DELTAPOS) { int val; float fval; send_notify = true; // control editable asociado que está en desc // actualizamos su valor // Si en un descriptor con varios controles // tenemos q averiguar cual de ellos tenemos // que actualizar. CTRLID_INF ctrlinf; for(int i=0;i<desc->GetNumControls();i++) { ctrlinf = desc->GetCtrlID(i); if(ctrlinf.link_id != -1) { if(ctrlinf.link_id == wControlID) break; } else break; } if(desc->type==EDITTYPE_FLOAT || desc->type==EDITTYPE_VEC3_FLOAT || desc->type==EDITTYPE_VEC4_FLOAT || desc->type== EDITTYPE_RANGE_FLOAT) { CString sval; char aux[64]; gr->GetDialog()->GetDlgItemText( ctrlinf.id, sval); strcpy(aux, sval.GetBuffer()); fval = atof(aux); fval -= lpnmud->iDelta / 10.0; sprintf(aux, "%.6f", fval); gr->GetDialog()->SetDlgItemText( ctrlinf.id, aux); } else{ // en ctrlinf.id tenemos el id del control val = gr->GetDialog()->GetDlgItemInt( ctrlinf.id); val -= lpnmud->iDelta; gr->GetDialog()->SetDlgItemInt( ctrlinf.id, val); } } break; case TYPE_GRIDCTRL: if(wMessageID == (WORD)GVN_ENDLABELEDIT){ GV_DISPINFO *pgvDispInfo = (GV_DISPINFO *)lParam; GV_ITEM *pgvItem = &pgvDispInfo->item; send_notify = true; } break; } } if(send_notify){ if(nt->OutputType() != OUTPUT_TYPE_DEFAULT){ OSGObjectType *obj = dynamic_cast<OSGObjectType*> (nt); if(obj) { if(nt->OutputType() == OUTPUT_TYPE_NODE) obj->SetSelectedObj( OSGAVH->m_wndSceneTree.GetSelected()->node.get()); nt->ParamModified(obj->GetSelectedObj().get(),

210

Page 212: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

desc->param_id); OSGObjectType *attacher = obj->GetCurrentAttacher(); if(attacher) attacher->AttachParamModified( obj->GetCurrentAttacherIndex(), desc->param_id); } } else // Tipo Output nt->ParamModified(NULL, desc->param_id); } }

6.2.4 El control ColorSwatch Cualquier tipo de dato (parámetro) lo hemos podido representar en un diálogo utilizando los controles comunes que proporciona la API de Win32. No obstante, para representar un color hemos querido hacer una excepción; un color no es más que un vector de 4 elementos (Red, Gree, Blue y Alpha), lo cual se podria representar con 4 spinners con valores de 0 a 255. Esto puede ser poco intuitivo, ya que el usuario suele saber concretamente describir numéricamente el color exacto que está buscando, y del mismo modo, tampoco le resulta sencillo reconocer un color viendo sus valores RGB. Lo que se suele hacer es representar visualmente el color en pantalla. Por ello creamos la clase ColorSwatch, que será un pequeño rectángulo que deriva de CStatic, representando el valor del color, incluido el valor alpha. class CColorSwatch : public CStatic { public: CColorSwatch(CWnd* pNotify=NULL); virtual ~CColorSwatch(); void SetValues(BYTE bRed, BYTE bGreen, BYTE bBlue, BYTE bAlpha); void NotifyParent(); BYTE GetRed(); BYTE GetGreen(); BYTE GetBlue(); BYTE GetAlpha(); protected: BYTE m_bRed; BYTE m_bGreen; BYTE m_bBlue; BYTE m_bAlpha; CWnd *pNotifyWnd; public: afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); };

Este control mostrará un diálogo de selección de color al pulsar sobre él, que nos permitirá seleccionar el color que deseemos. void CColorSwatch::OnLButtonDown(UINT nFlags, CPoint point) { CSelColorDlg *dlg = new CSelColorDlg(m_bRed, m_bGreen, m_bBlue, m_bAlpha, this); dlg->Create(CSelColorDlg::IDD); dlg->ShowWindow(SW_SHOW); dlg->SetFocus(); CStatic::OnLButtonDown(nFlags, point); }

211

Page 213: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

6.2.5 Las clases OSGTabOutput y OSGTabOutputManager

Aunque la clase OSGTabOutput derivará en otras tres más, mantendremos una variable para saber de antemano que tipo de OSGTabOutput estamos usando:

#define OUTPUT_TYPE_DEFAULT 0 #define OUTPUT_TYPE_OBJECT 1 #define OUTPUT_TYPE_NODE 2 #define OUTPUT_TYPE_ATTRIBUTE 3

Esta clase proporciona los mecanismos necesarios para construir un objeto que se muestre en la barra de pestañas principal, más concretamente un diálogo, asi como para consultar y establecer los datos que queramos de los controles. class OSGTabOutput { public: OSGTabOutput(void); ~OSGTabOutput(void); void Init(); virtual void CreateIOControls()=0; virtual void ShowCustomData(osg::Object *obj) = 0; virtual void ParamModified(osg::Object *obj, int param_id)=0; void ShowData(osg::Object *obj); inline std::string GetName(); inline int OutputType(); bool HasIOGroups(); std::vector<OSGParamGroup*> * GetIOGroups(); void SetDialogsCreated(bool b); bool DialogsCreated; inline bool IsDataShown(); inline bool IsDialogShown(); inline void SetGroupName(int group_idx, std::string name); void GenerateRollupContent(); void ClearRollupContent(); CWnd* GetParamHandle(int param_id); void MapIOControls(); void GetParamValue(int param_id, std::string &value); void GetParamValue(int param_id, int &value); void GetParamValue(int param_id, osg::Vec3f &value); void GetParamValue(int param_id, osg::Vec4 &value); void GetParamValue(int param_id, float &value); void GetParamValue(int param_id, osg::Vec4d &value); void GetParamValue(int param_id, osg::Quat &value); void GetParamValue(int param_id, osg::Matrixd &value); void GetParamValue(int param_id, CPoint &value); void GetParamValue(int param_id, std::string &value, int row, int col); void GetParamValue(int param_id, float &min, float &max); void AddParamFlag(int param_id, int addflag); void RemoveParamFlag(int param_id, int addflag); bool IsParamEditable(int param_id); void SetParamValue(int param_id, std::string &value); void SetParamValue(int param_id, int &value); void SetParamValue(int param_id, float &value); void SetParamValue(int param_id, float &min, float &max); void SetParamValue(int param_id, osg::Vec3f &value); void SetParamValue(int param_id, osg::Vec4 &value); void SetParamValue(int param_id, osg::Vec4d &value); void SetParamValue(int param_id, osg::Quat &value); void SetParamValue(int param_id, osg::Matrixd &value); void SetParamValue(int param_id, std::vector<std::string> &values, bool sorted=true); void SetParamValue(int param_id, OSGW_PAIRLIST &values);

212

Page 214: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

protected: std::vector<OSGParamGroup*> iogroups; bool dialogs_created; bool dialog_shown; bool data_shown; int output_type; std::string name; std::map<int, OSGParamGroupDesc*> hash_pidgroupdesc; std::map<int, OSGTabOutput*> attach_list; // Objectos adjuntos };

Las funciones para obtener el valor de un parámetro y establecer este valor son GetParamValue y SetParamValue. Estas funciones estarán sobrecargadas para todos y cada uno de los tipos de datos que soporta el descriptor de parámetros. También podremos asignar flags a los parámetros. De momento solo están implementados dos flags: #define DESC_EDITABLE 0 #define DESC_READONLY 1

La función MapIOControls() la realiza el TabOutputMananger automáticamente, y esta a su vez realiza una llamada a CreateIOControls(), que es una funcion virtual pura que deberá estar implementada en cada tipo de TabOutput y lo que hace es rellenar la el vector iogroups de los grupos de parámetros que tendrá el TabOutput. Al mismo tiempo se actualiza la tabla hash que relaciona cada uno de los parámetros con su descriptor de parámetros correspondiente. void OSGTabOutput::MapIOControls() { CreateIOControls(); if(HasIOGroups()){ for(unsigned i=0;i<iogroups.size(); i++){ OSGParamGroup *gr = iogroups[i]; for(unsigned j=0;j<gr->size();j++){ OSGParamGroupDesc *desc = gr->at(j); hash_pidgroupdesc[desc->param_id] = desc; } } } }

El gestor de este tipo de objetos tiene la siguiente estructura: class OSGTabOutputManager { public: OSGTabOutputManager(void); ~OSGTabOutputManager(void); void RegisterTabOutput(OSGTabOutput *objt); bool UnregisterTabOutput(int index); bool UnregisterTabOutput(std::string name); OSGTabOutput * GetTabOutput(int index); OSGTabOutput * GetTabOutput(std::string name); inline int GetNumTabOutputs(){return outputs.size();}

213

Page 215: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

void GetTabOutputStrings(std::vector<std::string> &list); protected: std::map<std::string, OSGTabOutput*> outputs; std::vector<OSGTabOutput*> outputs_v; };

Este gestor simplemente mantiene una tabla hash que identifica cada TabOutput por su nombre, y permite obtener un puntero al mismo ya sea por nombre o por índice. La funcion RegisterTabOutput almacena el TabOutput a almacenar, e inicializa los datos de los parámetros con la funciona MapIOControls. void OSGTabOutputManager::RegisterTabOutput(OSGTabOutput *obj) { // El primer elemento insertado obtendra NULL como padre // ya que default_type vale null inicialmente outputs_v.push_back(obj); outputs[obj->GetName()] = obj; // Inicializamos los valores de los parametros // de que manejará este tipo de nodo obj->MapIOControls(); }

6.2.6 Un ejemplo de OSGTabOutput : la clase OutCreateNodes La primera pestaña del interfaz permite la creación de lase deriva de OSGTabOutput y se implementa como

nodos en el grafo. Esta c sigue:

#define NUM_PARAMS 4 enum{PARAM_NODELIST, PARAM_CREATEASCHILD, PARAM_CREATEASPARENT, PARAM_CREATEFROMFILE}; OutCreateNodes::OutCreateNodes(void) { name = "Creador de nodos"; } OutCreateNodes::~OutCreateNodes(void) { } void OutCreateNodes::ShowCustomData(osg::Object *obj) { std::vector<std::string> lista; OSGAVH->nodetypem.GetObjectTypeStrings(lista); SetParamValue(PARAM_NODELIST, lista); } void OutCreateNodes::CreateIOControls() { OSGParamGroupDesc *desc = new OSGParamGroupDesc[NUM_PARAMS]; desc[0].Set(PARAM_NODELIST, TYPE_LISTBOX, "Nodos"); desc[1].Set(PARAM_CREATEASCHILD, TYPE_BUTTON, "Crear como hijo"); desc[2].Set(PARAM_CREATEASPARENT, TYPE_BUTTON, "Crear como padre"); desc[3].Set(PARAM_CREATEFROMFILE, TYPE_BUTTON, "Crear desde archivo..."); OSGParamGroup *mygroup = new OSGParamGroup("Creacion de Nodos", true); for(int i=0;i<NUM_PARAMS;i++) mygroup->push_back(&desc[i]); iogroups.push_back(mygroup);

214

Page 216: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

} // Atencion, aqui obj siempre es null void OutCreateNodes::ParamModified(osg::Object *obj, int param_id) { std::string nom; switch(param_id) { case PARAM_CREATEASCHILD: GetParamValue(PARAM_NODELIST, nom); if(!nom.empty()) { HTREEITEM item = OSGAVH->GetTreeCtrl()->GetSelectedItem(); if(item) { if(!OSGAVH->AddNodeWithHistory(nom, item)) AfxMessageBox("Nodo no instanciable"); } } break; case PARAM_CREATEASPARENT: GetParamValue(PARAM_NODELIST, nom); if(!nom.empty()) OSGAVH->AddParentNode(nom); break; case PARAM_CREATEFROMFILE: { if(OSGAVH->GetSelectedTni()) { COSGTreeCtrl *tree = OSGAVH->GetTreeCtrl(); osg::ref_ptr<osg::Group> group = OSGAVH->GetSelectedTni()->node.get()->asGroup(); if(group.valid()) { AbrirFichero(); tree->Expand(tree->GetSelectedItem(), TVE_EXPAND); tree->Redraw(); } } } } }

6.2.7 Las clases OSGObjectType y OSGObjectTypeManager La clase OSGObjectType deriva de OSGTabOutput y tiene ciertas particularidades, como son:

• Adjuntar otros ObjectTypes (función Attach y Detach) • La notificación de fin de selección (RecursiveOnEndSelection) • Notificación de que se ha modificado algun parámetro de un objeto adjunto

(AttachParamModified). • Obtener una nueva instancia de este tipo de clase (NewInstance). • Obtener una nueva instancia de este tipo de clase a partir de otro objeto existente.

class OSGObjectType : public OSGTabOutput { public: OSGObjectType(void); ~OSGObjectType(void); void Init();

215

Page 217: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

virtual void AttachParamModified(int attach_id, int param_id)=0; virtual osg::ref_ptr<osg::Object> NewInstance()=0; virtual osg::ref_ptr<osg::Object> NewInstance(osg::Object *_obj)=0; virtual void OnEndSelection(osg::Object *obj)=0; inline OSGObjectType* GetParentType(); inline std::string GetParentName(); void SetParentType(OSGObjectType *nodet); void SetSelectedObj(osg::Object *obj); inline osg::ref_ptr<osg::Object> GetSelectedObj(); void ShowRecursiveData(osg::Object *obj = NULL); void RecursiveOnEndSelection(osg::Object *obj = NULL); void RecursiveClearRollupContent(); void RecursiveGenerateRollupContent(); void Detach(int key); void Attach(int key, OSGObjectType *obj); bool Attach(int key, std::string name); void EndAttachSelection(int key, osg::Object *obj); void ShowAttachData(int key, osg::Object *obj); void ShowAttach(int key); void HideAttach(int key); int NumAttachs(); OSGObjectType *GetAttach(int key); inline OSGObjectType * GetCurrentAttacher(); inline int GetCurrentAttacherIndex(); protected: void SetCurrentAttacher(OSGObjectType *obj, int att_index); OSGObjectType *parent_type; std::string parent_type_name; osg::ref_ptr<osg::Object> selected_obj; std::map<int, OSGObjectType*> attach_list; // Objectos adjuntos OSGObjectType *current_attacher; // Quien esta actualmente adjuntado este objeto int current_attacher_index; // Indice del Attach al que apunta el Attacher };

Esta clase mantiene una tabla punteros a los ObjectType adjuntos (attach_list), y también un puntero al ObjectType que está actualmente enlazando a este ObjectType, y el objeto OpenSceneGraph que está actualmente representando. También mantiene un puntero a su ObjectType padre, lo cual que permite realizar una llamada recursiva al mostrar sus datos (ShowRecursiveData). El gestor de este tipo de objetos es como sigue: class OSGObjectTypeManager { public: OSGObjectTypeManager(void); ~OSGObjectTypeManager(void); void RegisterType(OSGObjectType *objt); bool UnregisterType(std::string name); OSGObjectType * GetObjectType(std::string name); void SetDefaultType(OSGObjectType *objt); osg::ref_ptr<osg::Object> NewCopyInstance(osg::Object *obj); osg::ref_ptr<osg::Object> NewInstance(std::string &name); void GetObjectTypeStrings(std::vector<std::string> &list); void GetAttributeTypeStrings(std::vector<std::string> &list); protected: std::map<std::string, OSGObjectType*> objtypes; std::vector<std::string> attributetypes; OSGObjectType *default_type; };

216

Page 218: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

La funcionalidad de este gestor es similar a la del gestor de TabOutputs con la particularidad de establecer un ObjectType por defecto (SetDefaultType, para cuando una clase no se reconozca en el grafo de escena) , poder obtener un No describiremos la estructura de AttributeType ni de NodeType , ni sus respectivos gestores puesto que siguen estructuras prácticamente idénticas.

6.2.8 Un ejemplo de OSGObjectType: TypeDrawable. #define NUM_PARAMS 9 #define ATT_STATESET 0 enum {PARAM_SUPPORTSDISPLAYLIST,PARAM_USEDISPLAYLIST,PARAM_USEVERTEXTBUFFER, PARAM_REQUIRESUPDATETRAVERSAL, PARAM_REQUIRESEVENTTRAVERSAL,PARAM_BOUNDINGBOX, PARAM_BBMIN,PARAM_BBMAX, PARAM_SHOWSHAPE, PARAM_SHOWSTATESET}; ObjTypeDrawable::ObjTypeDrawable(void) { name = "Drawable"; Attach(ATT_STATESET, "DrwStateSet"); } void ObjTypeDrawable::CreateIOControls() { OSGParamGroupDesc *desc = new OSGParamGroupDesc[NUM_PARAMS]; desc[0].Set(0, TYPE_CHECKBOX, "Soporta DisplayList"); desc[1].Set(1, TYPE_CHECKBOX, "Usa DisplayList"); desc[2].Set(2, TYPE_CHECKBOX, "Usa Objetos Vertex Buffer"); desc[3].Set(3, TYPE_CHECKBOX, "Requiere update traversal", DESC_READONLY); desc[4].Set(4, TYPE_CHECKBOX, "Requiere event traversal", DESC_READONLY); desc[5].Set(5, TYPE_STATIC, "Bound inicial"); desc[6].Set(6, EDITTYPE_VEC3_FLOAT, "BBMin"); desc[7].Set(7, EDITTYPE_VEC3_FLOAT, "BBMax"); desc[8].Set(8, TYPE_CHECKBUTTON, "Mostrar Shape"); desc[8].Set(9, TYPE_CHECKBUTTON, "Mostrar StateSet"); OSGParamGroup *mygroup = new OSGParamGroup("Drawable", true); for(int i=0;i<NUM_PARAMS;i++) mygroup->push_back(&desc[i]); mygroup->SetTabIndex(1); iogroups.push_back(mygroup); } void ObjTypeDrawable::OnEndSelection(osg::Object *obj) { HideAttach(ATT_STATESET); } void ObjTypeDrawable::ParamModified(osg::Object *obj, int param_id) { osg::ref_ptr<osg::Drawable> node = (osg::Drawable*) (obj); if(!node.valid()) return; int ival; switch(param_id) { case PARAM_BBMIN: case PARAM_BBMAX: { osg::Vec3 vv[2]; osg::BoundingBox bb; GetParamValue(PARAM_BBMIN, vv[0]); GetParamValue(PARAM_BBMAX, vv[1]); bb.set(vv[0], vv[1]); OSGAVH->Exec(new ActDrwSetInitialBound(node.get(), node->getInitialBound(), bb));

217

Page 219: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

} break; case PARAM_SUPPORTSDISPLAYLIST: GetParamValue(param_id, ival); OSGAVH->Exec(new ActDrwSetSupportsDisplayList(node.get(), node->getSupportsDisplayList(), ival)); break; case PARAM_USEDISPLAYLIST: GetParamValue(param_id, ival); OSGAVH->Exec(new ActDrwSetUseDisplayList(node.get(), node->getUseDisplayList(), ival)); break; case PARAM_USEVERTEXTBUFFER: GetParamValue(param_id, ival); OSGAVH->Exec(new ActDrwSetUseVertexBufferObjects(node.get(), node->getUseVertexBufferObjects(), ival)); break; } } // Mostrar la informacion de este tipo de dato // La salida puede ser la que el usuario elija void ObjTypeDrawable::ShowCustomData(osg::Object *obj) { osg::ref_ptr<osg::Drawable> node = (osg::Drawable*) (obj); if(!node.valid()) return; int ival; osg::Vec3f vec3; ival = node->getSupportsDisplayList(); SetParamValue(PARAM_SUPPORTSDISPLAYLIST, ival); ival = node->getUseDisplayList(); SetParamValue(PARAM_USEDISPLAYLIST, ival); ival = node->getUseVertexBufferObjects(); SetParamValue(PARAM_USEVERTEXTBUFFER, ival); ival = node->requiresUpdateTraversal(); SetParamValue(PARAM_REQUIRESUPDATETRAVERSAL, ival); ival = node->requiresEventTraversal(); SetParamValue(PARAM_REQUIRESEVENTTRAVERSAL, ival); osg::BoundingBox bb = node->getInitialBound(); vec3.set(bb.xMin(), bb.yMin(), bb.zMin()); SetParamValue(PARAM_BBMIN, vec3); vec3.set(bb.xMax(), bb.yMax(), bb.zMax()); SetParamValue(PARAM_BBMAX, vec3); ShowAttachData(ATT_STATESET, node->getStateSet()); } void ObjTypeDrawable::AttachParamModified(int attach_id, int param_id) { osg::ref_ptr<osg::Drawable> node = dynamic_cast<osg::Drawable*> (GetSelectedObj().get()); if(!node.valid()) return; ObjTypeDrwStateSet *kkk = dynamic_cast<ObjTypeDrwStateSet *> (GetAttach(ATT_STATESET)); if(attach_id == ATT_STATESET) { if(node->getStateSet() == NULL) { if(AfxMessageBox("No existe ningun StateSet\n¿Crearlo?", MB_YESNO|MB_ICONQUESTION) == IDYES) { osg::StateSet *sts = new osg::StateSet(); node->setStateSet(sts); ShowAttachData(ATT_STATESET, sts);

218

Page 220: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

} } } } // Clase no instanciable osg::ref_ptr<osg::Object> ObjTypeDrawable::NewInstance() { osg::ref_ptr<osg::Object> ref = NULL; return ref; } // Clase no instanciable osg::ref_ptr<osg::Object> ObjTypeDrawable::NewInstance(osg::Object *_obj) { osg::ref_ptr<osg::Object> ref = NULL; return ref; }

6.3 Implementación del árbol del grafo de escena.

6.3.1 La clase TreeNodeInfo Como ya sabemos, nuestro editor mantendrá de manera duplicada, pero usando nuestra propia estructura de datos, el grafo de escena de OpenSceneGraph. Esta estrcutra de datos a utilizar es la clase TreeNodeInfo: class TreeNodeInfo { public: typedef std::vector<TreeNodeInfo*> List; typedef std::vector<HTREEITEM> HTIList; TreeNodeInfo(DataType dtype=TYPE_NODE); ~TreeNodeInfo(void); static TreeNodeInfo * FindNode(std::vector<TreeNodeInfo*> vector, osg::Node *thenode); osg::ref_ptr<osg::Node> node; // El elemento puede tener MULTIPLES INSTANCIAS // y a su vez puede tener varios "mirrors" std::vector<HTIList> treeitems; OSGObjectType *nodetype; void AddParent(TreeNodeInfo *newtni, bool node_too=true); void RemoveParent(TreeNodeInfo *tni, bool node_too=true); void RemoveChild(TreeNodeInfo *child, bool node_too=true); void SetChild(int i, TreeNodeInfo *newtni, bool node_too=true); void ReplaceChild(TreeNodeInfo *oldtni, TreeNodeInfo *newtni, bool node_too=true); bool AddChild( TreeNodeInfo *child, bool node_too=true); bool InsertChild( unsigned int index, TreeNodeInfo *child, bool node_too=true); void AddMirror(); void RemoveMirror(int index); inline int GetNumMirrors(); void RemoveTreeItem(HTREEITEM hItem, int mirror_index=0); void AddTreeItem(HTREEITEM hItem, int mirror_index, int pos=-1); inline int GetNumInstances(){ return treeitems[0].size();} inline int GetNumInstances(int mirror_index); int GetInstanceIndex(HTREEITEM hitem, int mirror_index); int GetInstanceIndex(HTREEITEM hitem); inline , int mirror_index=0); HTREEITEM GetTreeItem(int index

219

Page 221: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

int FindTNI(std::vector<TreeNodeInfo*> vector, TreeNodeInfo *tni); void SetNode(osg::Node * _node); inline const List& GetParents() const; inline List GetParents(); inline int GetNumParents(); inline const List& GetChildren() const; inline List GetChildren(); inline int GetNumChildren(); List children; List parents; };

Para construir un grafo a partir de esta estructura, tan solo necesitamos la lista de hijos de de padres y las funciones que nos permitan añadir padres o hijos, asi como desvincularlos. Además, cada uno de estos “Nodos” contiene un puntero al nodo de OpenSceneGraph equivalente, y un vector de vectores de enlaces a HTREEITEMs, puesto que un mismo Nodo puede estar múltiplement do en una escena, pero ademas necesitamos identificar ese mismo item en todos los árboles de todas las TreeBar que hayamos duplicado.

6.3.2 La clase CEditTreeCtrl Para describir el árbol que identificará el grafo OSG tenemos una clase base que iremos extendiendo:

e instancia

class CEditTreeCtrl : public CTreeCtrlEx { public: // Correspondencia entre el HTREEITEM y el // nodo TreeNodeInfo que le corresponde std::map<HTREEITEM, TreeNodeInfo*> hash_iteminfo; // Correspondencia entre el osg::Node y el // nodo TreeNodeInfo que le corresponde std::map<osg::ref_ptr<osg::Node>, TreeNodeInfo*> hash_nodeinfo; TreeNodeInfo * selected_tni; std::list<HTREEITEM> copyItems; void SelectAllInstances(TreeNodeInfo *tni, bool selec); void SelectAllMirrors(HTREEITEM hItem, bool selec); void OnSelectedItemChanged(); void ExpandSubtree(HTREEITEM hItem, bool expand=true); void ShadowSubtree(HTREEITEM hItem, bool shadow=true); HTREEITEM GetMirrorInTree(HTREEITEM hItem, CEditTreeCtrl *tree); TreeNodeInfo * GetTNI(HTREEITEM hItem); TreeNodeInfo * GetTNI(osg::Node * node); int GetSubtreeCount(HTREEITEM hRoot); virtual HTREEITEM DragMoveItem(HTREEITEM hDrag, HTREEITEM hDrop, EDropHint hint, int copyOp, bool autosel=true); protected: virtual bool HandleKeyDown(WPARAM wParam, LPARAM lParam); virtual bool NewItem(TVINSERTSTRUCT & ins); virtual void OnNewItem(HTREEITEM hItem); virtual void CreateCursorMap(); virtual void SortCurrentLevel(HTREEITEM hItem = 0); virtual void SortCurrentLevelAndBelow(HTREEITEM hItem = 0); virtual void DisplayContextMenu(CPoint & point); virtual void ExtendContextMenu(CMenu & menu); protected: virtual void DragStart(); virtual void DragMove(); virtual void DragEnd(); virtual void DragStop(); virtual void SetDragCursor(HTREEITEM hDropTarget, EDropHint hint);

220

Page 222: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

virtual CDragData * CreateDragData(HTREEITEM hDragItem, bool bRightDrag); virtual bool DoEditLabel(HTREEITEM); virtual bool DoInsertSibling(HTREEITEM); virtual bool DoInsertChild(HTREEITEM); virtual bool DoInsertRoot(HTREEITEM); virtual bool DoSortCurrentLevel(HTREEITEM); virtual bool DoSortCurrentLevelAndBelow(HTREEITEM); virtual bool DoSelectFromScene(HTREEITEM hItem); virtual bool DoAddSelectFromScene(HTREEITEM hItem); public: virtual bool DoCopyClipboard(int copyOp); virtual bool DoPasteClipboard(); virtual bool DoDeleteItem(HTREEITEM); bool IsAncestor(HTREEITEM hItem, HTREEITEM hCheck) const; protected: EDropHint GetDropHint(UINT flags); HTREEITEM GetDropTarget(EDropHint & hint); HTREEITEM CopyItem(HTREEITEM hOrig, HTREEITEM hParent, HTREEITEM hInsertAfter, int mirror_index, bool tni_too=true, bool duplicate=false, TreeNodeInfo *tni_dup=NULL ); };

La estructura EDropHint sirve para indicar de que manera se va a copiar un elemento respecto al elemento destino: enum EDropHint { DROP_BELOW, DROP_ABOVE, DROP_CHILD, DROP_NODROP };

Esta clase derivada de CTreeCtrl es la que contiene la correspondencia de los items del árbol con su nodo del grafo. Esta se representa mediante dos tablas hash, una para identificar el puntero al nodo de nuestro grafo duplicado a partir del HRTREEITEM del árbol, y otra para identificar el nodo de OpenSceneGraph a partir del HTREEITEM del árbol también. También proporciona funciones para Seleccionar todas las instancias de un mismo nodo, o modificar el color de un subárbol (para cuando cortamos un nodo), y mover nodos entre distintos elementos. Esta clase es la que procesa los eventos de teclas pulsadas, y el arrastre de elementos con el ratón. También permite ordenar un nivel y sus descendientes. Esta clase también tendrá la funcionalidad de añadir un menú contextual (para cuando se pulse el botón derecho del ratón), que permite distintas opciones sobre el elemento seleccionado. Los eventos de copiar y pegar nodos usando el teclado (Copiar y Pegar) están incluidos en la siguiente función para procesar los distintos eventos de teclado: bool CEditTreeCtrl::HandleKeyDown(WPARAM wParam, LPARAM lParam) { bool bCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; bool bShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; HTREEITEM hCur = GetSelectedItem(); switch(int(wParam)) { // CTRL+C COPIAR (INSTANCIAR) case 'C':

221

Page 223: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

222

if (GetKeyState(VK_CONTROL) & 0x80000000) { if(!m_pDragData) { DoCopyClipboard(COPYOP_COPY); } } break; // CTRL+D COPIAR (DUPLICADO) case 'D': if (GetKeyState(VK_CONTROL) & 0x80000000) { if(!m_pDragData) { DoCopyClipboard(COPYOP_DUPLICATE); } } break; // CTRL+X CORTAR case 'X': if (GetKeyState(VK_CONTROL) & 0x80000000) { if(!m_pDragData) { DoCopyClipboard(COPYOP_MOVE); } } break; // CTRL+V PEGAR case 'V': if (GetKeyState(VK_CONTROL) & 0x80000000) { if(!m_pDragData) { DoPasteClipboard(); } } break; } return false; }

6.3.3 La clase CEditTreeCtrlEx De la clase EditTreeCtrl deriva EditTreeCtrlEx que es una extensión de la anterior y permite múltiple selección de objetos. Esta clase tan solo tiene que sobrecargar las funciones virtuales que necesite modificar para adaptar su comportamiento para la selección múltiple. La principal diferencia de la clase anterior es su función GetSelectedItemsWithoutDescendents(…) que devuelve una lista de items seleccionados en el árbol. class CEditTreeCtrlEx : public CEditTreeCtrl { […] };

void CEditTreeCtrlEx::GetSelectedItemsWithoutDescendents

(std::vector<HTREEITEM> & listSel) { listSel.clear(); for(HTREEITEM hItem = GetFirstSelectedItem(); hItem != 0; hItem = GetNextSelectedItem(hItem)) {

Page 224: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

bool bChild = false; for(std::vector<HTREEITEM>::iterator it = listSel.begin(); it != listSel.end(); ++it) if(IsAncestor(*it, hItem)) { bChild = true; break; } if(!bChild) listSel.push_back(hItem); } }

6.3.4 La clase COSGTreeCtrl Seguimos derivando el árbol. Esta extensión del árbol añade funcionalidades más relacionadas con el grafo en sí. class COSGTreeCtrl : public CEditTreeCtrlEx { DECLARE_DYNAMIC(COSGTreeCtrl) public: COSGTreeCtrl(); virtual ~COSGTreeCtrl(); HTREEITEM SetRootNode(osg::Node *node, HTREEITEM hRoot=NULL); HTREEITEM AddNodeToTree( LPSTR lpszItem, osg::Node* node, HTREEITEM parent); HTREEITEM GetItemFromNodePath(osg::NodePath &np); void SetItemImageByType(HTREEITEM hItem, std::string classname); void GetNodePathFromItem(HTREEITEM item, osg::NodePath & res); void Redraw(); inline TreeNodeInfo * GetSelected(){ return selected_tni; } void CloneFrom(COSGTreeCtrl *clone, HTREEITEM hFirst); public: afx_msg void OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); };

La funcion de inicialización establece los iconos de los nodos : int COSGTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CEditTreeCtrlEx::OnCreate(lpCreateStruct) == -1) return -1; SetImageList (&OSGAVH->mainfr->m_imageList, TVSIL_NORMAL); return 0; }

Vamos a mostrar una función muy importante, SetRootNode(…), que permite establecer como nodo raíz (o como una rama) un grafo a partir de un Nodo de OpenSceneGraph: // Cuelga del grafo del editor, así como del TreeCtrl // El grafo de escena que se le pasa // Pudiendo ser el destino de este un nodo del arbol // del editor, en este caso del TreeCtrl (hRoot). // DEVUELVE EL PRIMER ELEMENTO CREADO HTREEITEM COSGTreeCtrl::SetRootNode(osg::Node * node, HTREEITEM hRoot) { readNodeVisitor mireader(hRoot); mireader.CompleteApply(*node, this);

223

Page 225: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

return mireader.GetRootItem(); }

La clase readNodeVisitor utilizada dentro de la función SetRootNode(…) se encarga de recorrer el grafo, construyendo el árbol imagen del grafo. class readNodeVisitor : public osg::NodeVisitor { public: readNodeVisitor(HTREEITEM _root=TVI_ROOT); OSGObjectType * GetTypeFromName(std::string name); TreeNodeInfo* getFirst(); void CompleteApply(osg::Group &sN, COSGTreeCtrl *_tree); void CompleteApply(osg::Node &sN, COSGTreeCtrl *_tree); std::vector<TreeNodeInfo*> & getNodeList(); TreeNodeInfo* Contains(osg::Node *node); std::string GetNodeName(osg::Node &sN); HTREEITEM GetRootItem(); protected: virtual void apply(osg::Node &searchNode); virtual void apply(osg::Group &searchNode); void getNodeInfo(osg::Node &sN, TreeNodeInfo *ni); void getGroupInfo(osg::Group &sN, TreeNodeInfo *ni); void SecondPass(); private: std::vector<TreeNodeInfo*> foundNodeList; std::stack<HTREEITEM> m_vec; HTREEITEM root; bool firstTime; COSGTreeCtrl *tree; };

La funcion CompleteApply(…) que es la que invoca SetRootNode(…) es como sigue: void readNodeVisitor::CompleteApply(osg::Group &sN, COSGTreeCtrl *_tree) { firstTime = false; tree = _tree; apply(sN); SecondPass(); }

la funcion apply() se llama por primera vez dentro de esta función, pero OpenSceneGraph seguirá invocándola para todos y cada uno de los nodos del grafo. Dentro de esta función es donde se va construyendo el árbol que representará en grafo y el grafo duplicado (incompleto) que utilizará el editor. Al terminar, realizaremos una segunda pasada, SecondPass(), para ajustar los punteros de los padres y los hijos de nuestros nodos del grafo duplicado.

6.3.5 CTreeBar y CMultiTreeBar. La clase CTreeBar será la que contenga un vector de todos los árboles del editor, uno por cada escena. Cada una de estas “escenas” será una instancia de la clase COSGTreeCtrl. class CTreeBar : public CSizingControlBar { public: COSGTreeCtrl *active_tree; std::vector<COSGTreeCtrl*> scenetree_list;

224

Page 226: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

HTREEITEM SetRootNode(osg::Node *node, int scene_idx, HTREEITEM hRoot=NULL); void RemoveSceneTree(int scene_index); void SetActiveSceneTree(COSGTreeCtrl *thetree); void SetActiveSceneTree(int theindex); inline int GetNumScenes(); public: COSGTreeCtrl * CreateSceneTree(); protected: void AddSceneTree(COSGTreeCtrl *thetree); };

Conteniendo a esta clase está MultiTreeBar , que no es más que un agregado de TreeBars, y es la que permite visualizar varias copias de un mismo árbol en el editor, y copiar elementos entre ellas. class OSGMultiTreeBar : public std::vector<CTreeBar*> { public: HTREEITEM SetRootNode(osg::Node *node, int scene_idx, HTREEITEM hRoot=NULL); void AddNewBar(); int GetNumScenes(); void RemoveSceneTree(int scene_index); void SetActiveSceneTree(int index); COSGTreeCtrl * CreateSceneTree(); void ReplicateSceneTree(int scene_idx, int to_bar_index, HTREEITEM hFirst); int GetActiveBarIndex(); int GetBarIndex(CEditTreeCtrl *tree); int GetBarIndex(CTreeBar *treebar); inline CEditTreeCtrl * GetClipboardSrc(); inline void SetClipboardSrc(CEditTreeCtrl *tree); inline void SetCopyOp(int cpop); inline int GetCopyOp(){ return copyOp;} inline void SetActiveBar(CTreeBar *tb); inline CTreeBar* GetActiveBar(); inline TreeNodeInfo *GetSelected; inline int GetActiveSceneTree; CEditTreeCtrl *clipboard_src; CTreeBar *active_bar; int active_tree_index; int copyOp; };

Cuando el usuario decide duplicar una escena en el editor, para visualizar dos o más árboles del mismo grafo de escena, se invoca la funcion AddNewBar(): // Agregamos una nueva DockableBar al programa // que contendrá un el treectrl duplicado void OSGMultiTreeBar::AddNewBar() { CTreeBar *m_newtreebar = new CTreeBar(); OSGAVH->bar_manager.CreateBar(m_newtreebar, "SceneTree", "Grafo de escena"); // la agregamos a la lista this->push_back(m_newtreebar); // Ahora copiamos la informacion de todas las escenas // desde la primera TreeBar a esta. if(this->size()>1) { CTreeBar *bar = this >at(0); - if(bar) { // replicamos TODOS los arboles de escena de una barra

225

Page 227: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

en las siguientes // // Para ello , como se trata de una barra nueva, tendremos // que crear el arbol de cada una de las escenas previamente. for(int i=0;i<bar->scenetree_list.size();i++) { m_newtreebar->CreateSceneTree(); ReplicateSceneTree(i, this->size()-1, NULL); } } } // si es la primera la marcamos como la activa else active_bar = m_newtreebar; }

Podemos ver aquí como MultiTreeBar invoca al Gestor de Bars del Manejador de la Vista Activa para añadir una nueva Bar, conteniendo los árboles de las distintas escenas. La función ReplicateSceneTree(…) permite realizar una replica de una escena de una Bar en otra Bar haciendo uso de la funcion CloneFrom(…) de COSGTreeCtrl: void OSGMultiTreeBar::ReplicateSceneTree(int scene_idx, int to_bar_index, HTREEITEM hFirst) { COSGTreeCtrl *thetree = NULL; CTreeBar *to_bar = this->at(to_bar_index); if(this->size()>1) { CTreeBar *from_bar = this->at(0); thetree = from_bar->scenetree_list[scene_idx]; if(from_bar) { COSGTreeCtrl *tree = to_bar->scenetree_list[scene_idx]; tree->CloneFrom(thetree, hFirst); tree->Redraw(); } } }

6.4 Interacción con el visor 3D

6.4.1 La clase OSGSelection La principal clase relacionada con la interacción con el visor 3D es la clase OSGSelection. Esta mantiene una lista de objetos seleccionados en la escena y permite aplicar operaciones sobre todos ellos de manera conjunta. Cada uno de los objetos seleccionados se almacenará dentro de una estructura llamada SelectionInfo. Esta estructura contendrá la informacion necesaria para el objeto seleccionado: typedef struct SelectionInfo { RefMatrix full_transform; osg::Matrix full_parent; RefMatrix target_transform; osg::Matrix saved_matrix; } SelectionInfo;

La clase OSGSelection es como sigue: class OSGSelection { public:

226

Page 228: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

OSGSelection(void); ~OSGSelection(void); void Init(osg::Group *scn_root, osg::Group *sel_root, osgUtil::SceneView *scview, COSGTreeCtrl *thetree); inline OSGAxisManipulator * GetAxis(); inline int GetCount(); osg::ref_ptr<osg::MatrixTransform> GetSelectionTransform(HTREEITEM hItem); void CalculateTransform(HTREEITEM hItem, osg::MatrixTransform *transf); std::vector<HTREEITEM> GetSelectionList(); osg::MatrixTransform * FindNearestTransform(HTREEITEM hItem); void SetSelectionTransform(std::map<HTREEITEM, SelectionInfo> &selection); osg::Vec3 To3DInPlane (float x, float y, osg::Vec3 &plane_point, osg::Vec3 &plane_n); osg::ref_ptr<osg::MatrixTransform> GetOrCreateParentMatrixTransform (HTREEITEM &hItem); void GetAxisPlaneNormalAndLine(osg::Vec3 &p_planenorm, int &linemov); void StartTranslation(float xpos, float ypos); void StartRotation(float xpos, float ypos); void StartScale(float xpos, float ypos); void DoTranslate(float xpos, float ypos); void EndTranslate(); void DoRotate(float x_offset, float y_offset); void EndRotate(); void DoScale(float x_offset, float y_offset, bool uniform2D, bool uniform3D); void EndScale(); void UpdateSelectionBoundingBox(); bool UpdateAxis(float x, float y); inline void SetAxisPos(osg::Vec3 pos); inline void ShowAxis(bool bshow){axisman.Show(bshow);} void Select(std::vector<HTREEITEM> &list, bool sel=true); void Select(HTREEITEM &hItem, bool sel=true); void SelectWithoutHistory(std::vector<HTREEITEM> &list, bool sel=true); void SelectWithoutHistory(HTREEITEM &hItem, bool sel=true); void SelectOnly(HTREEITEM &hItem); void SelectOnly(std::vector<HTREEITEM> &listSel); void SelectOnlyWithoutHistory(std::vector<HTREEITEM> &listSel); void SelectAll(bool sel=true); void SelectAllWithoutHistory(bool sel=true); void CloneAndSelectOnly(); void SwitchSelect(HTREEITEM hItem); inline void Clear(); inline void Kill(); bool IsSelected(HTREEITEM hItem); inline int IsCursorOverSomething(); void GetIntersection(float x, float y,osg::Group *firstnode, osg::NodePath& nodePath); void GetAxisIntersection(float x, float y, osg::NodePath& nodePath); void GetSelectionIntersection(float x, float y, osg::NodePath& nodePath); void Update(float x, float y, int w_width, int w_height); void OnLButtonDown(float x, float y, int w_width, int w_height, bool key_ctrl, bool key_shift); void OnLButtonUp(float x, float y, float dragx, float dragy, int w_width, int w_height, bool key_ctrl, bool key_shift); void Convert2DOffsetTo3D(float x_offset, float y_offset, osg::Vec3 &vec); inline osg::Vec3 GetSelectionCenter(); void UpdateSelectionCenter(); protected: COSGTreeCtrl *tree; std::map<HTREEITEM, SelectionInfo> selected_objects; osg::ref_ptr<osg::Group> selection_root; osg::ref_ptr<osg::MatrixTransform> axis_data; osg::ref_ptr<osg::Group> scene_root;

// posicion 3D inicial del puntero al aplicar una transformacion osg::Vec3 mouse_saved_pos; osg::Vec3 selection_center; HTREEITEM hTarget; bool alive; // para que no pete la aplicacion y dejar de updatear

227

Page 229: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

ursor int cursor_over; // sobre qué esta el c OSGAxisManipulator axisman; osg::ref_ptr<osgUtil::SceneView> view; int width, height; };

La clase se inicializa pasandole, entre otros, el nodo raiz de la escena, y el nodo raiz que contendrá los datos de selección. Esta clase contiene una tabla de los elementos de la escena seleccionados, en una tabla hash cuya clave es el HTREEITEM del elemento, y cuyo valor es la estructura de datos SelectionInfo. También almacena una instancia de la clase eje manipulador (OSGAxisManipulator), que será una representacion de los ejes de coordenadas para manipular los objetos. Al comenzar una transformación se guardará en u centro de la selección (mouse_saved_pos) , y el valor actual del centro de la selec macena tambien en una variable (selection_center). Otra variable muy importante es cursor_over, que indica en que estado se encuentra actualmente el cursor, en referencia a la escena, los valores que puede tomar son:

na variable el valor del ción se al

enum { CURSOR_OVER_NOTHING=0, CURSOR_OVER_UNSELECTED_OBJECT, CURSOR_OVER_SELECTED_OBJECT, CURSOR_OVER_AXIS};

Y definen si el cursor no está enci ima de un objeto no seleccionado, encima de un objeto seleccionado, o está sobre el eje manipulador. La funcion Update(…) se invoca en cada movimiento del ratón, y se engarga de actualizar la forma del cursor en funcion de la variable cursor_over haciendo uso de la funcion GetIntersection(…), la selección y la posicion de la boundingbox que la define asi como el eje manipulador.

ma de nada, esta enc

void OSGSelection::Update(float x, float y, int w_width, int w_height) { osg::Node *node=NULL; osg::Group *parent=NULL; osg::NodePath nodepath; bool axis_target; if(selected_objects.size() > 0) { cursor_over = CURSOR_OVER_NOTHING; axis_target = UpdateAxis(x,y); // Comprobamos si el raton está encima de alguno // de los objetos seleccionados y en caso de estarlo // marcamos el cursor como que está seleccionando // en funcion de la accion actual. if(!axis_target) { GetIntersection(x,y,scene_root.get(), nodepath); if(nodepath.size()>1) { HTREEITEM hItem = tree->GetItemFromNodePath(nodepath); if(IsSelected(hItem)) cursor_over = CURSOR_OVER_SELECTED_OBJECT; else cursor_ R_UNSELECTED_OBJECT; over = CURSOR_OVE } } } else // ningun objeto seleccionado en pantalla {

228

Page 230: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

GetIntersection(x, y, scene_root.get(), nodepath); if(nodepath.size()>1) { cursor_over = CURSOR_OVER_UNSELECTED_OBJECT; } else cursor_over = CURSOR_OVER_NOTHING; } }

Si existe algun objeto seleccionado, la funcion Update(…) realiza una llamada a UpdateAxis() para actualizar tambien el eje manipulador. bool OSGSelection::UpdateAxis(float x, float y) { osg::NodePath nodepath; // Obtenemos la interseccion con los elementos del EJE auxiliar GetAxisIntersection(x,y, nodepath); if (nodepath.size() >0) { cursor_over = CURSOR_OVER_AXIS; osg::ref_ptr<osg::Node> node= nodepath[nodepath.size()-1]; if(node->getName() == "CONE_X") axisman.SetAxis(AXIS_X); else if(node->getName() == "CONE_Y") axisman.SetAxis(AXIS_Y); else if(node->getName() == "CONE_Z") axisman.SetAxis(AXIS_Z); else if(node->getName() == "PLANE_XY") axisman.SetAxis(AXIS_X | AXIS_Y); else if(node->getName() == "PLANE_ZX") axisman.SetAxis(AXIS_Z | AXIS_X); else if(node->getName() == "PLANE_ZY") axisman.SetAxis(AXIS_Z | AXIS_Y); return true; } return false; }

Los eventos del ratón son la principal herramienta de interaccion en el visor, por tanto es un elemento importante que debe de ser introducido: void OSGSelection::OnLButtonDown(float x, float y, int w_width, int w_height, bool key_ctrl, bool key_shift) { osg::NodePath nodepath; width = w_width; height = w_height; // Al hacer un click , comprobamos si el objeto sobre el que pulsamos // esta seleccionado // 1) Esta seleccionado // a) Si esta pulsada la tecla CTRL Hacemos un Switch de ese objeto // b) Sino , no hacemos nada, y no deseleccionaremos // los demas objetos hasta el buttonUP // siempre y cuando no hayamos hecho ningun DRAG // 2) No esta seleccionaddo // a) Si esta pulsada la tecla CTRL lo agregamos // b) Sino, directamente lo seleccionamos SOLO A EL GetIntersection(x,y, scene_root.get(), nodepath); if(key_shift && selected_objects.size()>0 && cursor_over == CURSOR_OVER_AXIS) { CloneAndSelectOnly();

229

Page 231: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

} // Hemos hecho click sobre un objeto! else if(nodepath.size()>1) { HTREEITEM hItem = tree->GetItemFromNodePath(nodepath); if(hItem) { if(key_shift) { CloneAndSelectOnly(); } else { if(IsSelected(hItem)) { if(key_ctrl) SwitchSelect(hItem); else ;//SelectOnly(hItem); } else { if(key_ctrl) Select(hItem); else SelectOnly(hItem); } } } //Update(x, y, width, height); axisman.Show(true); } else // hemos hecho click sobre el Vacio if(cursor_over == CURSOR_OVER_NOTHING) { if(selected_objects.size()) { SelectAll(false); axisman.Show(false); } } }

La función OnLButtonDown(…) se invoca al pulsar el botón izquierdo del ratón, en función de lo que esté seleccionando el cursor, o de lo que ya esté seleccionado, y de la tecla del teclado que tengamos pulsada, el comportamiento puede ser distinto, así por ejemplo, si tenemos el cursor sobre el eje manipulador y existen objetos seleccionados y además tenemos pulsada la tecla Shift, lo que conseguiremos será clonar la selección actual. void OSGSelection::OnLButtonUp(float x, float y, float dragx, float dragy, int w_width, int w_height, bool key_ctrl, bool key_shift) { osg::NodePath nodepath; width = w_width; height = w_height; if(dragx == 0 && dragy == 0) { GetIntersection(x,y, scene_root.get(), nodepath); if( cursor_over == CURSOR_OVER_SELECTED_OBJECT ) { // Hemos hecho click sobre un objeto! if(nodepath.size()>1) { HTREEITEM hItem = tree->GetItemFromNodePath(nodepath); if(hItem) {

230

Page 232: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

SelectOnly(hItem); } } } else { if(cursor_over ==CURSOR_OVER_NOTHING) { if(selected_objects.size()) { SelectAll(false); axisman.Show(false); } } } } }

6.4.2 La clase OSGAxisManipulator Esta clase representa los tres ejes de coordenadas y permite una interaccion con el usuario para su posterior transformado. Esta clase nos permite saber si el usuario ha seleccionado uno o dos ejes simultáneamente y cuales son estos ejes. class OSGAxisManipulator { public: OSGAxisManipulator(void); ~OSGAxisManipulator(void); void SetPos(osg::Vec3 &pos); void SetAxis(unsigned int mask); void AddAxis(unsigned int mask); void RemoveAxis(unsigned int mask); bool GetAxis(unsigned int flag); void SwitchAllOff(); void SwitchAxis(unsigned int mask, int mode); void Show(bool show); inline osg::ref_ptr<osg::Switch> GetRootNode(){return axis_root;} osg::ref_ptr<osg::Switch> axis_root; osg::ref_ptr<osg::MatrixTransform> axis_trans; protected: osg::ref_ptr<osg::Switch> p_xy; osg::ref_ptr<osg::Switch> p_zx; osg::ref_ptr<osg::Switch> p_zy; osg::ref_ptr<osg::Switch> switch_ejes; int selected_axis; int last_selected; };

Esta clase consta de una serie de nodos, Switches e información geométrica que se irán activando y desactivando para el resalte cuando el cursor pase por encima de algun eje. Esta estructura presenta el siguiente aspecto de la siguiente figura 6.1.

231

Page 233: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 6.1. Estructura del grafo que forma el Eje Manipulador

La función SetAxis(…) e tivar los distintos hijos de los Switches de OpenSceneGraph que darán al eje manipulador el comportamiento que queremos. Los hijos los identificaremos por un número:

s la encargada de activar y desac

#define CHILD_NORMAL_AXIS 0 #define CHILD_X_AXIS 1 #define CHILD_Y_AXIS 2 #define CHILD_Z_AXIS 3 #define CHILD_XY_AXIS 4 #define CHILD_ZX_AXIS 5 #define CHILD_ZY_AXIS 6

Y la función es como sigue: void OSGAxisManipulator::SetAxis(unsigned int mask) { if(mask != selected_axis) { selected_axis = mask; SwitchAllOff(); SwitchAxis(mask,1); } } void OSGAxisManipulator::SwitchAxis(unsigned int mask, int mode) { int res = AXIS_Y|AXIS_Z;

232

Page 234: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

if(mask==(AXIS_X|AXIS_Y)) { p_xy->setSingleChildOn(mode); switch_ejes->setSingleChildOn(CHILD_XY_AXIS); } else if(mask==(AXIS_X|AXIS_Z)) { p_zx->setSingleChildOn(mode); switch_ejes->setSingleChildOn(CHILD_ZX_AXIS); } else if(mask==(AXIS_Y|AXIS_Z)) { p_zy->setSingleChildOn(mode); switch_ejes->setSingleChildOn(CHILD_ZY_AXIS); } else if(mask==(AXIS_X)) { p_xy->setSingleChildOn(0); p_zx->setSingleChildOn(0); p_zy->setSingleChildOn(0); switch_ejes->setSingleChildOn(CHILD_X_AXIS); } else if(mask==(AXIS_Y)) { p_xy->setSingleChildOn(0); p_zx->setSingleChildOn(0); p_zy->setSingleChildOn(0); switch_ejes->setSingleChildOn(CHILD_Y_AXIS); } else if(mask==(AXIS_Z)) { p_xy->setSingleChildOn(0); p_zx->setSingleChildOn(0); p_zy->setSingleChildOn(0); switch_ejes->setSingleChildOn(CHILD_Z_AXIS); } }

6.4.3 La clase MFCKeyboardMouseCallback Esta clase deriva de Producer::KeyboardMouseCallback y dispone de funciones de procesado de teclas y eventos de ratón. Tambien es la que almacena los distintos cursores que toma la aplicación en función del modo activo. Es en esta clase donde se decide si el movimiento del ratón deberá hacer una llamada a rotar, escalar, o trasladar, dentro de la función mouseMotion(). Además es la clase que contiene el objeto OSGSelection, y también el objeto TrackBall. La

Producer::Trackball proporciona a la vista movilidad y un comportamiento de rotación o desplazamiento de cámara, y permite establecer la vista directamente con su matriz en caso necesario.

clase

class MFCKeyboardMouseCallback : public Producer::KeyboardMouseCallback { public: MFCKeyboardMouseCallback(osgUtil::SceneView* sceneView); void home(); virtual void keyPress( Producer::KeyCharacter key); virtual void specialKeyRelease( Producer::KeyCharacter key); virtual void specialKeyPress( Producer::KeyCharacter key); virtual void mouseScroll(Producer::KeyboardMouseCallback::ScrollingMotion sm); virtual void mouseMotion( float mx, float my ) ; virtual void passiveMouseMotion( float mx, float my ) ; virtual void buttonPress( float mx, float my, unsigned int mbutton ); virtual void buttonRelease( float mx, float my, unsigned int mbutton ) ; virtual void doubleButtonPress(float mx, float my, unsigned int mbutton ) ;

233

Page 235: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

virtual void OnDoubleLButtonPress(); void LookAtSelection(); void SetTrackballMatrix(Producer::Matrix &m){ _trackBall->setMatrix(m); _trackBall->update(); } inline Producer::Trackball *GetTrackball(){ return _trackBall.get();} float mx() { return _mx; } float my() { return _my; } unsigned int mbutton() { return _mbutton; } void resetTrackball(); inline void SetRedrawCursor(int bb){must_redraw_cursor=bb;} inline bool MustRedrawCursor(){ return must_redraw_cursor;} void SetSelMode(int mod); inline int GetSelMode(){return selection.GetMode();} inline HCURSOR GetCursor(){return ccursor;} void SetCursor(); void DisableTrackball(); osg::Matrixd getViewMatrix(); OSGSelection selection; int _px, _py; private: float _mx, _my; float _mx_buttonPress, _my_buttonPress; float _mxdrag, _mydrag; unsigned int _mbutton; osg::ref_ptr<Producer::Trackball> _trackBall; osg::ref_ptr<osgUtil::SceneView> _sceneView; bool key_ctrl; bool key_shift; bool clone_actived; bool started_translate, started_rotate, started_scale; HCURSOR crotate, ctranslate, ctranslateview, czoom, crotateview, cscale, cselect; HCURSOR ccursor; // Current bool must_redraw_cursor; bool lb_pressed; };

6.5 El sistema de deshacer / rehacer.

6.5.1 La clase OSGAction. Se trata de una clase virtual pura, que servirá para implementar todas y cada una de las acciones que se puedan deshacer en el editor. class OSGAction : public osg::Referenced { public: OSGAction(); virtual ~OSGAction(); virtual void Execute()=0; virtual std::string getActionString() = 0; virtual void Undo()=0; };

234

Page 236: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Veamos un ejemplo de acción, por ejemplo la llamada a setColor del StateAttribute FOG de OpenSceneGraph: class ActSetFogColor : public OSGAction { public: ActSetFogColor(osg::Fog *_sa, const osg::Vec4 &_old, const osg::Vec4 &_new); ~ActSetFogColor(void); virtual void Execute(); virtual void Undo(); virtual std::string getActionString() { return std::string("Modificar Color Fog"); } osg::Vec4 old_value; osg::Vec4 value; osg::ref_ptr<osg::Fog> sa; };

Y la implementacion de las funciones: ActSetFogColor::ActSetFogColor(osg::Fog *_sa, const osg::Vec4 &_old, const osg::Vec4 &_new) { sa = _sa; value = _new; old_value = _old; } void ActSetFogColor::Execute() { sa->setColor(value); } void ActSetFogColor::Undo() { sa->setColor(old_value); }

6.5.2 La clase OSGHistory Para gestionar las acciones, y permitir avanzar y retroceder en el historial de acciones existe la clase OSGHistory : class OSGHistory { typedef std::vector<osg::ref_ptr<OSGAction> > ActionList; public: OSGHistory(void); ~OSGHistory(void); void AddAction(OSGAction *c); void Undo(); void Redo(); void GoTo(unsigned position); void Clear(); protected: ActionList actions; /// Lista de acciones ejecutadas unsigned position; // Posicion actual en la historia };

OSGHistory::OSGHistory(void) { position = 0; }

235

Page 237: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

OSGHistory::~OSGHistory(void) { actions.clear(); } void OSGHistory::AddAction(OSGAction *c) { if (position == actions.size()) { actions.push_back(c); position++; } else { while (position < actions.size()) { actions.erase(actions.begin()+position); } actions.push_back(c); position++; } } void OSGHistory::Undo() { if(position > 0) { position--; actions[position]->Undo(); } } void OSGHistory::Redo() { if (position < actions.size()) { actions[position]->Execute(); position++; } } void OSGHistory::Clear() { actions.clear(); position=0; }

6.6 El sistema gestor de plugins

6.6.1 El plugin Cartoon Hemos implementado un plugin como ejemplo en nuestro editor. Este plugin sirve para dar soporte a un nuevo tipo de nodo de OpenSceneGraph. Para que un desarrollador cualquiera pueda generar un plugin, deberá crear un nuevo proyecto, y se le deberá facilitar el fichero OSGWorld.lib, para poder linkar la dll. En primer lugar tendremos que implementar la clase para encapsular este tipo de dato, derivándola de OSGNodeType, de manera similar a como hemos hecho con la clase Drawable derivándola de OSGObjectType: class PluginCartoon : public OSGNodeType { public: PluginCartoon(void);

236

Page 238: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

~PluginCartoon(void); virtual void ShowCustomData(osg::Object *obj); virtual void CreateIOControls(); virtual void ParamModified(osg::Object *obj, int param_id); virtual void AttachParamModified(int attach_id, int param_id){} virtual void OnEndSelection(osg::Object *obj){}; virtual osg::ref_ptr<osg::Object> NewInstance(); virtual osg::ref_ptr<osg::Object> NewInstance(osg::Object *_obj); };

Crearemos un nuevo proyecto para crear una DLL, que deberá contener las funciones que ya hemos explicado: #define PLUG_API __declspec(dllexport) extern "C" PLUG_API OSGTabOutput* LibClassInstance(int i); extern "C" PLUG_API int LibNumClasses(); extern "C" PLUG_API std::string LibDescription(); extern "C" PLUG_API int LibVersion(); PLUG_API OSGTabOutput* LibClassInstance(int i) { switch(i) { case 0: return new PluginCartoon(); break; } return NULL; } PLUG_API int LibNumClasses() { return 1; } PLUG_API std::string LibDescription() { std::string str; str = "Plugin de extension para agregar el Nodo de efectos FX tipo Cartoon que da un aspecto 2D a la geometria 3D"; return str; } PLUG_API int LibVersion() { return OSGWORLD_VERSION; }

6.6.2 La clase OSGPluginManager Esta clase almacena los plugins que el editor va cargando, utilizando la siguiente estructura de datos: typedef std::vector<OSGTabOutput*> TabOutputList; class PluginInfo { public: PluginInfo(){}; ~PluginInfo(){}; std::string file;

237

Page 239: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

std::string path; int version; std::string desc; HMODULE handle; TabOutputList objlist; };

Cont sponde con el plugin, la ruta, la version con la que fue compilado, la descripción del mismo, el manejador que nos ha devuelto, y la lista de objetos OSGTabOutput que contiene.

iene información acerca del fichero que se corre

class OSGPluginManager { public: OSGPluginManager(void); ~OSGPluginManager(void); // Carga una DLL PluginInfo* LoadPlugin(std::string szFileName, std::string path=""); PluginInfo * GetPluginInfo(std::string filename); OSGTabOutput* GetPluginClass(std::string name); // libera una DLL ya cargada bool FreePlugin(std::string name); std::map<std::string, PluginInfo*> plugin_files; std::map<std::string, OSGTabOutput*> plugin_classes; };

Este gestor nos permite cargar el plugin, y acceder al mismo mediante el nombre del fichero, o tambien acceder al objeto tipo OSGTabOutput que nos interese obtener haciendo uso del nombre de la clase que nos interesa obtener. typedef OSGTabOutput* (*PL_LIBCLASSINSTANCE)(int); typedef int (*PL_LIBNUMCLASSES)(void); typedef std::string (*PL_LIBDESC)(); typedef int (*PL_LIBVERSION)(void); PluginInfo* OSGPluginManager::LoadPlugin(std::string szFileName, std::string path) { std::string full_path = path + szFileName; HMODULE hModule = LoadLibrary(full_path.c_str()); OSGTabOutput *obj = NULL; PluginInfo *inf=NULL; if (!hModule) return false; else { inf = new PluginInfo(); PL_LIBCLASSINSTANCE pClassInstance = (PL_LIBCLASSINSTANCE) GetProcAddress(hModule, _T("LibClassInstance")); PL_LIBNUMCLASSES pNumClasses = (PL_LIBNUMCLASSES) GetProcAddress(hModule, _T("LibNumClasses")); PL_LIBVERSION pVersion = (PL_LIBVERSION) GetProcAddress(hModule, _T("LibVersion")); PL_LIBDESC pDescription = (PL_LIBDESC) GetProcAddress(hModule, _T("LibDescription")); if (pClassInstance != NULL && pNumClasses != NULL) { int numclasses = pNumClasses(); inf->handle = hModule; inf->desc = pDescription(); inf->version = pVersion(); inf->file = szFileName; inf->path = path; if(!GetPluginInfo(szFileName)){ for(int i=0;i<numclasses;i++) {

238

Page 240: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

obj = pClassInstance(i); if(obj){ inf->objlist.push_back(obj); nom = obj->GetName(); // Si no existe ya esta clase... if(!GetPluginClass(nom)) plugin_classes[nom] = obj; else{ char msg[256]; sprintf("%s, no se pudo cargar la clase %s puesto que ya existe en otro plugin", szFileName.c_str(), nom.c_str()); AfxMessageBox(msg); } } } plugin_files[szFileName] = inf; }else delete inf; } } return inf; }

6.6.3 La clase OutPlugins Esta clase deriva de OSGTabOutput, y se utiliza para mostrar una serie de controles en el interfaz que muestre información sobre los plugins que hay cargados en el sistema. Puesto que esta clase se crea automaticamente por el editor al arrancar y registrar todos los TabOutputs, es la encargada de distribuir el cada uno de los objetos cargados en el plugin entre los distintos gestores del sistema al cargar todos los plugins: #define NUM_PARAMS 3 enum{PARAM_PLUGINLIST, PARAM_DESC, PARAM_CLASSLIST}; OutPlugins::OutPlugins(void) { name = "Gestion de plugins"; plugins_loaded = false; } OutPlugins::~OutPlugins(void) { } void OutPlugins::CreateIOControls() { OSGParamGroupDesc *desc = new OSGParamGroupDesc[NUM_PARAMS]; desc[0].Set(PARAM_PLUGINLIST, TYPE_LISTBOX, "Listado de plugins:"); desc[1].Set(PARAM_DESC, TYPE_TEXTBOX, "Descripción:", DESC_READONLY); desc[2].Set(PARAM_CLASSLIST, TYPE_LISTBOX, "Clases:"); OSGParamGroup *mygroup = new OSGParamGroup("Gestion de Plugins", true); for(int i=0;i<NUM_PARAMS;i++) mygroup->push_back(&desc[i]); mygroup->SetTabIndex(3); iogroups.push_back(mygroup); } void OutPlugins::ShowCustomData(osg::Object *obj) { std::vector<std::string> lista; if(!plugins_loaded) {

239

Page 241: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

FindDLLs(lista); SetParamValue(PARAM_PLUGINLIST, lista); plugins_loaded = true; } } // Atencion, aqui obj siempre es null void OutPlugins::ParamModified(osg::Object *obj, int param_id) { std::string nom; OSGTabOutput *plug; switch(param_id) { case PARAM_PLUGINLIST: { GetParamValue(param_id, nom); PluginInfo *inf = OSGAVH->plugin_manager.GetPluginInfo(nom); if(inf) { std::vector<std::string> vec; for(int i=0;i<inf->objlist.size();i++) vec.push_back(inf->objlist[i]->GetName()); SetParamValue(PARAM_CLASSLIST, vec); SetParamValue(PARAM_DESC,inf->desc); } } break; } } int OutPlugins::FindDLLs(std::vector<std::string> &lista) { long lFile = 0L; struct _finddata_t sFILE; CString szSearchPath = "./plugins/*.dll"; CString szCommandLine ; int nNumDlls = 0 ; lFile = (long) _findfirst(szSearchPath, &sFILE); PluginInfo *inf; OSGTabOutput *obj; if (lFile != -1L) { do { CString kk = "./plugins/"; inf = OSGAVH->plugin_manager.LoadPlugin(sFILE.name, kk.GetBuffer()); if(inf) { lista.push_back(inf->file); for(int i=0;i<inf->objlist.size();i++) { obj = inf->objlist[i]; switch(obj->OutputType()) { case OUTPUT_TYPE_DEFAULT: OSGAVH-> output_manager.RegisterTabOutput(obj); break; case OUTPUT_TYPE_ATTRIBUTE: case OUTPUT_TYPE_OBJECT: { OSGAVH->objecttypem.RegisterType(obj); } break; case OUTPUT_TYPE_NODE: OSGAVH->nodetypem.RegisterType(obj); break;

240

Page 242: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

} } nNumDlls++; } } while (_findnext(lFile, &sFILE) == 0); _findclose(lFile); } return nNumDlls; }

6.7 El manejador de la vista activa y las clases MFC

6.7.1 La clase OSGActiveViewHandler Este será el único objeto global en la aplicación (sin tener en cuenta el código generado por las MFCs). OSGActiveViewHandler *OSGAVH;

Y será la encargada de contener las instancias de todos los discomo distintas funcionalidades globales.

tintos gestores del sistema, asi

class OSGActiveViewHandler { public: OSGActiveViewHandler(void); ~OSGActiveViewHandler(void); void ChangeView(osgUtil::SceneView *scnview, Producer::RenderSurface *surface, osg::Group * scn_root, OSGHistory *history, OSGSelection *selec); void SetMainFrame(CMainFrame *mf); void SetActiveSceneTree(int scene_ID); void SetActiveBar(CWnd *actbar); inline void SetRootNode(osg::Node *node, int scene_ID); void InitObjectTypes(); int InitBars(); void InitTabOutput(); void SaveBarStates(); void SaveToFile(std::string nom); osg::ref_ptr<osg::Node> CreateNode(std::string name); TreeNodeInfo *CreateTreeNode(std::string name); HTREEITEM AddNode(std::string node_name); HTREEITEM AddNodeWithHistory(std::string node_name, HTREEITEM hParent); HTREEITEM AddNode(std::string node_name, HTREEITEM hParent); HTREEITEM AddNode(TreeNodeInfo *tni, HTREEITEM hParent); void AddParentNode(std::string node_name); void DeleteNode(HTREEITEM hItem, int mirror_index); void CleanSubtree(HTREEITEM hItem, int mirror_index); void CopyNode(TreeNodeInfo *tni, TreeNodeInfo *newparent); void SelectObject(HTREEITEM hItem, bool select=true); void SelectObjectOnly(std::vector<HTREEITEM> &vec); void SelectObjectOnly(HTREEITEM hItem); void SelectObjectFromTree(HTREEITEM hItem, bool select=true); void SelectObject(int x, int y); void SelectObject(osg::Node * node, osg::Group *parent,bool select); void SelectObject(TreeNodeInfo *node, TreeNodeInfo *parent, bool select); void SelectAll(bool select); void ShowTreeNodeInfo(TreeNodeInfo *tni, bool reset=true); void ShowTabOutput(OSGTabOutput *outp); void Exec(OSGAction *action, bool addtohistory=true);

241

Page 243: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

void CloseAllMirrors(); void OnCloseScene(int scene_id); void OnCloseTreeBar(CTreeBar *treebar); BOOL CreateControlBar(); inline void SetSelectedTni(TreeNodeInfo *tni); inline TreeNodeInfo * GetSelectedTni(); inline COSGTreeCtrl * GetTreeCtrl(); inline COSGTreeCtrl * GetTreeCtrl(int mirror_index); inline COSGTreeCtrl * GetTreeCtrl(int mirror_index, int scene_index); inline int GetBarIndex(CEditTreeCtrl *tree); inline int GetBarIndex(CTreeBar *treebar); // Supuestamente esta llamada se hace despues de crear un nuevo SceneTree int GetUniqueSceneID(); inline int GetSceneIndex(int scene_id); inline bool int scene_id); IsSceneActive( HTREEITEM GetMirrorItem(HTREEITEM hItem, int mirror_idx=0); // Globales y unicos CMainFrame *mainfr; OSGObjectTypeManager nodetypem; OSGObjectTypeManager objecttypem; OSGDockBarManager bar_manager; OSGParamManager param_manager; OSGTabOutputManager output_manager; OSGPluginManager plugin_manager; std::map<int, int> hash_sceneindex; int last_sceneID; // Dependientes del view activo osg::ref_ptr<osgUtil::SceneView> m_SceneView; osg::ref_ptr<Producer::RenderSurface> m_RenderSurface; osg::ref_ptr<osg::Group> scene_root; OSGHistory *m_History; OSGSelection *selection; CRITICAL_SECTION critical_section; TreeNodeInfo *last_tni; OSGMultiTreeBar m_wndSceneTree; CDebugBar m_wndDebug; CGridBar m_wndDataGrid; CPropSheetBar m_wndSheetBar; //Barra principal de control };

Como podemos ver, esta clase contiene el gestor de NodeTypes, el gestor de ObjectTypes, el Gestor de Bars, el Gestor de parámetros, el gestor de TabOutputs, el gestor de plugins, el gestor de TreeBars, el gestor de historia actual, y la selección de objetos, y una instancia de la barra principal que es un conjunto de pestañas, cada una con una funcionalidad diferente. También contiene una referencia al visor actual y su superficie de render, así como el nodo raíz de la escena d Esta clase es la encargada de mostar la información de un nodo de un grafo de escena en el interfaz de usuario, lo que hace realmente esta función es mostrar los datos del nodo a través de su NodeType:

el grafo de escena.

void OSGActiveViewHandler::ShowTreeNodeInfo(TreeNodeInfo *tni, bool reset/*sin uso*/) { if(!tni->nodetype->DialogsCreated()){ param_manager.RecursiveCreateDialogs(tni->nodetype); } if(last_tni) { // Si son TIPOS de nodo distintos // regeneramos los controles if(last_tni->nodetype != tni->nodetype){ last_tni->nodetype->RecursiveClearRollupContent(); tni->nodetype->RecursiveGenerateRollupContent();

242

Page 244: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

} // Ademas si son nodos distintos // eliminamos los controles del StateAttribute // Y notificamos al NodeType del cambio de nodo if(last_tni != tni){ last_tni->nodetype->RecursiveOnEndSelection(); } }else{ if(!tni->nodetype->IsDialogShown()) tni->nodetype->RecursiveGenerateRollupContent(); } if(tni->nodetype){ tni->nodetype->SetSelectedObj(tni->node.get()); tni->nodetype->ShowRecursiveData(); } last_tni = tni; }

La funcion RecursiveGenerateRollupContent() invocada por ShowTreeNodeInfo() invoca a GenerateRollupContent(). // Muestra los controles por pantalla // Los controles ya existen en memoria // tan solo los muestra. // Si tiene algun tipo padre, crea tambien los dialogos // que contenga ese nodo (LLAMADA RECURSIVA). // El orden de las llamadas *importa* ya que dependerá // del orden en que se muestren los Grupos de parametros. void OSGObjectType::RecursiveGenerateRollupContent() { if(parent_type != NULL) parent_type->RecursiveGenerateRollupContent(); GenerateRollupContent(); } // Crea para cada unos de los grupos de parametros // que contiene el tipo de nodo, un dialogo. void OSGTabOutput::GenerateRollupContent() { if(HasIOGroups() && DialogsCreated()){ for(unsigned i=0; i<iogroups.size();i++){ OSGParamGroup *gr = iogroups[i]; if(gr->GetDialog()){ gr->SetGroupPage( OSGAVH->m_wndSheetBar.AddGroup( gr->GetTabIndex(), gr->group_name.c_str(), gr->GetDialog(), gr->IsRollable(), false, gr->IsExpanded())); } } } dialog_shown = true; }

También implementa una función para mostrar los distintos TabOutputs: void OSGActiveViewHandler::ShowTabOutput(OSGTabOutput *outp) { if(!outp->DialogsCreated()) { param_manager.CreateDialogs(outp); } if(!outp->IsDialogShown()) outp->GenerateRollupContent(); outp->ShowData(NULL); }

243

Page 245: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Inicializa las Bars del interfaz de usuario : int OSGActiveViewHandler::InitBars() { if(!mainfr) return -1; m_wndSceneTree.AddNewBar(); if (!m_wndDebug.Create(_T("Debug"), mainfr, CSize(180, 380), TRUE, FIRST_BAR_ID+2)) { TRACE0("Failed to create Debug\n"); return -1; } m_wndDebug.SetBarStyle(m_wndDebug.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); m_wndDebug.EnableDocking(CBRS_ALIGN_ANY); mainfr->DockControlBar(&m_wndDebug,AFX_IDW_DOCKBAR_LEFT); m_wndDebug.setCaption("Debug Output"); CreateControlBar(); if (mainfr->VerifyBarState(_T("OSGWORLD_BarState"))) { CSizingControlBar::GlobalLoadState(_T("OSGWORLD_BarState")); mainfr->LoadBarState(_T("OSGWORLD_BarState")); } }

Y crea la barra principal que contiene las distintas pestañas. Los Rollups son diálogos que permiten extenderse más de lo que la pantalla ocupa, generando una especie de barra de Scroll en caso de extenderse más de los límites visuales de la aplicación: BOOL OSGActiveViewHandler::CreateControlBar() { CTabContainerDlg *p1 = new CTabContainerDlg(); CTabContainerDlg *p2 = new CTabContainerDlg(); CTabContainerDlg *p3 = new CTabContainerDlg(); CTabContainerDlg *p4 = new CTabContainerDlg(); CTabContainerDlg *p5 = new CTabContainerDlg(); m_wndSheetBar.AddRollup(p1, IDD_TAB_CONTAINER, IDI_ICON5); m_wndSheetBar.AddRollup(p2, IDD_TAB_CONTAINER, IDI_ICON6); m_wndSheetBar.AddRollup(p3, IDD_TAB_CONTAINER, IDI_ICON7); m_wndSheetBar.AddRollup(p4, IDD_TAB_CONTAINER, IDI_ICON8); m_wndSheetBar.AddRollup(p5, IDD_TAB_CONTAINER, IDI_ICON9); // Creamos la barra y seguidamente creamos los rollups // (necesitan saber cual es su padre una vez creado) m_wndSheetBar.CreateWithRollups(_T("PropSheetBar"), mainfr, CSize(200, 380), TRUE, FIRST_BAR_ID+3); m_wndSheetBar.setCaption("Parametros"); m_wndSheetBar.SetBarStyle(m_wndSheetBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); m_wndSheetBar.EnableDocking(CBRS_ALIGN_ANY); mainfr->DockControlBar(&m_wndSheetBar); return true; }

Tambien inicializamos los tipos de datos soportados:

244

Page 246: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

void OSGActiveViewHandler::InitObjectTypes() { // Primero registramos los object // para los posibles attach de los nodetypes o attribtypes objecttypem.RegisterType(new ObjTypeStateSet()); objecttypem.RegisterType(new ObjTypeDrwStateSet()); objecttypem.RegisterType(new ObjTypeCounter()); objecttypem.RegisterType(new ObjTypeVariableRateCounter()); objecttypem.RegisterType(new ObjTypeRandomRateCounter()); objecttypem.RegisterType(new ObjTypeConstantRateCounter()); objecttypem.RegisterType(new ObjTypeDrawable()); objecttypem.RegisterType(new ObjTypeShapeDrawable()); objecttypem.RegisterType(new ObjTypeGeometry()); objecttypem.RegisterType(new ObjTypeParticle()); objecttypem.RegisterType(new ObjTypeParticleSystem()); objecttypem.RegisterType(new ObjTypeText()); // StateAttributes objecttypem.RegisterType(new AttTypeFog()); objecttypem.RegisterType(new AttTypeMaterial()); objecttypem.RegisterType(new AttTypeBlendFunc()); objecttypem.RegisterType(new AttTypeLight()); objecttypem.RegisterType(new AttTypeTexEnv()); objecttypem.RegisterType(new AttTypeTexGen()); objecttypem.RegisterType(new AttTypeTexture()); objecttypem.RegisterType(new AttTypeTexture2D()); objecttypem.RegisterType(new AttTypeVertexProgram()); objecttypem.RegisterType(new AttTypeFragmentProgram()); OSGNodeType *first = new TypeNode(); // Iniciamos la informacion de los parametros // de los nodos. nodetypem.RegisterType(first); nodetypem.SetDefaultType(first); nodetypem.RegisterType(new TypeGroup()); nodetypem.RegisterType(new TypeLOD()); nodetypem.RegisterType(new TypePagedLOD()); nodetypem.RegisterType(new TypeSwitch()); nodetypem.RegisterType(new TypeGeode()); nodetypem.RegisterType(new TypeSequence()); nodetypem.RegisterType(new TypeBillboard()); nodetypem.RegisterType(new TypeTransform()); nodetypem.RegisterType(new TypeDOFTransform()); ); nodetypem.RegisterType(new TypePositionAttitudeTransform() nodetypem.RegisterType(new TypeMatrixTransform()); nodetypem.RegisterType(new TypeAutoTransform()); nodetypem.RegisterType(new TypeLightSource()); nodetypem.RegisterType(new TypeParticleSystemUpdater()); nodetypem.RegisterType(new TypeParticleProcessor()); nodetypem.RegisterType(new TypeEmitter()); nodetypem.RegisterType(new TypeModularEmitter()); nodetypem.RegisterType(new TypeFXEffect()); nodetypem.RegisterType(new TypeFXCartoon()); nodetypem.RegisterType(new TypeFXSpecularHighlights()); nodetypem.RegisterType(new TypeFXBumpMapping()); output_manager.RegisterTabOutput(new OutCreateNodes()); output_manager.RegisterTabOutput(new OutPlugins()); }

Y liberar la memoria necesaria cuando cerramos una escena : // Al cerrar una escena tendremos que liberar toda // la memoria del arbol correspondiente en // cada uno de los mirrors void OSGActiveViewHandler::OnCloseScene(int scene_id) { int scene_index = hash_sceneindex[scene_id]; if(last_tni) { last_tni->nodetype->RecursiveOnEndSelection();

245

Page 247: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

last_tni->nodetype->RecursiveClearRollupContent(); SetSelectedTni(NULL); last_tni = NULL; } m_wndSceneTree.RemoveSceneTree(scene_index); // Disminuimos cada uno de los indices de cada escena std::map<int, int>::iterator m_it; int del_key; for(m_it=hash_sceneindex.begin(); m_it!=hash_sceneindex.end(); ++m_it) { if(m_it->second >= scene_index) hash_sceneindex[m_it->first] = hash_sceneindex[m_it->first]-1; } hash_sceneindex.erase(scene_id); // Borramos el historial m_History->Clear(); }

6.7.2 La clase COSGWorldView Es la vista MFC donde se representa el visor 3D y la que captura todos los eventos del visor. Tambien se engarga d anejador de la Vista Activa de que se ha seleccionado esta vista como activa. Al cargar un fichero, las MFC’s crean una nueva clase Documento y otra de Vista (COSGWorldView) que se muestra a continuación.

e inicializar los datos de le escena, e informar al M

class COSGWorldView : public CView { public: static COSGWorldView * COSGWorldView::GetActiveView(); // Reemplazos public: virtual void OnDraw(CDC* pDC); // Reemplazado para dibujar esta vista void SetPolygonMode(osg::PolygonMode::Mode m); void SetShading(osg::ShadeModel::Mode m); void SetProjectionType(ProjectionType pt); void SetViewType(ViewType vt); protected: void DoFrame(); osg::ref_ptr<Producer::KeyboardMouse> m_KBM; osg::ref_ptr<MFCKeyboardMouseCallback> m_KBMCallback; osg::ref_ptr<Producer::RenderSurface> m_RenderSurface; osg::ref_ptr<osgUtil::SceneView> m_SceneView; osgDB::DatabasePager* m_DatabasePager; BOOL m_bRenderSurfaceRealized; BOOL m_bModelLoaded; osg::Timer_t m_StartTick; // Frame Number unsigned int m_uiFrameNum; BOOL m_bGotFocus; // indice de la escena correspondiente a esta view // (se usa para el arbol) int scenetree_ID; OSGHistory m_History; osg::ref_ptr<osg::Group> scene_root; osg::ref_ptr<osg::StateSet> global_state_set;

246

Page 248: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

};

Esta clase contiene distintos elementos necesarios para interactuar con OpenSceneGraph:

• La superficie de render necesaria para dibujar el grafo. • El DatabasePager • Un manejador de eventos de teclado y ratón • La visualización del grafo de escena la escena • La funcion de dibujado

Además, contendrá una referencia al nodo raíz de la escena del grafo de escena y un StateSet global que nos permitirá cambiar el modo de visualizacion del editor. Esta clase será la que contenga la instancia real del gestor de Historia (dehacer / rehacer). El Manejador de la Vista Activa tan solo tendrá una referencia al gestor de historia activo en ese momento. La función OnInitialUpdate es la que se encarga de inicializar todos los datos iniciales del grafo, incluyendo los datos auxiliares como es el Grid y el Eje manejador: void COSGWorldView::OnInitialUpdate() { CView::OnInitialUpdate(); osg::ref_ptr<osg::Group> root = new osg::Group(); osg::ref_ptr<osg::Group> node_auxdata = new osg::Group(); osg::ref_ptr<osg::Group> node_selectdata = new osg::Group(); //osg::ref_ptr<osg::Switch> node_axisdata = new osg::Switch(); scene_root = new osg::Group(); osg::ref_ptr<osg::PositionAttitudeTransform> transf2 = new osg::PositionAttitudeTransform(); // La estructura basica del grafo de escena // es un nodo raiz del que cuelgan dos nodos // scene, que es el nodo que representa la escena // y auxdata, que es informacion "invisible" que // será utilizada por el editor, transparente al usuario root->setName("raiz"); scene_root->setName("escena"); node_auxdata->setName("auxdata"); node_selectdata->setName("selectdata"); // CREAMOS EL GRID osg::ref_ptr<osg::Group> ref_grid00 = OSGBasicShapes::MakeGrid(2000,5); osg::ref_ptr<osg::Group> ref_grid0 = OSGBasicShapes::MakeGrid(2000,10); osg::ref_ptr<osg::Group> ref_grid1 = OSGBasicShapes::MakeGrid(4000,20); osg::ref_ptr<osg::Group> ref_grid2 = OSGBasicShapes::MakeGrid(8000,40); osg::ref_ptr<osg::Group> ref_grid3 = OSGBasicShapes::MakeGrid(12000,80); osg::ref_ptr<osg::LOD> ref_LOD = new osg::LOD(); ref_LOD->addChild(ref_grid00.get()); ref_LOD->addChild(ref_grid0.get()); ref_LOD->addChild(ref_grid1.get()); ref_LOD->addChild(ref_grid2.get()); ref_LOD->addChild(ref_grid3.get()); ref_LOD->setRange(0, 0,500); ref_LOD->setRange(1, 500,1000); ref_LOD->setRange(2, 1000,2000); ref_LOD->setRange(3, 2000,4000); ref_LOD->setRange(4, 4000,12000); node_selectdata->addChild(ref_LOD.get()); node_auxdata->addChild(node_selectdata.get()); node_auxdata->addChild(m_KBMCallback->selection.GetAxis()->GetRootNode().get()); root->addChild(scene_root.get()); root->addChild(node_auxdata.get());

247

Page 249: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

int a; if (!m_bModelLoaded) { m_RenderSurface->makeCurrent(); CString csFileName = GetDocument()->GetFileName(); // cargamos el fichero if(!csFileName.IsEmpty()) { osg::ref_ptr<osg::Node> model = osgDB::readNodeFile((LPCSTR)csFileName); scene_root->addChild(model.get()); if (model.get()) { m_SceneView->setSceneData(root.get()); m_DatabasePager->registerPagedLODs( m_SceneView->getSceneData()); m_bModelLoaded = TRUE; OSGAVH->m_wndDebug.Print("%s cargado", csFileName); } else AfxMessageBox("Se produjo un error cargando el fichero", MB_OK, NULL); } else // fichero vacio : creamos datos por defecto { osg::ref_ptr<osgSim::DOFTransform> transf1 = new osgSim::DOFTransform(); osg::ref_ptr<osg::LightSource> focoluz = new osg::LightSource(); osg::ref_ptr<osg::Light> luz = new osg::Light(); focoluz->setLight(luz.get()); transf2->setPosition( osg::Vec3(0,-1.5,3.0) ); scene_root->addChild(transf1.get()); scene_root->addChild(transf2.get()); transf1->addChild(focoluz.get()); m_SceneView->setSceneData(root.get()); m_DatabasePager->registerPagedLODs(m_SceneView->getSceneData()); m_bModelLoaded = TRUE; } // record the timer tick at the start of rendering. m_StartTick = osg::Timer::instance()->tick(); m_uiFrameNum = 0; m_KBMCallback->home(); // leemos la informacion del grafo osg::ref_ptr<osg::Group> theRealRoot = (osg::Group*)m_SceneView->getCamera()->getChild(0); // Si no existe control asociado a la escena // lo creamos y lo marcamos como activado if(scenetree_ID == -1) { if(OSGAVH->m_wndSceneTree.CreateSceneTree()) { scenetree_ID = OSGAVH->GetUniqueSceneID(); OSGAVH->SetActiveSceneTree(scenetree_ID); OSGAVH->m_wndDebug.Print("SetActiveScene(%d)\n", scenetree_ID); } } // Y actualizamos la informacion del TreeCtrl OSGAVH->SetRootNode(theRealRoot.get(), scenetree_ID); OSGAVH->GetTreeCtrl()->ExpandSubtree( OSGAVH->GetTreeCtrl()->GetRootItem()); m_KBMCallback->selection.Init(scene_root.get(), node_selectdata.get(), m_SceneView.get(), OSGAVH->GetTreeCtrl(0));

248

Page 250: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

OSGAVH->GetTreeCtrl()->Redraw(); } global_state_set = new osg::StateSet(); scene_root->setStateSet(global_state_set.get()); m_SceneView->setClearColor(osg::Vec4(0.69,0.69,0.69,1.0)); m_SceneView->setLightingMode(osgUtil::SceneView::SKY_LIGHT); m_RenderSurface->useBorder(true); }

6.8 Problemas y “tips” de implementación.

6.8.1 La actualización de OpenSceneGraph 0.9 a 1.0. Este problema requirió indagar el código fuente propio de OpenSceneGraph. Para establecer el nodo raíz del grafo es escena hacemos uso de la clase osgUtil::SceneView. Esto se hace mediante la funcion setSceneData(root). Del mismo modo que establecemos el nodo raíz, podemos volver a consultarlo mediante la función. Puesto que nosotros sabemos cual es el nodo raíz, sabemos que no contiene ningún padre. En cierto punto del programa realizamos la comprobación de que el nodo no contenga ningún padre para identificarlo como nodo raíz. Hasta aquí todo funcionaba bien. En la versión 1.0 de la librería, hubo un cambio aparentemente transparente al desarrollador, y es que el al establecer el nodo raiz de la clase SceneView, lo que internamente hace es agregarlo como hijo a un objeto interno que contiene, tipo CameraView. Por tanto, aquí nuestro nodo raíz deja de cumplir la condición que antes buscabamos, y el programa comienza a cascar. La solución para acceder al nodo realmente raíz del grafo fue la llamada a GetCamera() de la clase SceneView.

6.8.2 La clase RefParticle. La clase ObjectType de nuestra aplicación está pensanda para representar un tipo de dato de OpenSceneGraph. Tras haber estudiado a fondo la librería, se tomó la decision de adoptar como tipo de dato base el tipo osg::Object (que deriva de la case osg::Referenced). La clase Referenced se utiliza para hacer uso punteros referenciados (ref_ptr). Estos objetos se declaran a modo de plantilla que permite referenciar cualquier tipo de objeto, y nos permiten tratar los datos a los que apuntan de manera similar a Java y su “recolector de basura”. Por suerte o por desgracia, nos hemos visto obligados a hacer uso de esta plantilla para referenciar cualquier objeto derivado de Referenced, puesto que de no hacerlo, obtendremos resultados imprevisibles en la aplicación. Bien, todo esto para explicar que la clase ObjectType, deberá contener una referencia a un Object: osg::ref_ptr<osg::Object> selected_obj;

Esta referencia identifica el dato que estamos mostrando actualmente en el panel de comandos.

249

Page 251: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

No existió ningun problema hasta que nos encontramos con el objeto osgParticle::Particle. Este objeto no deriva de ningun otro, y además, es un objeto importante a la hora de trabajar con sistemas de partículas. La solución que se decidió adoptar fue crear una nueva clase que encapsulase la anterior y derivase de Referenced: class RefParticle : public osg::Object { public: RefParticle(){}; RefParticle(osgParticle::Particle &part){Set(part);} RefParticle(osgParticle::Particle *part){Set(part);} inline void Set(osgParticle::Particle *part; inline void Set(const osgParticle::Particle &part; inline osgParticle::Particle *GetParticle(); virtual Object* cloneType() const; virtual Object* clone(const osg::CopyOp& cp) const; virtual const char* libraryName() const{return "osg";} virtual const char* className() const{return "Particle";} protected: virtual ~RefParticle(){} osgParticle::Particle particle; };

De esta manera podremos trabajar con este tipo de dato. Tan solo tendremos que realizar una llamada a la función GetParticle() para acceder a los datos en sí.

6.8.3 La función clone. Esta función la implementan los objetos OpenSceneGraph para generar nuevas instancias de objetos a partir de otros. Esta función se utiliza para crear el duplicado de ramas (la funcion copiar simplemente añade padres al nodo). Al duplicar un nodo se crea una copia con el mismo contenido que el nodo a copiar (haciendo uso de la funcion Clone(…)), y luego se añade el nuevo padre, y se continua clonando su descendencia. El problema era que los objetos se clonaban 2 veces. Es decir, al duplicar un objeto, obteniamos tres, en lugar de dos, y de esos tres, uno era independiente, y el otro era una copia (instancia) del primero. Lo que realmente sucedía es que se creaba un duplicado y una copia, puesto que al realizar la llamada a clone, se obtenía una instancia del objeto con la misma información, pero tambíen con la información de los padres y los hijos. La solución fue eliminar tanto los padres como los hijos del objeto recién clonado antes de seguir trabajando con él.

6.8.4 La función DoFrame(). La clase OSGWorldView realiza una llamada a la función OnStartRendering cuando se produce el evento de posicionar el ratón sobre el área de dibujado de la vista. Esta función entra en un bucle que realiza la llamada a DoFrame() que es la encargada de realizar el proceso de render de OpenSceneGraph. Cuando el ratón abandona el proceso de dibujado, el bucle termina y la escena deja de actualizarse.

250

Page 252: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Pero como a nosotros nos interesa que la escena continúe mostrándose indefinidamente, para poder apreciar los cambios que se produzcan en la escena al modificar los parámetros de cualquier nodo o cualquier tipo de dato, eliminamos la condición del bucle y lo dejamos de manera indefinida. Consecuencia : La aplicación se ralentiza y es imposible manipular los controles. Una posible solución era indicar a la View que repintase la escena al modificar cualquier parámetro del panel de comandos. El problema de esto es que una vez hemos salido de este bucle, es imposible ponerse en contacto directo con la clase View, puesto que es un hilo que gestiona las MFCs y no permite el acceso. Se intentó almacenar algun puntero a esta clase pero dabá error de ejecución o enviar algún tipo de mensaje pero no llegaban. Optamos como último recurso establecer un Timer cuando este bucle terminase. Del mismo modo, cuando volvamos a entrar en el bucle, lo primero que haremos será eliminar el Timer. De esta manera el usuario tiene siempre la impresión de que la escena está en continuo movimiento, sin afectar en absoluto al resto de la aplicación. LRESULT COSGWorldView::OnStartRendering(WPARAM,LPARAM) { KillTimer(scenetree_ID); while (m_bGotFocus) { DoFrame(); MSG msg; if (::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE )) { AfxGetApp()->PumpMessage(); } } if(scenetree_ID >= 0) { if(OSGAVH->IsSceneActive(scenetree_ID)) { SetTimer(scenetree_ID,17,NULL); } } return 0; }

6.8.5 Eliminar un nodo, deshacer y rehacer. Eliminar un nodo es algo aparentemente trivial, sin embargo, cuando contamos con un elemento de historia la cosa cambia. Recordemos que un nodo está representado en el editor mediante una estructura TreeNodeInfo, que contiene un puntero al nodo OpenSceneGraph, y punteros a las distintas instancias que contiene en el árbol en cada una de las TreeBars. Si eliminamos un nodo perdemos sus datos, por lo que se opta por conservar en la historia la rama eliminada almacenando una referencia al nodo eliminado (Es decir, que al eliminar un nodo simplemente lo desvinculamos del árbol). De esta manera, al rehacer la acción, tan solo tendremos que re-vincular el nodo de allá donde lo desvinculamos. El problema viene cuando usamos el árbol. Hemos dicho que un nodo está identificado por un TreeNodeInfo, que contiene referencias a los ítems del árbol. No es posible desvincular un ítem de un control de árbol. Hay que eliminarlo, por tanto, al rehacer la acción estaremos creando un nuevo ítem. Por tanto, el TreeNodeInfo deberá actualizar sus referencias al árbol.

251

Page 253: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Pero eso no es todo, si al deshacer la acción, continuamos deshaciendo acciones, podremos encontrarnos alguna acción que haga referencia al ítem del árbol que ya no existe. Una solución es utilizar la clase ActionNode para identificar a un elemento del grafo. Esta clase almacena el puntero al nodo del editor y el índice de la instancia que representa tal nodo. De esta manera, cuando eliminemos un nodo y lo volvamos a crear, aunque si referencia en el árbol sea distinta, el valor del ActionNode se mantendrá constante y nos permitirá identificar de manera única el elemento del árbol. class ActionNode { public: ActionNode(){}; ~ActionNode(){}; inline HTREEITEM Item(){return tni->GetTreeItem(index);} void Set(TreeNodeInfo *tn, int idx){ tni=tn;index=idx;} TreeNodeInfo *tni; int index; };

252

Page 254: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

PARTE VII APLICACIONES DE PRUEBA

253

Page 255: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

254

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Page 256: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE PARTE VII......................................................................................................

7.1 Introducción ...................................................................... ¡Error! Marcador no definido. 7.2 El editor OSGWorld.......................................................... ¡Error! Marcador no definido.

7.2.1 Especificación de los elementos del Interfaz gráfico. ¡Error! Marcador no definido. 7.2.1.1 La barras de menus.............................................. ¡Error! Marcador no definido. 7.2.1.2 La barra principal de herramientas. ..................... ¡Error! Marcador no definido. 7.2.1.3 La barra de nodos. ............................................... ¡Error! Marcador no definido. 7.2.1.4 Los paneles de comandos .................................... ¡Error! Marcador no definido. 7.2.1.5 La barra de árbol ................................................. ¡Error! Marcador no definido. 7.2.1.6 El Visor 3D.......................................................... ¡Error! Marcador no definido.

7.3 Ejemplos de escenas mediante el uso del editor................ ¡Error! Marcador no definido. 7.3.1 Utilización de Sistemas de partículas para crear fuego y humo. ¡Error! Marcador no definido. 7.3.2 Utilización de las Luces. ............................................ ¡Error! Marcador no definido. 7.3.3 Efecto Cartoon ........................................................... ¡Error! Marcador no definido. 7.3.4 Efecto BumpMapping ................................................ ¡Error! Marcador no definido. 7.3.5 Efecto de Specular Highlights.................................... ¡Error! Marcador no definido. 7.3.6 Instanciación multiple ................................................ ¡Error! Marcador no definido. 7.3.7 Efecto de niebla.......................................................... ¡Error! Marcador no definido. 7.3.8. Ejemplo de utilizacion de Shaders ............................ ¡Error! Marcador no definido.

255

Page 257: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

256

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Page 258: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

7.1 Introducción Hasta ahora se han desarrollado todos los elementos necesarios para el correcto funcionamiento de la aplicación. En este capítulo, se pretende demostrar la funcionalidad del trabajo realizado, asi como introducir tanto los elementos del interfaz, como los conceptos básicos para el manejo de la aplicación, y mostrar algunos ejemplos que se han podido realizar como prueba.

7.2 El editor OSGWorld.

7.2.1 Especificación de los elementos del Interfaz gráfico. La aplicación constará de un interfaz de ventanas que permitirán al usuario realizar todas las acciones posibles de interacción. Para ello se han intentado seguir ciertos criterios:

• Que sean elementos intuitivos, de forma que los usuarios con una rápida visualización del interfaz sean capaces de intuir gran parte de las acciones que se pueden realizar. De esta manera evitaremos que el usuario pierda demasiado tiempo en averiguar la manera de realizar ciertas operaciones que pueden ser algo complicadas.

• Se intentará que la aplicación le parezca lo más dinámica posible al usuario. Para ello se intentará disminuir en lo posible el número de diálogos que puedan confundirlo u obligarle a tomar demasiadas decisiones.

• Se requerirá que el usuario sea informado de las posibles acciones que puedan producir cambios indeseados en la escena antes de que estas se produzcan, o de eventos que informen de un resultado inesperado en la aplicación.

Figura 7.1. Aspecto del interfaz gráfico

El interfaz estará compuesto principalmente de los siguientes elementos:

257

Page 259: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

• Un marco de ventana con botones de minimizar, maximizar y cerrar. • Las barras de menus, dando acceso a distintas acciones sobre el editor. • Una barra principal de herramientas, con distintos accesos a las acciones más comunes

en la utilización del editor. • Una barra de nodos para la creación directa de nodos en el grafo de escena. • Una barra de árbol duplicable (se pueden mostrar tantas como se quiera) donde se

muestra el grafo actual de escena. • Una barra de depuracion, donde se muestra información de depuración del programa. • Los paneles de comandos, que consta de 5 paneles, cada uno con una funcionalidad

distinta. • El visor principal, donde se muestra la representacion final de la geometria del grafo es

escena.

7.2.1.1 La barras de menus

258

La barra de menús se encuentra directamente debajo de la barra de título de la ventana principal. El título de cada menú indica la finalidad de los comandos que contiene. Todos los menús siguen las convenciones estándar de Microsoft Windows. Al seleccionar un menú, se abre un menú desplegable que muestra varios comandos. Como alternativa al uso del ratón (u otro dispositivo señalador), cada nombre de menú incluye un carácter subrayado. Al presionar la tecla correspondiente junto con la tecla ALT, el menú se abre. Los comandos de los menús abiertos normalmente tienen también un carácter subrayado. Mientras el menú está abierto, puede presionar la tecla correspondiente al carácter para que el comando se ejecute.

Los puntos suspensivos (…) al final de un comando indican que abre un cuadro de diálogo. Una flecha hacia la derecha después de un comando indica la aparición de un submenú. Si un comando tiene un método abreviado del teclado, se muestra en el menú a la derecha del nombre del comando. Los comandos de menú que pueden conmutarse indican su estado mediante una marca de verificación.

El menu Archivo Nuevo: permite crear una nueva escena, con su grafo de escena correspondiente. Abrir: abre un fichero de grafo de escena. Insertar Fichero: Insertar un fichero en la escena actual. Cerrar: Cierrra la escena actual. Guardar: Guarda la escena actual. Guardar como: Permite guardar la escena actual con un nombre de fichero distinto al que ya tiene. Listado de archivos recientes: Muestra una lista de los últimos 5 archivos cargados en el editor.

Page 260: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Menu Edición

• Deshacer: El comando Deshacer invierte la última operación realizada con el objeto u objetos seleccionados.

• Rehacer: Invierte la última operación realizada por el comando Deshacer.

• Cortar: Corta los elementos seleccionados en el árbol al portapapeles.

• Copiar: Copia de manera instanciada los elementos seleccionados en el arbol al portapapeles.

• Copiar Duplicado: Copia de manera duplicada los elementos seleccionados en el arbol al portapapeles.

• Pegar: Pega el contenido del portapapeles en funcion de la operación de copiado. • Replicar selección: Crear una réplica exacta de la selección (instanciada), y desplazada

de la original.

Menu Ver

• Barra de herramientas: Muestra u oculta la barra de herramientas principal de la aplicación.

• Barra de estado: Muestra u oculta la barra de estado de la aplicación.

• Barra de Nodos: Muestra u oculta la barra de nodos de la aplicación.

• Barra de paneles: Muestra u oculta la barra paneles de la aplicación.

• Ventana de depuración: Muestra u oculta la ventana de depuración de la aplicación.

259

Page 261: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

260

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 7-2. Modo de visualización de rejilla.

Menu Escena

• Nuevo árbol: Crea una nueva barra conteniendo el árbol del grafo de escena.

• Seleccionar por nombre: Muestra un diálogo de selección de nodos por nombre.

• Centrar selección: Centra la selección de objetos actual del visor en pantalla.

• Seleccionar: Activa el modo Seleccionar. • Trasladar: Activa el modo Trasladar. • Rotar: Activa el modo Rotar. • Escalar: Activa el modo Escalar.

Figura 7.3. Diálogo de seleccionar por nombre.

Page 262: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

261

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Menu Representación

Este menu permite cambiar los distintos aspectos de representacion del visor.

• Modo o Wireframe: Activa el modo de visualizacion de

poligonos en alambre. o Relleno: Activa el modo de visualizacion de

poligonos en relleno. • Sombreado

o Plano: Activa el modo de sombreado plano. o Suavizado: Activa el modo de sombreado suavizado.

• Vistas o Superior: Muestra la vista superior de la escena. o Inferior: Muestra la vista inferior de la escena. o Izquierda: Muestra la vista lateral izquierda de la

escena. o Derecha: Muestra la vista lateral derecha de la

escena. o Frontal: Muestra la vista frontal de la escena. o Trasera: Muestra la vista trasera de la escena.

Menu Nodos

Permite crear distintos tipos de nodos predeterminados del editor en el grafo de escena como hijos del nodo actualmente seleccionado en el árbol. Estos comandos no funcionarán si no existe ningún elemento seleccionado en el árbol.

Page 263: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

262

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Menu Ventana:

• Nueva ventana: Crea una nueva escena. • Cascada: Organizar las ventanas para que se

superpongan. • Mosaico: Organizar las ventnas en mosaico • Organizar iconos: permite organizar los iconos en la

parte inferior de la ventana. • Submenu ventanas: permite seleccionar la escena

activa.

Menu Ayuda:

Temas de ayuda: Muestra los temas de ayuda.

Acerca de OSGWorld…: Muestra el dialogo de “Acerca de…”

7.2.1.2 La barra principal de herramientas.

La barra de herramientas principal predeterminada ofrece acceso rápido a herramientas y cuadros de diálogo para muchas de las tareas comunes del programa.

Nuevo: permite crear una nueva escena, con su grafo de escena correspondiente.

Abrir: abre un fichero de grafo de escena.

Guardar: Guarda la escena actual.

Cortar: Corta los elementos seleccionados en el árbol al portapapeles.

Copiar: Copia de manera instanciada los elementos seleccionados en el arbol al portapapeles.

Copiar duplicado: Copia de manera duplicada los elementos seleccionados en el arbol al portapapeles.

Pegar: Pega el contenido del portapapeles en funcion de la operación de copiado.

Deshacer: El comando Deshacer invierte la última operación realizada con el objeto u objetos seleccionados.

Rehacer: Invierte la última operación realizada por el comando Deshacer.

Page 264: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

263

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Nuevo árbol: Crea una nueva barra conteniendo el árbol del grafo de escena.

Seleccionar: Activa el modo Seleccionar.

Seleccionar por nombre: Muestra un diálogo de selección de nodos por nombre.

Trasladar: Activa el modo Trasladar.

Rotar: Activa el modo Rotar.

Escalar: Activa el modo Escalar.

Insertar fichero: Insertar un fichero en la escena actual.

Rotar Vista: Activa el modo de rotar la vista.

Desplazar Vista: Activa el modo de desplazar la vista.

Centrar selección: Centra la selección de objetos actual del visor en pantalla.

Figura 7-4. Ejemplo de la manipulación de objetos sobre un modelo de un tren.

7.2.1.3 La barra de nodos.

La barra de nodos permite crear directamente los principales tipos de nodos de raph en el grafo de escena. OpenSceneG

Nodo Projection: Inserta un nodo Projection como hijo del nodo actual.

Nodo LOD: Inserta un nodo LOD como hijo del nodo actual.

Page 265: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Nodo Geode: Inserta un nodo Geode como hijo del nodo actual.

Nodo LightSource: Inserta un nodo LightSource como hijo del nodo actual.

Nodo Switch: Inserta un nodo Switch como hijo del nodo actual.

Nodo MatrixTransform: Inserta un nodo MatrixTransform como hijo del nodo actual.

Nodo Cartoon: Inserta un nodo Cartoon como hijo del nodo actual.

Nodo Group: Inserta un nodo Group como hijo del nodo actual.

del nod

Nodo PositionAttitudeTransform: Inserta un nodo PositionAttitudeTransform como hijo o actual.

Nodo Sequence: Inserta un nodo Sequence como hijo del nodo actual.

Nodo Billboard: Inserta un nodo Billboard como hijo del nodo actual.

nodo

Nodo ParticleSystemUpdater: Inserta un nodo ParticleSystemUpdater como hijo del actual.

Nodo ModularEmitter: Inserta un nodo ModularEmitter como hijo del nodo actual.

Nodo FluidProgram: Inserta un nodo FluidProgram como hijo del nodo actual.

actual.

Nodo SpecularHighlights: Inserta un nodo SpecularHighlights como hijo del nodo

Nodo AutoTransform: Inserta un nodo AutoTransform como hijo del nodo actual.

Nodo BumpMapping: Inserta un nodo BumpMapping como hijo del nodo actual.

Nodo AutoTransform: Inserta un nodo AutoTransform como hijo del nodo actual.

7.2.1.4 Los paneles de comandos

Los paneles de comandos son cinco paneles de la interfaz de usuario con los que se accede a casi todas las funciones de construccion del grafo de escena. Sólo hay un panel visible a la vez; para ver otro, hay que seleccionar ficha en la parte superior del panel de comandos. El contenido de los paneles es deslizable verticalmente.

Los cinco paneles son:

264

Page 266: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 7-5. Panel de creacion de nodos.

Panel Crear: Permite seleccionar de una lista cualquiera de los nodos soportados por el editor para crear uno nuevo colgando del nodo actualmente seleccionado en el arbol.

de los nodos

Panel Nodos: Permite manipular los parámetros del grafo. Cada escalón en el árbol de

jerarquia del nodo se representa por un grupo distinto, pudiendo modificar los parámetros de manera independiente a medida que el nodo va aumentando su complejidad.

Figura 7-6. Panel de parámetros de nodos.

265

Page 267: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Panel StateSet: Permite crear o eliminar StateAttributes al StateSet de un nodo o un Drawable y modificar sus parámetros. En este panel los StateAttributes se van a diferenciar en StateAttributes normales y StateAttributes de textura.

Se pueden agregar nuevos atributos de los soportados por el editor pulsando sobre Agregar Atributo, asi como eliminarlos del StateSet.

Cada atributo tendrá asociados ciertos modos, cuyos valores podemos modificar, asi como agregar nuevos, todos ellos relacionados con OpenGl.

Figura 7-7. Panel de StateSet del nodo.

266

Page 268: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

los plugi

Figura 7-8. El panel de plugins.

Panel Plugins: Muestra un listado de ns cargados por el editor asi como

informacion adicional sobre cada uno de ellos.

Panel Utilidades: Este panel está disponible para los programadores de plugins.

7.2.1.5 La barra de árbol

Este arbol reprensenta el grafo de escena de OpenSceneGraph. Los nodos se pueden arrastrar unos sobre otros (siempre que su tipo de dato lo permita), podremos copiar y pegar, incluso entre distintas vistas.

La siguiente captura del editor muestra un ejemplo de dos vistas de árbol simultáneas de una misma escena.

Figura 7-9. La barra del árbol del grafo de escena.

267

Page 269: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

268

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Figura 7-10. Visualización de varias vistas simultáneas del árbol del grafo de escena.

El árbol además permite la pulsacion del botón derecho del ratón sobre los elementos mostrando un menú contextual de Opciones:

• Seleccionar: Selecciona en el visor los elementos del árbol seleccionados.

• Agregar a selección: Agrega a la selección en el visor los elementos del árbol seleccionados.

• Eliminar: Elimina los elementos del arbol seleccionados. • Ordenar:

o Nivel Actual: Ordena alfabéticamente el en el árbol.

o Nivel actual y debajo: Ordena alfabétiseleccionados en el árbol y sus descendientes.

• Seleccionar todos: Selecciona todos los elementos del árbol. • Seleccionar ninguno: Deselecciona todos los elementos del árbol. • Expandir subárbol: Expande el subárbol que contiene el elemento actual del árbol en

caso de estar contraido. • Contraer subárbol: Contrae el subárbol que contiene el elemento actual del árbol en

caso de estar expandido.

nivel actual de los nodos seleccionados

camente el nivel actual de los nodos

Page 270: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

269

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

7.2.1.6 El Visor 3D

El visor es el área de la aplicación donde se muestra en tiempo real la representación final de la geometria del grafo es escena.

Acciones sobre el editor

El visor permite cierta interacción directa con el usuario haciendo uso del teclado y el ratón de manera conjunta y con ayuda del eje manipulador.

Figura 7-11. Composición de una escena completa utilizando el editor.

Al seleccionar uno o más objetos en el visor, automáticamente nos aparecerá un eje auxiliar como el de la figura.

Este eje nos permitirá aplicar transformaciones a la selección actual sobre el eje o los ejes iluminados de manera simultánea (plano).

Las acciones que podemos realizar sobre el visor son las siguientes:

• Seleccionar objetos: Se pueden seleccionar objetos pulsando simplemente sobre ellos. • Agregar objetos a la selección actual: Se pueden

agregar objetos a la selección actual manteniendo pulsada la tecla CTRL y pulsando sobre el objeto que queremos seleccionar.

• Trasladar objetos: Con el modo de trasladar activo,

podemos desplazar el objeto libremente por el espacio 3D haciendo uso del eje manipulador, de esta manera podremos desplazar el objeto en cualquie de estos 3 ejes, y en cualquiera de sus combinaciones que formen un plano.

• Rotar Objetos: Con el modo de rotar activo

Page 271: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

270

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

podemos rotar objetos alrededor de si mismos sobre cualquiera de los 3 ejes, o sobre dos ejes simultáneos.

• Escalar Objetos: Con el modo escalar activo o Escalado con ayuda del eje manipulador: Podemos rotar objetos alrededor de

sí sobre cualquiera de los 3 ejes, o sobre dos ejes simultáneos. o Escalado uniforme: Si mantenemos pulsada la tecla mayúsculas podremos

escalar el objeto de manera uniforme independientemente de los ejes seleccionados en el eje manipulador.

• Clonar objetos: Se pueden clonar todos los objetos de una selección manteniendo pulsada la tecla mayúsculas a la vez que hacemos una traslación. El resultado se puede apreciar en la Figura 7.8.

• Mostrar los parámetros de un objeto: Se puede forzar la selección del objeto actual del árbol del grafo para mostrar sus parámetros en el panel de Nodos haciendo doble click sobre el objeto que queramos en el visor.

Figura 7-12. Clonado rápido de objetos usando teclado y ratón.

7.3 Ejemplos de escenas mediante el uso del editor.

En este apartado vamos a mostrar algunos ejemplos de escenas creadas a partir de la utilización de la aplicación.

Page 272: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

7.3.1 Utilización de Sistemas de partículas para crear fuego y humo

7.3.2 Utilización de las Luces.

271

Page 273: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

7.3.3 Efecto Cartoon

7.3.4 Efecto BumpMapping

272

Page 274: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

7.3.5 Efecto de Specular Highlights

7.3.6 Instanciación multiple

273

Page 275: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

7.3.7 Efecto de niebla.

7.3.8. Ejemplo de utilizacion de Shaders

274

Page 276: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

PARTE VIII CONCLUSIONES

275

Page 277: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

276

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Page 278: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

INDICE

PARTE VIII ....................................................................................................

8.1 Conclusiones ..................................................................... ¡Error! Marcador no definido. 8.2 Trabajos futuros................................................................. ¡Error! Marcador no definido. 8.3 Comparativa con OSGEdit................................................ ¡Error! Marcador no definido.

277

Page 279: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

278

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Con todo esto, podemos concluir haber cumplido con los objetivos planteados al inicio del proyecto:

• Hemos construido un interfaz amigable, dinámico y sencillo de manejar. Además, la barra de paneles de comandos guarda un gran parecido con la barra del panel de comandos de 3D Studio Max, por lo que los usuarios de este programa estarán muy familiarizados con algunos aspectos de la aplicación.

• Hemos conseguido mostrar el grafo en una estructura de árbol, permitiendo copiar, cortar, duplicar, y pegar nodos, unos dentro de otros o como hermanos, a golpe de ratón (arrastrando elementos) o de teclado. Además, podemos estableces tantas vistas simultáneas del árbol como queramos, lo cual facilitará en gran medida la manipulación de árboles que representen grafos de escena muy pesados.

• Se ha conseguido parametrizar las estructuras de datos de OpenSceneGraph en el panel de comandos antes mencionado. Esto permite al usuario realizar ajustes de parámetros de manera sencilla.

• Podemos manipular la escena directamente, aplicando transformaciones a los objetos, copiándolos o duplicándolos e incluso eliminándolos directamente de la pantalla. Además, hemos conseguido hacer uso del eje manipulador, al igual que el 3D Studio Max, y conseguir que las traslaciones se hagan al punto donde el ratón se desplaza, de este modo, hemos conseguido que el usuario tenga la impresión de estar realmente “moviendo” objetos por la pantalla.

• Hemos conseguido que la mayoría de acciones puedan ser invertibles, incluso en aquellos casos en los que la acción requiera eliminar objetos. De este modo, estamos ahorrando al usuario el tiempo que podría dedicar a corregir muchos errores que se cometen en el manejo de aplicaciones, y que podría costarnos mucho mas tiempo del que pensamos.

• Hemos dotado a la aplicación de un sistema de plugins, proporcionando un conjunto de librerías o Kit de Desarrollo, que permitirán al desarrollador implementar nuevas funcionalidades en el programa de una manera sencilla, y con un mínimo esfuerzo.

Como conclusiones personales del alumno, podemos destacar que se ha conseguido familiarizar con el entorno de programación Visual .NET, se ha aprendido a fondo el funcionamiento de la librería OpenSceneGraph, y se ha profundizado en la utilización de estructuras de datos en C++. Del mismo modo, se han adquirido nuevos conocimientos sobre la programación en Windows, y más concretamente sobre las MFC, la generación de controles, y las peculiaridades propias de esta librería. Por último, destacar los grandes conocimientos adquiridos en cuanto al desarrollo de aplicaciones altamente modulares, y ampliables gracias a un sistema de carga y desarrollo de plugins.

8.1 Conclusiones

Page 280: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

8.2 Trabajos futuros La lista de nuevas funcionalidades que se podría añadir a la aplicación podría ser interminable, es por ello que se establecieron unos objetivos que se pudieran cumplir en el plazo establecido para realizar el proyecto. No obstante, a continuación pasaremos a enumerar aquellos de los trabajos futuros que hemos considerado como más interesantes.

• Puesto que uno de los principales objetivos del sistema de plugins fueron los trabajos futuros se desarrolló el sistema de plugins. Por tanto, podremos decir que cualquier desarrollo de un plugin puede ser un trabajo futuro. Este podría abarcar desde el desarrollo de un sistema de motion capture para la aplicación, hasta la implementación de nuevos tipos de nodo que todavía no estén implementados en la aplicación, o nuevos efectos que vayan apareciendo, ya que OpenSceneGraph es una librería relativamente joven y en continuo desarrollo.

• Permitir el desarrollo de plugins de exportación e importación de ficheros. Hasta ahora la aplicación permite plugins de tipos de datos, y plugins genéricos (que se muestran en el panel de comandos, y permiten manipular cualquier información de la escena), pero no existe manera de importar o exportar tipos de datos desconocidos, para ello se debería de implementar un tipo de plugin específico para esta tarea.

• Añadir nuevos manipuladores. Estos objetos auxiliares se conocen en 3D Studio Max como Guizmos, y existe uno distinto para cada tipo de transformación. En nuestro caso hemos utilizado el eje manipulador (Guizmo de traslación en 3d max) para cualquier transformación.

• Agregar la posibilidad de trasladar luces como su fueran objetos. Esta opción de momento no está disponible y las posiciones de las luces deben de ser establecidas mediante el panel de comandos.

• Permitir modificar las propiedades de animación. Existen estructuras de datos en OpenSceneGraph que gestionan la animación, y sería interesante que fueran manipulables desde el editor.

• Permitir crear agrupaciones de elementos. Una características de cualquier software 3D, permite agrupar elementos (independientemente de su disposición en el grafo), de manera que al estar agrupados las transformaciones afectan por igual a cada uno de los miembros.

• Añadir un sistema de representación de 4 visores simultáneos. Debido al sistema de representación que utiliza OpenSceneGraph, nos resultaba algo complicado añadir esta funcionalidad, por lo que el tiempo de implementación estimado hubiera sido sobrepasado.

• Adición de interfaces multimodal avanzados para agilizar y facilitar al usuario el montaje de las escenas. Esta característica podría consistir en añadir un sistema de captura al programa para aplicar transformaciones a los objetos, sustituyendo al ratón, de esta manera se podrían por ejemplo desplazar objetos en es espacio 3D de una manera más intuitiva que con un ratón.

8.3 Comparativa con OSGEdit. Para terminar el apartado de conclusiones, vamos a pasar a realizar una comparativa con el software más parecido que existe actualmente para la edición de escenas en OpenSceneGraph. En esta comparativa enumeraremos las distintas funcionalidades de cada aplicación en una tabla, indicando su disponibilidad en color verde, y su ausencia en color rojo.

279

Page 281: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Funcionalidad OSGEdit OSGWorld Representación en árbol del grafo de escena. Copiar y pegar nodos sobre el árbol Duplicar nodos Arrastrar nodos sobre el árbol Crear cualquier tipo de nodo soportado en la aplicación. Visualización múltiple del árbol Mapeado de parámetros de tipos de datos Adición de StateAttributes Transformación inteligente de Geodes Transformación de Geodes mediante eje manipulador Soporte de Vertex y Program Shaders Sistema deshacer/rehacer Unir el grafo con un fichero Posibilidad de desarrollo de plugins Ventanas dockables Posibilidad de abrir varias escenas simultáneas

280

Page 282: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

PARTE IX BIBLIOGRAFIA

281

Page 283: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

282

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Page 284: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

Bibliografía. Libros:

[1] Marcos Fernández, apuntes de las asignaturas Informática Gráfica y Ampliación de Informática Gráfica. Año 2004.

[2] Deitel & Deitel. Cómo programar C++. Prentice Hall.

[3] Jeffrey Richter. Programación Avanzada en Windows. Microsoft Press.

[4] Richard C. Leinecket y Tom archer. La Biblia de Microsoft Visual C++ 6.0. Anaya multimedia. Año 1999. [5] Herbert Schildt. Programación con MFC 6.0. Osborne McGraw-Hill. Año 1999. [6] James D. Foley, Andries van Dam, Steven K. Feiner, John F. Hughes. Computer Graphics, Principles And Practice. Second Edition. IBM Editorial Board. [7] Alan Watt, Mark Watt. Advanced Animation And Rendering Techniques, Theory And Practice. Addison-Wesley Publishing Company. [8] Jackie Neider, Tom Davis, Mason Wood. OpenGL Programming Guide, The official guide to learning OpenGL (Release 1). Addison-Wesley Publishing Company. [9] James D. Foley, Andries van Dam, Steven K. Feiner, John F. Hughes, Richard L. Phillips, Introducción a la graficación por computador. Addison-Wesley Ibero-Americana. [10] Bernie Reahl. El creador de mundos virtuales. Anaya multimedia. Año 1994. [11] R. Stuart Ferguson. Practical algorithms for 3d computer graphics. Paperback. [12] Andrew S. Glassner. An Introducing to Ray Tracing. Academic Press. [13] Martin Brownlow. Game programming golden rules. Paperback. [14] Richard S. Wright Jr. Michael Sweet. Programación en OpenGL. Anaya multimedia. Año 1996. [15] Christopher Lampton. Vuelos de fantasía. Anaya Multimedia. Año 1993. [16] T. Akenine-Möller and E Haines. Real-Time Rendering, 2nd edition, Junio 2002. [17] Wolfgang Engel. Programming Vertex & Pixel Shaders. Paperback. [18] Sebastian St-Laurent. Shaders for Game Programmers and Artists. Paperback. Online: [19] Microsoft. Microsoft Developer Network (MSDN) Library Visual Studio. Versión Junio 2006.

283

Page 285: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

284

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

[20] Autodesk. U3D Studio MAX Software Development Kit Help (SDK)U. Versión 5.1. [21] Miguel Lozano, Carlos calderón. UEntornos virtuales 3D clásicos e inteligentes: hacia un Unuevo marco de simulación para aplicaciones gráficas 3D interactivasU. Departmento de Informática, Universidad de Valencia. [22] George Eckel, Ken Jones, Tammy Domeier. UOpenGLPerformer™ Getting Started GuideU. Version 3.2. Silicon Graphics, Inc. Año 2004. [23] George Eckel,Ken Jones. UOpenGLPerformer™ Programmer’s Guide U. Version 3.2. Silicon Graphics, Inc. Año 2004. Páginas y referencias web: [24] Hhttp://www.openscenegraph.org/H Página oficial de OpenSceneGraph. [25] Hhttp://osgedit.sourceforge.net H/ Página oficial del OSGEdit. [26] Hhttp://www.opengl.comH/ Página oficial de la librería OpenGL. [27] Hhttp://es.wikipedia.orgH/ Wikipedia, la enciclopedia libre. [28] Hhttp://www.ogre3d.org/H Página oficial del motor Ogre 3D. [29] Hhttp://www.sgi.com/software/performer/H Página de SGI OpenGL Performer. [30] Hhttp://www.multigen-paradigm.com/ H Página oficial de multigen. [31] Hhttp://www.codepixel.comH/ Pagina web orientada a la programación gráfica. [32] Hhttp://openrm.sf.net H/ Página oficial de la libreria gráfica OpenRM. [33] Hhttp://www.opensg.org H/ Página oficial de la libreria gráfica OpenSG. [34] Hhttp://plib.sf.nefH/ Página web de la libreria Plib. [35] Hhttp://www.r3vis.com/RMSSceneGraphH/ Página oficial de la libreria RMSceneGraph. [36] Hhttp://www.sgi.com/software/optimizerH/ Página de la herramienta SGI OpenGL Optimizer. [37] Hhttp://sgl.sf.netH/ Página oficial de la librería SGL. [38] Hhttp://java.sun.com/products/java-media/3DH/ Página de la API de Java 3D. [39] Hhttp://www.gamasutra.comH/ Pagina web sobre programación gráfica y videojuegos. [40] Hhttp://www.codeproject.comH/ Gran cantidad de tutoriales y recursos MFC. [41] Hhttp://www.codeguru.comH/ Página con cantidad de tutoriales y recursos de programación. [42] Hhttp://www.nps.navy.mil/cs/sullivan/osgtutorials/ H Tutoriales de OpenSceneGraph.

Page 286: Desarrollo de un sistema de edición de escenas basado en ...mural.uv.es/mimaro/proyecto_final.pdf · MEMORIA DEL PROYECTO DE FIN DE CARRERA Desarrollo de un sistema de edición de

285

E.T.S.E. Universidad de Valencia Desarrollo de un sistema de edidión de escenas basado en una librería gráfica de alto nivel.

[43] Hhttp://www.gamedev.net H/ Página orientada al desarrollo y programación de videojuegos. [44] Hhttp://developer.kde.org/documentation/tutorials/developing-a-plugin-structure/index_es.html H Artículo sobre la arquitectura de plugins. [45] Hhttp://es.wikipedia.org/wiki/Gr%C3%A1ficos_3D_por_computadoraH/ Artículo sobre la historia de las 3D. [46] Hhttp://www.realityprime.com/scenegraph.phpH/ Artículo sobre los grafos de escena. Avi Bar-Zeev. Scenegraphs: Past, present and future. [47] Hhttp://www.3dscenegraph.comH/ Portal sobre los distintos grafos de escena disponibles actualmente, y gran cantidad de artículos relacionados. [48] Hhttp://www.codeproject.com/dll/RegDLL.aspH Ejemplo de creacion de una DLL en Visual Studio. [49] Hhttp://www.codeproject.com/dll/TargetApp.aspH Desarrollo de una DLL a modo de plugin. [50] Hhttp://www.clockworkcoders.com/oglsl/index.htmlH Artículo sobre shaders. [51] Hhttp://www.lighthouse3d.com/opengl/glsl/H Tutorial básico sobre GLSL. [52] Hhttp://www.geocities.com/eric6930/Win32_tips.html H Tips sobre programacion de controles Win32. [53] Hhttp://www.gamedev.net/community/forums/ H Foros de la comunidad gamedev.