You are on page 1of 286

MEMORIA DEL PROYECTO DE FIN DE CARRERA

Desarrollo de un sistema de edicin de escenas basado en una librera grfica de alto nivel: OpenSceneGraph.
INGENIERA INFORMATICA ESCUELA TECNICA SUPERIOR DE INGENIERA

Septiembre 2006

Alumno: Miguel Martnez Rodilla Tutor: Marcos Fernndez Marn

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

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


1.1 Introduccin. ..................................................................................................................... 11 1.2 Objetivos. .......................................................................................................................... 12

PARTE II ................................................................................................... 13
2.1 Informtica grfica en tiempo real. ................................................................................... 17 2.1.1 Introduccin. .................................................................................................................. 17 2.1.2 Orientacin hacia el Hardware Grfico 3D. Libreras grficas de bajo nivel. ............... 18 2.1.2.1 OpenGl. ................................................................................................................... 19 2.1.2.2 Representacin 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 Libreras grficas de Alto Nivel. Grafos de escena........................................................ 24 2.1.3.1 Grafos de Escena. Generalidades. ........................................................................... 24 2.1.3.2 Tipos bsicos de Nodos........................................................................................... 25 2.1.3.3 Proceso de seleccin 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 Revisin 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 libreras graficas de alto nivel........................................................................ 38 2.1.5 Motores de Videojuegos................................................................................................. 38 2.1.5.1 Motores de Visualizacin........................................................................................ 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 dinmico ......................................................................................... 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 parmetros........................................................................................... 79 2.4 Conclusiones. .................................................................................................................... 79

PARTE III.................................................................................................. 81
3.1 Metodologa ...................................................................................................................... 84 3.2 Materiales .......................................................................................................................... 84 3.3 Planificacin temporal....................................................................................................... 84 3.3.1 Diagrama de Gant....................................................................................................... 85

PARTE IV .................................................................................................. 89
4.1 Introduccin ...................................................................................................................... 94 4.2 Anlisis de Requisitos. ...................................................................................................... 95 4.2.1 Requisitos generales del sistema. ............................................................................... 95 4.2.2 Requisitos de la representacin del grafo de escena .................................................. 95 4.2.3 Requisitos de la representacin de tipos de datos en el interfaz................................ 96 4.2.4 Requisitos de la manipulacin sobre la representacin 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 Anlisis.............................................................................................................................. 98 4.3.1 Anlisis de la representacin de los datos del grafo en el interfaz ............................. 98 4.3.1.1 Grupos de parmetros.......................................................................................... 99 4.3.1.2 Descriptores de parmetros ................................................................................. 99 4.3.1.3 El gestor de parmetros ....................................................................................... 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 Anlisis de la representacin 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 mltiples vistas de rbol .................................................... 106 4.3.2.3 Acciones sobre el rbol ..................................................................................... 107 4.3.2.4 Mostrar la informacin de un nodo del grafo.................................................... 108 4.3.3 Anlisis de la interaccin con el visor del editor...................................................... 108 4.3.3.1 El gestor de seleccin ........................................................................................ 109 4.3.3.2 El eje manipulador ............................................................................................ 109 4.3.3.3 Creacin automtica de Matrices de Transformacin ....................................... 110 4.3.3.4 Traslacin de objetos usando el eje manipulador.............................................. 111 4.3.3.5 Representacin de objetos independientes a la escena del editor...................... 112 4.3.4 Anlisis del sistema deshacer / rehacer. ................................................................... 113

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4.2.7 Anlisis del sistema de plugins. ............................................................................... 114 4.2.8 Anlisis del Manejador de Vista Activa................................................................... 115 4.4 Casos de uso .................................................................................................................... 117 4.4.1 Funciones del sistema............................................................................................... 117 4.4.2 Descripcin de alto nivel de los Casos de Uso......................................................... 119 Iniciar la aplicacin. ...................................................................................................... 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 parmetros de un TabOutput...................................................... 120 Cargar Plugins. .............................................................................................................. 121 Cerrar aplicacin. .......................................................................................................... 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 segn el nombre de su NodeType. ........................................................ 126 Crear una nueva instancia de un nodo segn 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 informacin de un nodo ............................................................................... 128 Crear los dilogos de un TabOutput.............................................................................. 129 Crear un dilogo a partir de un grupo de parmetros .................................................... 129 Generar el contenido de un TabOutput ......................................................................... 130 Vaciar el contenido de un TabOutput............................................................................ 130 Notificar fin de seleccin de un ObjectType................................................................. 130 Mostrar los datos de un TabOutput ............................................................................... 131 Seleccionar nodo en el visor.......................................................................................... 131 Agregar nodo a la seleccin del visor ........................................................................... 131 Crear Matriz de Transformacin como padre de un nodo............................................. 132 Actualizar la seleccin. ................................................................................................. 132 Actualizar el eje manipulador. ...................................................................................... 132 Copiar nodo................................................................................................................... 133 Replicar seleccin. ........................................................................................................ 133 Mover nodo. .................................................................................................................. 133 Duplicar Nodo. .............................................................................................................. 134 Duplicar Seleccion. ....................................................................................................... 134 Eliminar nodo................................................................................................................ 134 Activar modo seleccin................................................................................................. 135 Activar modo traslacin de objetos............................................................................... 135 Activar modo escalado de objetos................................................................................. 135 Activar modo rotacin de objetos. ................................................................................ 136

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Activar modo rotar vista................................................................................................ 136 Activar modo trasladar vista. ........................................................................................ 136 Escalar seleccin. .......................................................................................................... 136 Comenzar escalado de seleccin. .................................................................................. 137 Realizar escalado de seleccin. ..................................................................................... 137 Finalizar escalado de seleccin. .................................................................................... 138 Rotar seleccin. ............................................................................................................. 138 Comenzar rotacin de seleccin.................................................................................... 138 Realizar rotacin de seleccin....................................................................................... 139 Finalizar rotacin de seleccin...................................................................................... 139 Trasladar seleccin........................................................................................................ 139 Comenzar traslacin de seleccin. ................................................................................ 140 Realizar traslacin de seleccin. ................................................................................... 140 Finalizar traslacin de seleccin. .................................................................................. 140 Centrar la vista en la seleccin...................................................................................... 141 Modificar el zoom de la vista. ....................................................................................... 141 Aadir un StateAttribute a un StateSet.......................................................................... 141 Eliminar un StateAttibute de un StateSet. ..................................................................... 142 Aadir un Modo a un StateSet. ..................................................................................... 142 Eliminar un Modo de un StateSet. ................................................................................ 142 Modificar un Modo de un StateSet. .............................................................................. 142 Modificar el parmetro de un control del panel de comandos. ..................................... 143 Establecer el valor de un parmetro. ............................................................................. 143 Establecer el valor de un parmetro. ............................................................................. 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 notacin UML. .............................................................. 147

PARTE V.................................................................................................. 163


5.1. Introduccin. .................................................................................................................. 167 5.2 Diagrama de componentes del sistema. .......................................................................... 167 5.3 Diseo de las funciones del sistema mediante diagramas de secuencia y colaboracin. 168 5.3.1 Inicio. ....................................................................................................................... 168 5.3.2 Finalizar aplicacin .................................................................................................. 170 5.3.3 Nueva Escena ........................................................................................................... 171 5.3.4 Insertar fichero. ........................................................................................................ 172 5.3.5 Modificar Parmetro ................................................................................................ 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 Introduccin .................................................................................................................... 205 6.2 Parametrizacin de datos................................................................................................. 206 6.2.1 El descriptor de parmetros (OSGParamGroupDesc). ............................................ 206 6.2.2 Los grupos de parmetros (OSGParamGroup) ........................................................ 207 6.2.3 El gestor de parmetros (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 Implementacin del rbol del grafo de escena. ............................................................... 219 6.3.1 La clase TreeNodeInfo ............................................................................................ 219 6.3.2 La clase CEditTreeCtrl............................................................................................. 220

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 Interaccin 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 implementacin. .......................................................................... 249 6.8.1 La actualizacin de OpenSceneGraph 0.9 a 1.0. ...................................................... 249 6.8.2 La clase RefParticle.................................................................................................. 249 6.8.3 La funcin clone....................................................................................................... 250 6.8.4 La funcin DoFrame().............................................................................................. 250 6.8.5 Eliminar un nodo, deshacer y rehacer. ..................................................................... 251

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


7.1 Introduccin .................................................................................................................... 257 7.2 El editor OSGWorld........................................................................................................ 257 7.2.1 Especificacin de los elementos del Interfaz grfico. .............................................. 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 Utilizacin de Sistemas de partculas para crear fuego y humo............................... 271 7.3.2 Utilizacin 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 Instanciacin 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


Bibliografa. .......................................................................................................................... 283

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE I

INTRODUCCIN

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

INDICE

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


1.1 Introduccin. ..................................................................... Error! Marcador no definido. 1.2 Objetivos. .......................................................................... Error! Marcador no definido.

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

10

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

1.1 Introduccin.
En el mundo de los grficos por ordenador, existen dos lneas de investigacin que se encuentran en estados muy avanzados, pero han seguido caminos divergentes: de un lado la Animacin 3D que ha centrado toda su atencin en la calidad visual de las imgenes, y de otro, la Realidad Virtual o Informtica Grfica en Tiempo Real, que ha intentando conseguir la mayor calidad posible, pero dando prioridad a la rapidez en la generacin de imgenes. La realidad virtual puede ser de dos tipos: inmersiva y no inmersiva. Los mtodos inmersivos de realidad virtual con frecuencia se ligan a un ambiente tridimensional creado por un ordenador, el cual se manipula a travs de cascos, guantes u otros dispositivos que capturan la posicin y rotacin 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 travs de una ventana de escritorio. Este enfoque no inmersivo tiene varias ventajas sobre el enfoque inmersivo como son el bajo coste y fcil y rpida aceptacin 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 ratn que por medio de cascos pesados o guantes. Pero tanto la Animacin 3D como la Informtica Grfica en Tiempo Real siempre han estado complementadas por herramientas especficas o interfaces de edicin. Estas herramientas grficas 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 geometra manualmente. Estas herramientas tambin han ido evolucionando al mismo tiempo que lo han ido haciendo los motores grficos, permitiendo en algunas de ellas una visualizacin en tiempo real del resultado final de la imagen. Adems, gracias a la modularidad de estas aplicaciones, cada vez son ms las aplicaciones que admiten extensiones, desarrollables por terceras personas, que se pueden ir aadiendo a las mismas para mejorar su capacidad y flexibilidad. Gran parte de los motores grficos de simulacin 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 agrupacin, introduciendo algn tipo de poda o aplicando alguna transformacin afn. Los nodos hijos de estas estructuras suelen ser los objetos geomtricos a representar. Aunque hasta hoy los grafos de escena han estado principalmente orientados a la representacin de entornos estticos, u objetos relativamente simples, cada vez ms se pueden encontrar grafos de escena que permiten realizar animaciones ms complejas y dinmicas, incluso que soportan sistemas de partculas. La motivacin de este proyecto radica en proporcionar una herramienta de edicin para uno de los ltimos grafos de escena disponibles en cdigo abierto: OpenSceneGraph, dada la carencia de potentes herramientas de edicin para este grafo de escena. Esta librera est siendo ampliamente utilizada por el Instituto de Robtica de la Universidad de Valencia, debido a la antigedad de OpenGL Performer (el motor grfico de SGI basado tambin en grafo de escena). Para ello, ser necesario analizar las carencias de las actuales herramientas existentes, as como las necesidades del Instituto de Robtica para as proponer soluciones que permitan llegar a construir una aplicacin a la altura de sus exigencias.

11

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

1.2 Objetivos.
En este proyecto se pretende construir una aplicacin que permita construir y manipular un grafo de escena de la librera OpenSceneGraph, proporcionando un interfaz sencillo e intuitivo, pero a la vez potente, ampliable, y que no requiera apenas conocimientos de programacin. Concretamente vamos a enumerar los siguientes objetivos: Crear un interfaz sencillo, flexible y dinmico pero a la vez potente, proporcionando al usuario acciones que faciliten algunas de las tareas ms 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 Robtica, y ser una de las aplicaciones que complementen con la aplicacin desarrollada en este proyecto. Dotar a la aplicacin de un mecanismo de visualizacin y manipulacin de la estructura del grafo de escena. Del mismo modo, realizar una parametrizacin de los datos del grafo de escena en el interfaz grfico para permitir la manipulacin de los datos, de la manera ms intuitiva posible y que aporte la mayor informacin al usuario. Disponer de un sistema de historia, para poder deshacer y rehacer cualquier tipo de accin sobre el grafo. Visualizar el estado del grafo de escena en tiempo real, permitiendo una interaccin 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 podrn desarrollar nuevas funcionalidades en la aplicacin, sin necesidad de modificar su ncleo. Por tanto se deber proporcionar un conjunto de clases y libreras disponibles para el desarrollador de plugins.

Todos estos objetivos se debern cumplir siempre siguiendo las tcnicas de desarrollo aprendidas en las asignaturas de Ingeniera del Software, pudiendo obtener, de este modo, unas aplicaciones de buena calidad.

12

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE II

ESTADO ACTUAL DE LAS TECNOLOGIAS IMPLICADAS

13

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

14

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

INDICE
PARTE II .......................................................................................................
2.1 Informtica grfica en tiempo real. ................................... Error! Marcador no definido. 2.1.1 Introduccin. .................................................................. Error! Marcador no definido. 2.1.2 Orientacin hacia el Hardware Grfico 3D. Libreras grficas de bajo nivel. .......Error! Marcador no definido. 2.1.2.1 OpenGl. ................................................................... Error! Marcador no definido. 2.1.2.2 Representacin 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 Libreras grficas 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 bsicos de Nodos........................................... Error! Marcador no definido. 2.1.3.3 Proceso de seleccin 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 Revisin 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 libreras graficas de alto nivel........................ Error! Marcador no definido. 2.1.5 Motores de Videojuegos................................................. Error! Marcador no definido. 2.1.5.1 Motores de Visualizacin........................................ 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 dinmico ......................................... 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 parmetros........................................... Error! Marcador no definido. 2.4 Conclusiones. .................................................................... Error! Marcador no definido.

16

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.1 Informtica grfica en tiempo real. 2.1.1 Introduccin.


La representacin una escena tridimensional en un ordenador requiere que toda la informacin referente a la descripcin de los objetos, la iluminacin, la atmsfera y los puntos de vista sean transformados en una imagen 2D que presente una calidad suficiente como para proporcionar una sensacin realista. La informtica grfica actual dispone de mltiples mtodos para proporcionar definiciones matemticas de los objetos tridimensionales, as, se pueden emplear definiciones de geometra slida (CSG), en superficies paramtricas, campos potenciales, fractales, etc. De igual modo, existen mltiples mtodos para definir las propiedades fsicas de los objetos que constituyen la escena tridimensional, y de iluminar y transformar estas escenas en imgenes planas. En el caso de que se est buscando la obtencin de imgenes estticas, o bien de secuencias grabadas de este tipo de imgenes, es posible recurrir a cualquiera de estos mtodos. 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 clculo que sea necesario), existen otro tipo de aplicaciones, en las que es necesario que la generacin de imgenes se produzca con una rapidez tal que posibilite la interactividad (por encima de 8 imgenes/segundo), o la percepcin continua del movimiento (tasas de generacin de imgenes en torno a los 50 imgenes/segundo). Con este objetivo, se han diseado tarjetas grficas especialmente orientadas a descargar a la CPU de las tareas relacionadas con el renderizado de las imgenes tridimensionales. No todos los mtodos software empleados en la actualidad para conseguir imgenes 3D, pueden ser fcilmente implementadas dentro de una estructura hardware. Los mtodos empleados para generar estas imgenes en tiempo real estn fuertemente condicionados por las caractersticas del hardware grfico existente, existiendo una lnea de investigacin paralela a la Informtica Grfica Tradicional, cuyo objetivo es tambin conseguir la mxima calidad grfica posible, pero siempre enmarcada por las limitaciones de este hardware grfico. Esta lnea de investigacin paralela suele recibir el nombre genrico de Informtica Grfica en Tiempo Real. Para poder realizar representaciones visuales de una escena tridimensional en tiempo real, se ha de disponer de un formato de datos, segn el cual, los objetos y sus caractersticas grficas estn definidos a partir primitivas optimizadas para trabajar con este tipo de hardware grfico. El hardware grfico dispone de uno o varios procesadores encargados de procesar dichas primitivas (transformar la posicin espacial de los objetos y realizar su proyeccin, clculos de iluminacin, ocultacin entre objetos, clculos 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 librera grfica de bajo nivel, la cual, adems de permitir realizar una gestin ptima del hardware grfico, acta como substrato inicial para la implementacin de otras capas software de mayor complejidad. Como se ver en apartados posteriores, existen varias libreras de este estilo, siendo el estndar actual ms aceptado la librera 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 nmero de polgonos que se ven implicados en la generacin de cada imagen. El coste de obtencin de cada imagen, depende de varios factores relacionados directamente con el nmero de vrtices que forman las primitivas geomtricas de la escena, y el rea (en pxeles) que ocupan sobre pantalla. Existen varios mtodos para mantener este coste bajo un cierto lmite, pero todos tienen como planteamiento bsico la seleccin de los objetos

17

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

grficos relevantes por medio de una estructura jerrquica 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 estn formados usualmente por primitivas de dibujado. El empleo de grafos de escena tambin facilita enormemente la organizacin lgica de la escena, y el control por parte del usuario. En los siguientes apartados se muestra un estado del arte sobre el hardware grfico, descrito a travs de las funcionalidades de las libreras grficas de bajo nivel empleadas para su manejo, se muestran las funcionalidades de las libreras grficas de alto nivel y sus grafos de escena, y por ltimo se realiza una revisin de los grafos de escena actuales.

2.1.2 Orientacin hacia el Hardware Grfico 3D. Libreras grficas de bajo nivel.
El objetivo bsico en la generacin de imgenes 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 clculos que suele sobrepasar la capacidad de la CPU del ordenador. Por ello, es norma comn recurrir a la utilizacin de hardware grfico especialmente diseado para esta tarea, y, como consecuencia de un API (Application Programmer's Interface) que proporcione un acceso eficiente a sus capacidades. Adems, es deseable que dicho API proporcione una interfaz comn entre los diferentes tipos de hardware grfico existentes. En la actualidad hay varios sistemas que proporcionan un API para renderizado de grficos 3D, pero no todos ellos resultan adecuados para su utilizacin en tiempo real. Uno de los ms conocidos es PHIGS (Programmers's Hierarchical Interactive Graphics System) . PHIGS est basado en GKS (Graphic Kernel System) y es un estndar ANS que permite manipular y dibujar escenas 3D encapsulando descripciones de objetos y atributos en display list, esta caracterstica es especialmente til si existen objetos complejos que pueden ser definidos una sola vez y dibujados varias veces, o tambin si la escena va a ser transmitida por red. Uno de sus principales inconvenientes es que no resulta adecuada si los objetos necesitan estar actualizndose continuamente, y tambin que no soporta algunas caractersticas actualmente bsicas 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 caractersticas avanzadas de rendering y que tan slo funciona en sistemas basados en X. Otro API muy conocido es Renderman, a diferencia de los anteriores, proporciona un lenguaje de programacin para realizar las descripciones de los objetos y sus propiedades, esta caracterstica permite generar imgenes de un nivel de acabado muy elevado, pero es muy difcil disear un hardware grfico que lo soporte. Los tres sistemas anteriores constituyen los sistemas estndar de generacin de imgenes histricamente ms conocidos, pero presentan algunas carencias importantes a la hora de ser empleados en la generacin de imgenes en tiempo real. OpenGl es un API desarrollado a partir de IrisGL, una librera 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 grficos. Una alternativa a OpenGl en sistemas Windows, es el API Direct3D, el cual es un subconjunto de DirectX, una librera que adems de la parte grfica da soporte de audio, vdeo, gestin de perifricos y gestin de red. Desde sus orgenes Direct3D ha sido considerada de inferior calidad que OpenGl (incluso en sistemas Windows), esta visin est cambiando debido a las

18

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

ltimos mejoras en su API que lo han hecho ms estable y potente. Sin embargo, Direct3D no es un standard abierto, solamente funciona en sistemas Windows, y es ms que dudoso que Microsoft tenga intencin 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 estndar industrial cuya especificacin 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 grficas bsicas tales como puntos, lneas, polgonos e imgenes, y operaciones tales como la aplicacin de transformaciones afines o proyecciones, clculos de iluminacin, ocultacin entre objetos o mapeado de texturas. En la actualidad existen gran cantidad de tarjetas grficas desarrolladas para cumplir la especificacin de OpenGl. Los drivers de OpenGl encapsulan la informacin sobre el hardware grfico al que van destinados, liberando al desarrollador de aplicaciones, de tener que hacer desarrollos adaptados a las caractersticas de los diferentes tipos de tarjetas grficas. El funcionamiento bsico de la OpenGl puede ser observado en la Figura 2-1. Los comandos de OpenGl son recibidos desde la parte izquierda del diagrama, la informacin que se enva es bsicamente relativa a vrtices de la geometra (Geometry Path) o a imgenes (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 visualizacin de OpenGl.

Tanto la informacin de vrtices como de imagen puede llegar en un formato compactado, siendo en este caso descomprimido dentro de la propia pipeline. Puede que la informacin referente a la geometra est indicada en forma curvas o superficies paramtricas, en tal caso se evalan y transforman en una descripcin basada en vrtices. En la siguiente etapa, se realizan operaciones sobre primitivas formadas de vrtices (puntos, segmentos de lneas y polgonos), los vrtices son transformados e iluminados, y las primitivas son ensambladas y recortadas por la pirmide de visin. Tambin se realizan operaciones sobre las imgenes, y algunas de ellas se almacenan sobre la memoria de texturas, listas para ser aplicadas sobre la geometra 3D. En la etapa de Rasterizacin, se utilizan los resultados de la fase anterior para generar una serie de direcciones y valores del framebuffer mediante la utilizacin de una descripcin 2D basada en puntos, lneas o polgonos. Por ltimo, el contenido del framebuffer es actualizado teniendo en cuenta la informacin 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 grficas del nivel ms bajo posible, y como consecuencia no proporciona mecanismos directos para realizar la descripcin de objetos

19

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

geomtricos complejos (como por ejemplo un cubo o una esfera). Estos han de ser ensamblados mediante la utilizacin de mltiples comandos de OpenGl.

2.1.2.2 Representacin 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 informtica grfica dispone de diferentes mtodos para proporcionar definiciones matemticas de dichos objetos, siendo una de las ms comunes considerar que la forma geomtrica de un objeto est ser definido por un conjunto de tringulos conectados por sus lados (ver Figura 2-2).

Figura 2-2. Modelo de representacin de objetos 3D mediante secuencias de tringulos.

El hecho de emplear una representacin de este tipo hace que el proceso de dibujado de una escena pueda ser considerado como el procesado de un conjunto ms o menos grande de tringulos. Las actuales tarjetas grficas 3D incorporan hardware capaz de procesar dichos tringulos y transformarlos en su representacin correspondiente en pxeles de pantalla. Las libreras grficas de bajo nivel proporcionan mtodos para realizar descripciones de este tipo de objetos poligonales y emplear de forma adecuada el hardware grfico. La forma bsica de descripcin de un objeto en OpenGl consiste en la definicin de las coordenadas que especifican vrtices entre un par de comandos glBegin/glEnd, as, por ejemplo, para definir un tringulo formado por los vrtices en (0,0,0) (0,1,0) y (1,0,1) seria necesaria la siguiente secuencia de cdigo.

glBegin(GL_POLYGON); glVertex3i(0,0,0); glVertex3i(1,1,0); glVertex3i(1,0,1); glEnd();

Cada vrtice es especificado con dos o tres coordenadas. Adicionalmente se pueden definir una normal, coordenadas de textura y color que sern utilizados en el procesamiento del vrtice. La normal se utiliza en los clculos de iluminacin y es especificada por medio de un vector de 3 componentes. El color proporciona informacin sobre las componentes Roja, Verde, Azul y de Alfa del vrtice. 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 tringulo se pueden haber definido otras caractersticas que afectaran a la forma en la que ser dibujado, tales como las caractersticas del material empleado, la posicin y caractersticas de las luces que le afectan, la presencia de niebla, etc.

20

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.1.2.3 Modelos de Sombreado. Sombreado Local.


OpenGl solamente proporciona mtodos de sombreado locales. Mtodos muy populares en la imagen de sntesis tradicional como son el trazado de rayos, o la radiosidad, necesitan conocer informacin de otras partes de la escena diferentes al polgono que se est dibujando, y no resultan adecuados para una aplicacin en tiempo real. La razn de esto es que estos mtodos requieren un conocimiento global de la escena a dibujar, mientras que el hardware grfico es una pipeline de operaciones muy localizadas, y que no tiene capacidad para almacenar y recorrer la gran cantidad de informacin que compone una escena compleja. Existe una posibilidad de emplear estos mtodos con OpenGl que consiste en realizar un preclculo de la iluminacin empleando algn mtodo de iluminacin global, y asociar los resultados a los objetos grficos en un proceso anterior e independiente del dibujado. Este tipo de tcnica solamente resulta adecuada en la representacin de escenarios estticos. En OpenGl, el color de cada vrtice es calculado de forma independiente a partir de las propiedades del material y las condiciones de iluminacin. Los colores obtenidos en cada vrtice son interpolados linealmente sobre las primitivas de dibujado segn el mtodo de Gouraud.

2.1.2.4 Primitivas de dibujado.


En una escena normal la cantidad de tringulos suele ser aproximadamente el doble que el nmero de vrtices, esto evidencia que la gran mayora de los vrtices estn siendo compartidos por varios tringulos. El procesado independiente de los vrtices de cada tringulo incrementa de forma innecesaria los costes asociados a la transformacin e iluminacin de los vrtices y tambin a su transferencia. Es usual que procesado redundante de los vrtices incremente estos costes en un factor de 6. Para reducir esta redundancia computacional, es comn que el hardware grfico 3D disponga de primitivas de dibujado en las que un mismo vrtice es utilizado simultneamente por varios tringulos. El tipo de primitiva de este tipo ms empleada son las tiras de tringulos, tambin denominadas t-mesh o tambin triangle strp. En este tipo de primitivas, cada vrtice es usado de forma conjunta con los dos vrtices procesados en ltimo lugar para generar el siguiente tringulo. En el caso de emplear t-meshes largas, en lugar de tringulos sueltos, la mayora de los vrtices son procesados tan slo 2 veces, reduciendo en un factor de 3 los clculos asociados a la transformacin e iluminacin de vrtices. An as, cada vrtice sigue siendo procesado 2 veces, y, por tanto, sigue existiendo un coste redundante. En la Figura 2-3 se pueden observar las primitivas geomtricas ms significativas empleadas por la librera OpenGl, y como el orden en el que se definen los vrtices, especifica la forma en la que se van generando los tringulos individuales.

21

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 2-3. Primitivas geomtricas empleadas por OpenGl.

En arquitecturas en las cuales las transformaciones geomtricas e iluminacin son realizadas por software, se pueden emplear estructuras indexadas en las que los vrtices pueden ser procesados y almacenados una sola vez, y los tringulos se generan en una fase posterior accediendo de forma indexada a estos vrtices ya procesados. Sin embargo, por razones de compatibilidad con el hardware grfico, los APIs actuales no suelen explotar esta posibilidad.

2.1.2.5 Pilas de Matrices.


OpenGl proporciona mtodos para realizar operaciones con matrices de 4x4, y bsicamente gestiona tres tipos de ellas: La matriz model-view que transforma las coordenadas de los vrtices; la matriz de texturas que es aplicada a las coordenadas de textura; y la matriz de proyeccin, la cual describe la pirmide de visin, 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 gestin de estas pilas de matrices, OpenGl incorpora una serie de funciones permiten entre otras cosas definir rotaciones, traslaciones, escalados, y operaciones de push y pop sobre las pilas. La matriz en la parte alta de cada pila, es la que en cada momento se est aplicando a los vrtices o las coordenadas de textura. El hecho de utilizar pilas de matrices resulta de gran utilidad en el caso de que exista una organizacin jerrquica de los objetos que se van a dibujar, y muy especialmente en el caso de que existan objetos con mltiples sistemas de referencia.

2.1.2.6 Empleo de Texturas.


La utilizacin de texturas mapeadas es una de las tcnicas que ms ha contribuido a mejorar la calidad grfica de los sistemas de generacin de imgenes en tiempo real. Dicha tcnica consiste emplear la capacidad de asociar imgenes a las primitivas geomtricas que representan los objetos, dichas imgenes proporcionan informacin de detalle sobre la apariencia de la superficie de los objetos, sobre sus zonas de transparencia, permite aplicar mapas de reflejo, etc.

22

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

La incorporacin de esta capacidad en los sistemas de generacin de imgenes en tiempo real supuso un enorme incremento en el realismo de las imgenes obtenidas (ver Figura 2-4).

Figura 2-4. Empleo de texturas por OpenGl.

Desde hace un par de aos es comn que el hardware grfico pueda aplicar varias texturas simultneamente sobre el mismo objeto, esta capacidad (multitexturing) ha contribuido a incrementar an ms la calidad de la imagen final.

2.1.2.7 Depth buffer.


El Depth-buffer (tambin conocido como Z-buffer) proporciona un mtodo sencillo para almacenar la informacin 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 cmara. Cuando ms adelante el proceso de dibujado de un objeto 3D ordene dibujar de nuevo sobre esa posicin, bastar con comparar si la distancia de ese objeto es superior o inferior a la ya almacenada, si es mayor, el objeto est ms 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 sera dibujado, y la nueva distancia almacenada. Normalmente cada pixel dispone de 24 o 32 bits para almacenar la informacin referente a la profundidad. Profundidades de z-buffer inferiores suelen hacer que se produzcan errores en la evaluacin de la profundidad a la que se encuentran los objetos, y, por tanto, pequeos errores de dibujado. Este mtodo es implementado muy fcilmente en el hardware, y resulta un mtodo muy eficiente para calcular las ocultaciones producidas entre los objetos 3D. Existen otros mtodos de ocultacin que son compatibles con OpenGl, tales como la utilizacin de BSP trees, la utilizacin de Octrees o la pre-ordenacin de los objetos, pero estos mtodos no son soportados directamente por el hardware grfico.

2.1.2.8 Shaders.
En los ltimos aos, los fabricantes de hardware grfico han centrado parte de sus esfuerzos en flexibilizar la forma en la que acta la OpenGl, permitiendo que algunas de las partes de la pipeline grfica (hasta ahora totalmente fija) puedan ser reemplazadas por unidades de cdigo definibles por el usuario. 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 diseadas para su utilizacin en grficos 3D. Un
Figura 2-5. Imagen generada con la ayuda de shaders

23

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

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

2.1.3 Libreras grficas de Alto Nivel. Grafos de escena.


Las libreras de bajo nivel como la OpenGl estn orientadas a facilitar la utilizacin hardware grfico, 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 grfico, y que al mismo tiempo, permita un control total sobre sus funcionalidades. Como consecuencia de esto, OpenGl proporciona acceso a operaciones grficas del nivel ms bajo posible, y deja en manos del desarrollador de la aplicacin la creacin y gestin de objetos geomtricos ms complejos tales como cubos, esferas, coches, casas o animales. Para ayudar al desarrollador en esta tediosa tarea, existen libreras de ms alto nivel que encapsulan la complejidad de estos objetos geomtricos en estructuras especiales, y que, adems, proporcionan mtodos para gestionar la inmensa cantidad de informacin geomtrica que suele ser manejada. Es usual que estas libreras de alto nivel, estn implementadas utilizando como base una librera de bajo nivel del estilo de la OpenGl. Las libreras de bajo nivel proporcionan mtodos para realizar nicamente descripciones geomtricas muy sencillas (por ejemplo un tringulo con un material y una textura determinada). La primera necesidad de un desarrollador de aplicaciones de realidad virtual es agrupar este tringulo con otros similares para poder, por ejemplo, definir la geometra un tornillo. A su vez, agrupar este tornillo con otra serie de elementos, para formar otro objeto de mayor complejidad, como puede ser una lmpara; agrupar esa lmpara con otros objetos para formar una habitacin, etc. Esta forma en la que los objetos del mundo real aparecen agrupados de forma jerrquica, ya podra ser una razn suficiente para que las libreras de alto nivel tomasen la decisin de emplear una estructura de datos con una organizacin jerrquica, pero, adems, la organizacin jerrquica de los elementos que constituyen una escena, facilita la utilizacin de mltiples sistemas de referencia, y ayuda a controlar la carga del sistema. La estructura jerrquica empleada de forma generalizada por todas las libreras grficas de alto nivel, recibe el nombre de Grafo de Escena o Scene Graph en literatura inglesa. En los siguientes subapartados se muestran las generalidades de los grafos de escena, se presentan los tipos de nodos bsicos empleados, y los mtodos de seleccin de nivel de detalle y culling, encargados de mantener la carga del sistema dentro de unos limites razonables. Por ltimo, se muestra la forma en la que actan las libreras grficas 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 acclico de nodos que contiene los datos que definen un escenario virtual y controlan su proceso de dibujado. Contiene descripciones de bajo nivel de la geometra y la apariencia visual de los objetos, as como descripciones de alto nivel referentes a la organizacin espacial de la escena, datos especficos de la aplicacin, transformaciones, etc. Los grafos de escena almacenan la informacin del escenario virtual en diferentes tipos de nodos. Existen nodos que almacenan la informacin geomtrica y actan como nodos hijos dentro del grafo de escena; el resto de los nodos suelen aplicar algn tipo de modificacin sobre el segmento de jerarqua que depende de ellos, bien sea estableciendo agrupaciones, aplicando

24

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

alguna transformacin afn o realizando algn tipo de seleccin 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 organizacin lgica de la escena. Establecer dependencias jerrquicas entre distintos sistemas de referencia. Posibilitar el proceso de seleccin entre mltiples niveles de detalle. Posibilitar el proceso automtico de Culling (eliminacin automtica de los objetos que se encuentran fuera del campo de visin). Facilitar el control de la escena por parte del usuario. Hacer ms cmodo el acceso a las libreras grficas de bajo nivel (OpenGl en este caso). En la siguiente imagen (Figura 2-5) se puede apreciar la descomposicin de un objeto en sus diferentes componentes, de manera agrupada, lo cual sera una aproximacin al grafo de escena que lo definira.

Figura 2-6. Descomposicin de un objeto en su aproximacin al correspondiente Grafo de Escena.

2.1.3.2 Tipos bsicos de Nodos.


En la actualidad existen varias libreras grficas de alto nivel, y cada uno de sus grqfos de escena presenta sus propias particularidades. Sin embargo, existe un conjunto bsico de nodos que, a veces con distintos nombres, se encuentran presentes en todos ellos: Nodo de Geometra. Almacenan la informacin poligonal de los objetos, tambin almacenan informaciones referentes a su apariencia, tales como material, textura, etc. Usualmente actan como nodos hoja.

25

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 jerrquico. Nodo Nivel de Detalle. Usualmente llamados nodos LOD (Level of Detail). Seleccionan uno de sus hijos, basndose en la distancia entre el objeto con mltiples niveles de detalle y el punto de vista. Nodo de Transformacin Afn. Permite aplicar una matriz de transformacin que afectara a ubicacin espacial de sus nodos hijos. Son necesarios para la definicin de objetos mviles y tambin para la creacin de estructuras articuladas. Nodo de Switch. Permiten realizar una seleccin entre sus nodos hijos.

Tambin 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 genricos que necesite el usuario, y tambin rutinas de callback escritas por el usuario que son invocadas junto con el cdigo interno de gestin del nodo.

2.1.3.3 Proceso de seleccin de niveles de detalle.


Cualquier sistema grfico presenta unas limitaciones que afectan al nmero de primitivas geomtricas 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 seleccin de niveles de detalle es una de estas estrategias. La idea principal del proceso de seleccin de niveles de detalle se basa en la observacin de que un objeto, cuando se encuentra alejado, no puede ser apreciado en detalle, bien sea por el reducido nmero de pxeles que ocupa en pantalla, debido al efecto de la perspectiva, o bien por efecto de las condiciones atmosfricas, tales como la niebla, o la iluminacin. Esta circunstancia hace que un objeto originalmente muy complejo, pueda ser sustituido por otro geomtricamente ms sencillo. Como consecuencia, una base de datos para grficos en tiempo real suele hacer que cada objeto presente distintas versiones de diferente complejidad geomtrica, cada una de las cuales representa al objeto en un margen de distancias concreto. Adems, 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 funcin de ella, se selecciona la representacin que resulte ms adecuada: una representacin geomtricamente muy sencilla si el objeto se encuentra tan alejado que es imposible percibir sus detalles, o una estructura geomtricamente 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 seleccin 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 visin empleado, la resolucin en pxeles de la imagen, la precisin ptica del sistema de monitorizacin, ciertos efectos atmosfricos 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 ms 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 condicin de cambio de nivel de detalle, (en funcin 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 inters especial a la forma en la que se producen los cambios entre niveles de detalle. Existen varias tcnicas, que permiten reducir

26

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

los efectos indeseables de las transiciones entre niveles de detalle, unas de ellas consisten en seleccionar el punto adecuado de transicin, otras, en la creacin de muchos niveles de detalle distintos, de tal forma que las diferencias entre dos niveles de detalle consecutivos sean mnimas, 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 transicin progresiva entre las dos representaciones: La tcnica de Fading produce un fundido suave entre las imgenes 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 estn siendo dibujados simultneamente; la tcnica de Morphing, hace que los vrtices de la geometra de uno de los modelos se modifiquen suavemente, hasta adoptar la posicin de los vrtices del otro modelo. Esto requiere que algunos vrtices 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 transicin la CPU consume un tiempo adicional en la gestin del morphing. Es el mtodo que presenta mejores resultados tanto a nivel visual como computacional, sin embargo, el hecho de que existan dependencias tan fuertes entre los distintos niveles de detalle, hace que dichos modelos sean muy difciles de generar, y que en la prctica, sea muy poco usado. Para tener una referencia de la magnitud de la reduccin de clculos que supone la utilizacin de niveles de detalle, se puede indicar que la representacin poligonal de una persona de una calidad aceptable requiere unos 2250 polgonos, mientras que el nivel de detalle ms bajo puede ser resuelto con tan slo 38. En la Figura 2-6 se pueden apreciar los diferentes niveles de detalles empleados en la representacin del busto de una persona.

Figura 2-7. Diferentes niveles de complejidad en la representacin geomtrica de un busto.

En la figura anterior, la representacin de ms calidad tiene aproximadamente unos 60.000 caras, la que aparece en tercer lugar presenta aproximadamente 600 caras, y por ltimo la ms sencilla, est formada por tan slo 60 caras. Esto evidencia que con la utilizacin adecuada de niveles de detalle se obtienen unas tasas de reduccin de su coste computacional que se mueven en dos ordenes de magnitud. En la Figura 2-7 se ha realizado una representacin conjunta de las geometras que representan el tercer y cuarto nivel de detalle, situndolas a distancias de la cmara cada vez mayores, es fcil comprobar que a medida que la distancia va aumentando las diferencias entre ellos se vuelven prcticamente imperceptibles.

27

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

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

Existe un gran nmero de investigaciones relativas al desarrollo de tcnicas de simplificacin geomtrica que pueden ser empleadas para la generacin de niveles de detalle.

2.1.3.4 Proceso de culling.


En una aplicacin de simulacin, o en cualquier entorno virtual en general, el usuario se encuentra inmerso en una inmensa base de datos geomtricos. Sin embargo, en cada instante est mirando en una direccin concreta, y, por consiguiente, gran parte de la geometra permanece fuera de su campo de visin. Enviar toda la base de datos al hardware grfico resultara muy costoso, y, adems, es innecesario. La CPU puede determinar cuales son los objetos que estn dentro de la pirmide de visin (denominada viewing frustum o simplemente frustum en la literatura inglesa) y con ello reducir considerablemente la cantidad de datos a transferir al hardware grfico y consecuentemente la cantidad de trabajo a realizar por ste. Este proceso es conocido como culling, y es junto el proceso de gestin de niveles de detalle, uno de los principios que permite mantener la cantidad de geometra a dibujar dentro de unos mrgenes adecuados. Existen mtodos 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 arquitectnico, formados por muchas habitaciones y paredes. Bsicamente consisten en determinar que objetos son visibles a travs de las puertas y ventanas, y almacenar la informacin en estructuras de datos adecuadas que son rellenadas en una fase previa a la simulacin. Otro tipo de tcnica de culling consiste en dividir el espacio en celdas regulares, y calcular que otras celdas son visibles desde cada una de ellas. Esta operacin ha de ser tambin realizada en una fase de preproceso. En tiempo de ejecucin simplemente se determina la celda en la que est el usuario, y en funcin de ello, se activa o desactiva la visualizacin de celdas correspondientes. Esta tcnica es especialmente til en aplicaciones en las que el espacio puede ser fcilmente compartimentado, como por ejemplo aquellas que consisten en el recorrido de carreteras o tneles. Estas dos ltimas tcnicas pueden ser aplicadas en bases de datos que tienen caractersticas muy concretas, y presentan como ventaja principal que los clculos 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 mviles, o bien, en aquellos casos en los que el usuario no tiene ningn tipo de restriccin en cuanto a su movimiento. Existen mtodos de culling genricos que pueden ser aplicados en cualquier circunstancia, y que estn basados en el clculo de interseccin entre la pirmide de visin y las envolventes de los objetos de la escena (conocidos en la literatura inglesa como bounding volumes). Esta tcnica 28

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

presenta corno inconveniente principal, el hecho de que las intersecciones han de ser calculadas en tiempo de ejecucin. Los algoritmos que realizan este tipo de culling han de ser capaces de establecer un balance entre la carga que producen sobre la CPU, y el ahorro de trabajo que producen sobre el hardware grfico. La utilizacin de bounding volumes resulta especialmente adecuada para las bases de datos organizadas en forma de Grafo de Escena, ya que su estructura puede ser aprovechada para definir una organizacin jerrquica de bounding volumes. Cada nodo tiene asociado un bounding volume que engloba al nodo en s, y a todos sus hijos. La librera que gestiona el scene graph, tiene capacidad para recalcular automticamente la forma de esas envolventes cada vez que existe una modificacin en la topologa 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 modificacin es propagada hacia sus padres. De este modo la jerarqua de bounding volumes permanece continuamente actualizada. Es bastante comn emplear como envolventes paraleleppedos alineados con los ejes (tambin 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 pirmide de visin, y, sin embargo, no ocurra lo mismo con el objeto en s. Por esta razn, es adecuado que la envolvente se adapte lo mximo posible a la forma real del objeto. Analizado desde esta ptica, las bounding boxes son una mejor aproximacin, sin embargo, la actualizacin, transformacin y testeado mediante bounding spheres es mucho ms rpida. Algunas libreras como OpenGl Performer emplean sistemas mixtos, en los que las geometras finales del grafo de escena se procesan mediante bounding boxes y los nodos intermedios mediante bounding spheres. El mtodo de procesado de una escena con este tipo de culling jerrquico consiste en hacer un recorrido recursivo del grafo de escena, comprobando para cada nodo la forma en la que su envolvente intersecta con la pirmide de visin, tomando las siguientes decisiones: El bounding volume est completamente fuera de la pirmide de visin: ni este nodo ni sus hijos han de ser dibujados. El recorrido del scene graph contina sin entrar en esta rama. El bounding volume est completamente dentro de la pirmide de visin: este nodo y sus hijos han de ser dibujados. En esta rama ya no es necesario realizar ms comprobaciones de cull. El bounding volume intersecta con la pirmide de visin: se contina 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 organizacin jerrquica de la escena, de tal modo que los objetos con una ubicacin espacial prxima aparezcan agrupados debajo de un mismo nodo. As por ejemplo, supongamos en el caso del tornillo que forma parte de una lmpara, la cual se encuentra en el saln de una casa que forma parte de un pueblo; si esta escena tuviese una organizacin jerrquica adecuada en la que hubiese sucesivos nodos tomillo->lmpara->saln->casa->pueblo, bastara con comprobar que la casa est fuera de la pirmide de visin 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 grfica una situacin 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 relacin entre la organizacin jerrquica de los nodos del grafo de escena y las bounding spheres correspondientes a cada nodo.

29

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 2-9. Bounding volumes en un proceso de culling jerrquico.

Existen mtodos de culling que tambin tienen en cuenta las condiciones de visibilidad debidas a las condiciones atmosfricas (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.3.5 Multiproceso.
Las aplicaciones de grficos en tiempo real suelen consumir gran cantidad de recursos, por ello es habitual que en algunos casos sea necesario recurrir al empleo de ordenadores con varios procesadores. Hay dos formas posibles de emplear de forma conjunta varios procesadores: La organizacin en paralelo y la organizacin en serie o pipeline. La primera de ellas presenta como ventaja que tiene poca latencia, pero es de difcil implementacin, pues encontrar la forma en la que paralelizar procesos encierra bastante complejidad. La organizacin en pipeline, presenta como inconveniente que tiene ms latencia que la anterior, pero, por el contrario, resulta de una implementacin mucho ms sencilla. Tambin es posible definir estructuras mixtas, pero es un rea que no ha sido muy investigada.

2.1.3.5.1 Procesamiento Paralelo.


Hay varias formas de paralelizar un algoritmo: empleando asignacin esttica, el trabajo total es dividido 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 asignacin dinmica, los trabajos a realizar por las CPUs son dejados en una zona comn, cuando un procesador ha finalizado su trabajo actual toma otro bloque de trabajo de la zona comn 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 tamao 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 haba tomado un bloque de trabajo demasiado grande.
El principal problema de la utilizacin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 generacin 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 aplicacin de grficos 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 actualizacin de los valores de los nodos con los valores provenientes de algn mecanismo de gestin del comportamiento de la escena. El procesado visual consiste en la realizacin de las operaciones de culling y dibujado (CULL y DRAW). Es habitual que los procesos de culling y draw sean realizados de forma automtica. La misin de cada una de estas etapas es la siguiente: APP. Lee valores de los perifricos de entrada, realiza la simulacin de los objetos que se mueven, actualiza la base de datos visual e interacciona con otras posibles simulaciones conectadas a travs de la red. CULL. Aplica el culling jerrquico determinando que porciones de la escena son potencialmente visibles, realiza una seleccin de los niveles de detalle, realiza una ordenacin de la geometra por su estado grfico, 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 grfico con la lista de los objetos que han quedado de la fase anterior. Algunas libreras grficas como OpenGl Performer incluyen en la pipeline de procesado de la escena otros procesos: ISECT. Realiza clculos de interseccin entre segmentos de lnea y la geometra del grafo de escena, lo cual se puede emplear para deteccin de colisiones. COMPUTE. Realiza clculos complejos de forma asncrona. DBASE. Gestiona de forma asncrona la base de datos que define la escena. Dependiendo del nmero de CPUs disponibles y del tipo de aplicacin se pueden emplear distintos modelos de multiproceso, as, en el caso de disponer de slo un nico procesador las tres etapas seran ejecutadas en la misma CPU. En el caso de disponer de dos, los procesos de APP y CULL pueden ser ejecutada en una y el DRAW en la otra, o bien se ejecutara la etapa de APP en una CPU y las de CULL y DRAW en las otra. En el caso de existir 3 procesadores, uno podra estar dedicado al APP, otro al CULL y otro al DRAW. En sistemas de simulacin complejos con dos o ms salidas grficas, es comn encontrar estructuras mixtas formadas por 8 o ms CPUs.

2.1.4 Revisin de Grafos de Escena.


Una vez presentadas las caractersticas bsicas de las libreras grficas de bajo y alto nivel, resulta adecuado analizar con ms profundidad las caractersticas de los grafos de escena ms conocidos. Si bien en este apartado no se profundiza en el anlisis de la totalidad de los grafos de escena actuales, s que se trata sobre aquellos que han tenido una mayor influencia en la evolucin de esta rama de la informtica grfica. Con esta intencin se hace una descripcin del funcionamiento de OpenGl Performer, que encapsula en estructuras de ms alto nivel la mayora de las funcionalidades de OpenGl y proporciona funcionalidades aadidas orientadas hacia aplicaciones que necesitan una elevada tasa de refresco, como por ejemplo aplicaciones de simulacin visual o escenografa virtual; la librera Open Inventor que proporciona una interfaz

31

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

grfica y un grafo de escena muy flexibles que facilitan la creacin y manipulacin interactiva de una escena 3D; VRML, un formato de fichero que describe un grafo de escena y que tiene la intencin de ser el estndar para la navegacin en espacios tridimensionales a travs de Internet ; y por ltimo se profundizara en OpenSceneGraph, que es la que hemos utilizado en el presente proyecto, una librera basada en OpenGl, y con gran similitud con OpenGl Performer, con la principal diferencia de que es de codigo abierto, y por tanto totalmente gratuita. En los siguientes apartados se detallaran las propiedades bsicas de estos grafos de escena, y se har una descripcin de cuales son los nodos que los constituyen y caractersticas. En un ltimo apartado se muestran de forma rpida otros grafos de escena existentes en la actualidad.

2.1.4.1 OpenGl Performer.


OpenGl Performer es un Grafo de Escena diseado para optimizar al mximo la utilizacin del

hardware grfico. Es una librera muy orientada al mercado de la simulacin visual, siendo su mayor prioridad la obtencin de tasas de refresco muy altas, llegando a mantener tasas constantes de 50 frames/segundo. Proporciona soporte para multiproceso, permitiendo dividir el trabajo entre mltiples CPUs, gestionando su sincronizacin y transferencia de informacin. Adems, proporciona algunas caractersticas avanzadas tales como la deteccin de intersecciones, la gestin de terrenos, morphing geomtrico o incluso una pequea interfaz de usuario. Los nodos utilizados por la librera Performer son los siguientes: Nodo Geode: Es un nodo hoja que almacena la informacin geomtrica de un objeto (Geometry node). Est formado por una lista de estructuras llamadas pfGeoSet que encapsulan caractersticas de bajo nivel referentes a primitivas de dibujado y su apariencia grfica, y que almacenan la informacin en un formato muy prximo a la OpenGl. Nodo Grupo: Sirve para agrupar varios nodos hijos. Nodo Scene: Acta como nodo padre de todo el grafo de escena. Se utiliza tambin para almacenar informaciones visuales comunes a toda la escena, tales como condiciones de iluminacin, modos de dibujado, condicin de niebla, etc. Nodo SCS: Permite definir un sistema de coordenadas que no pueden ser modificados durante la simulacin (Static Coordnate 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 simulacin (Dynamic Coordnate System). Se utiliza para implementar objetos articulados u objetos que se desplacen por la escena. Nodo FCS: (Flux Coordnate System). Es de caractersticas similares al DCS, pero presenta caractersticas especiales para su utilizacin en multiproceso. Nodo Switch: Es un nodo que puede tener varios hijos y permite que el usuario seleccione 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 duracin asignada. Es posible hacer que la secuencia se ejecute de inicio a fin, de fin a inicio, que se repita cclicamente, 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 geometra coplanar. Nodo LighSource: Contiene la especificacin de una fuente de luz.

32

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Nodo BillBoard: Rota una geometra de modo que siempre aparezca orientada hacia el punto de vista. Es especialmente til para representar objetos que tienen una simetra axial, como pueden ser rboles, farolas, etc. Nodo Partition: Particiona la geometra para realizar intersecciones eficientes. Nodo Text: Es tambin un nodo hoja que se utiliza para renderizar textos 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 librera Inventor es tambin un sistema de definicin, manipulacin y renderizado de escenas 3D basada en la utilizacin de descripciones geomtricas de alto nivel. La versin original se denominaba Iris Inventor funcionaba exclusivamente sobre mquinas SGI, y estaba implementada como una capa por encima de la librera IrisGl. En el momento que ARB creo la especificacin de librera OpenGl, tambin se realiz una descripcin del Open Inventor, una versin multiplataforma del antiguo Iris Inventor que utilizase como base a la librera OpenGl.
Inventor prima la usabilidad sobre el rendimiento. Est formado por un conjunto muy elaborado de nodos de uso muy sencillo, pero no proporciona un buen rendimiento en tiempo real (al menos comparado con otros sistemas como OpenGl Performer).

Las principales caractersticas de Open Inventor son: Facilita la organizacin de escenas 3D. Por tener una estructura de grafo de escena, permite organizar jerrquicamente la informacin de forma sencilla. Proporciona estructuras grficas predefinidas. Las formas bsicas proporcionadas por Inventor son cajas, conos, esferas y cilindros, adems, permite definir textos 2D y 3D. Proporciona utilidades grficas ya definidas, por ejemplo rutinas para manejar matrices. Tiene mecanismos muy flexibles de descripcin de formas y objetos. Permite definir objetos a partir de curvas y superficies de tipo NURBS, y tambin a partir de mallas de tringulos. Tiene capacidades de rendering sofisticadas. Permite seleccionar entre distintos modos de renderizado. Se pueden seleccionar distintas cmaras y distintos modos de visualizacin interactiva. Proporciona un mtodo integrado de seleccin y manipulacin 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 diseados para ese propsito. No est diseado para soportar multiproceso. Inventor es un grafo de escena en el que las propiedades de cada nodo afectan a los nodos que estn por debajo de l y tambin a los nodos colocados a su derecha. Cada nodo puede ser una forma, una propiedad de su apariencia, una transformacin, una cmara 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 transformacin afn, como por ejemplo una traslacin o una rotacin. Nodo Appearance: Modifica la apariencia de los objetos que le siguen en el grafo. Nodo Light: Aplica una iluminacin a los nodos que le siguen. Nodo Camera: Visualiza los nodos que le siguen.

33

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 centmetros, pulgadas o metros), y aplica un factor de escala en el caso que sea distinto de los nodos que le precedan. 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 Manpulator: Asigna a los objetos una interfaz 3D que permite de modificar su posicin, su tamao y orientacin 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 atmosfricos, como por ejemplo niebla. Nodo Normals: Es utilizado para realizar clculos de iluminacin.

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 acta como raz, y usualmente existe una cmara 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 despus de la primera esfera, sta no estara 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 posicin y orientacin deseada.

Figura 2-10. Ejemplo de Grafo de escena utilizado por Inventor.

Una de las objetivos principales de Inventor es definir escenas 3D interactivas. Inventor gestiona automticamente la seleccin y manipulacin de objetos 3D, as como el movimiento del usuario por la por la escena 3D o en torno a los objetos 3D. Tambin permite asociar animaciones automticas a los objetos.

34

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 incorporacin de textos, imgenes y secuencias de audio y vdeo. 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 direccin en Internet diferente de la de la habitacin principal, o puede que al seleccionar la puerta de dicha habitacin accedamos a una habitacin que est en otro servidor dentro de la red. Adems, VRML ha sido diseado para trabajar interactuando con Java y JavaScript. Concebido como una extensin de Inventor, sufre de sus mismos problemas de rendimiento. El formato VRML se encuentra en su versin 2.0. Su primera versin (VRML 1.0) slo permita crear y visualizar mundos 3D estticos. En la versin VRML 2.0 incorpora elementos que permiten hacer que los objetos 3D se modifiquen automticamente y sean capaces de responder a la accin 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.

Grouping nodes
Anchor Billboard Collision Group Transform

Sensors
CylinderSensor PlaneSensor ProximitySensor SphereSensor TimeSensor TouchSensor VisibilitySensor

Appearance
Appearance FontStyle ImageTexture Material MovieTexture PixelTexture TextureTransform

Special Groups
Inline LOD Switch

Geometry
Box Cone Cylinder ElevationGrid Extrusion IndexedFaceSet IndexedLineSet PointSet Sphere Text

Interpolators
ColorInterpolator CoordinateInterpolator NormalInterpolator OrientationInterpolator PositionInterpolator ScalarInterpolator

Common Nodes
AudioClip DirectionalLight PointLight Script Shape Sound SpotLight WorldInfo

Bindable Nodes
Background Fog NavigationInfo Viewpoint

Geometric Properties
Color Coordinate Normal TextureCoordinate
Tabla 2-1. Nodos de VRML 2.0.

Llama la atencin de existencia de nodos muy especializados como el Background que permite aadir imgenes de fondo, lo que permite representar por ejemplo montaas lejanas y un cielo, o de un tipo de nodo para crear fcilmente terrenos irregulares (nodo ElevationGrid). Tambin existen nodos como el Collision que permiten hacer que un objeto reaccione como si fuese slido de tal modo que el usuario no puede atravesarlo pero si caminar sobre l. Existe un grupo de nodos que actan 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 dinmicas sobre los objetos de la escena, 35

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

as es posible definir un objeto que presente un morphing geomtrico, una puerta de apertura automtica o un objeto que varia cclicamente su color o que recorre una trayectoria determinada. El nodo Sound permite incorporar sonidos con una ubicacin espacial tridimensional. Uno de los nodos ms importantes en VRML es el nodo Script, el cual bsicamente contiene un programa que recibe eventos de entrada, los procesa y genera eventos nuevos, mediante la utilizacin de este tipo de nodos se puede hacer que la escena y sus objetos presenten comportamientos muy sofisticados. Tambin resulta muy interesante la capacidad que tiene el usuario para definir nodos PROTO los cuales pueden contener en su interior ms nodos VRML, campos y scripts. Un desarrollador puede definir un nodo PROTO con unas determinadas caractersticas, de tal modo que puede ser utilizado, modificado o ampliado por un segundo desarrollador. En general se puede establecer una clasificacin similar en nodos grupo y nodos hoja similar a la de Performer o Inventor. Pero la gran cantidad de nodos (Figura 2-10), y las interdependencias que se establecen entre ellos, hacen VRML resulte mucho ms confuso que los grafos de escena anteriores.

2.1.4.4 OpenSceneGraph.
OpenSceneGraph (OSG) es un toolkit grfico de alto nivel y portable para el desarrollo de aplicaciones grficas de alto rendimiento tales como simuladores de vuelo, juegos, realidad virtual o visualizacin cientfica. Est orientado a objetos y construido a partir de la librera grfica OpenGL, esto libera al desarrollador de implementar y optimizar llamadas grficas de bajo nivel, y provee muchas utilidades adicionales para un rpido desarrollo de aplicaciones grficas. El corazn del grafo de escena ha sido diseado para tener mnimas dependencias de una plataforma especfica, requiriendo poco ms que C++ estndar y OpenGL. Esto ha permitido al grafo de escena ser rpidamente portado a un gran nmero de plataformas (originalmente desarrollado en IRIX, portado a Linux, Windows, FreeBSD, Mac OSX, Solares, HP-UX e incluso PlayStation2).

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

Todo el cdigo de OpenSceneGraph esta publicado bajo la OpenSceneGraph Public License (permite a proyectos de cdigo abierto y cerrado utilizarla, modificarla y distribuirla libremente). Open Scene Graph soporta view frustum culling, occlusion culling, small feature culling, nodos con nivel de detalle (LOD), clasificacin de estado, vertex arrays y listas de dibujado como parte del corazn del grafo de escena. OpenSceneGraph es uno de los grafos de escena disponibles de mayor rendimiento. Este rendimiento iguala a otros grafos de escena como OpenGL Performer o Vega Scene Graph. Open Scene Graph opta por soluciones muy parecidas a OpenGL Performer. Por contra, no soporta multiproceso, caracterstica que soporta OpenGL Performer. Open Scene Graph esta formado por los siguientes espacios de nombres:
osg : Es el ncleo de la librera OSG, y proporciona las clases bsicas del grafo de

escena tales como Nodes, Status, y Drawables, as como clases matemticas y otras.

36

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

osgDB: osgDB proporciona soporte para leer y escribir grafos de escena,

proporcionando un framework para plugins y clases para manejo de ficheros. osgFX : Es una extensin del ncleo del grafo de escena para proporcionar un framework de efectos especiales. osgGA : osgGA (osg GUI Abstraction) proporciona herramientas para ayudar a los desarrolladores para trabajar con distintos sistemas de ventanas. osgIntrospection : Proporciona un entorno de programacin que permite la consulta en tiempo de ejecucin de las propiedades y los mtodos relacionados con las librerias OSG. osgParticle : osgParticle amplia el ncleo del grafo de escena para soportar efectos de partculas. osgProducer : Es una librera de utilidades que integra OpenProducer para proporcionar clases de viewer de propsito general. osgSim : osgSim extiende el ncleo del grafo de escena para soportar Nodes y Drawables que especifiquen la simulacin visual, tales como soporte para un punto de luz navegacional y transformaciones de grados de libertado del estilo OpenFlight. osgTerrain : Librera de utilidades que proporciona soporte para la generacin de bases de datos de terreno. osgText : Extiende el ncleo del grafo de escena para dar soporte a texto de alta calidad. osgUtil : Proporciona clases de utilidad de propsito 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 bsicos de nodos: Node : La clase base para todas la clases que derivan de Node. Group : Agrupa varios nodos hijos. Transform : Clase base para aplicar una transformacin al subgrafo. MatrixTransform : Transformacin de una matriz 4x4. PositionAttitudeTransform : Transformacin que usa un Vector de tres coordenadas (Vec3) para la posicin, y una rotacin de Cuaternion (Quat) para la actitud, y un Vec3 para el pivote. DOFTransform : Nodo de transformacin de grados de libertad. Geode : Es un nodo hoja que almacena la informacin geomtrica de un objeto. Billboard : Rota una geometra de modo que siempre aparezca orientada hacia el punto de vista. Es especialmente til para representar objetos que tienen una simetra axial, como pueden ser rboles, farolas, etc. LOD : Se emplea para gestionar distintos niveles de detalle de un objeto Impostor : aade soporte para el cacheado jerrquico de imgenes. Switch : Es un nodo que puede tener varios hijos y permite que el usuario seleccione cuales de ellos quiere que sean dibujados. Sequence : 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 duracin asignada. Es posible hacer que la secuencia se ejecute de inicio a fin, de fin a inicio, que se repita cclicamente, etc. LightSource : Posicin un objeto Light en la escena ClipNode : Posiciona un objeto ClipPlane en la escena Projection : Sobrecarga la matriz de proyeccin. OccluderNode : Permite colocar en la escena planos y cajas para definir oclusiones entre objetos.

37

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.1.4.5 Otras libreras graficas de alto nivel


En los ltimos aos 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 cdigo abierto y multiplataforma. No tiene sentido aqu profundizar en las particularidades de cada uno de ellos, simplemente se mostrar una descripcin abreviada y un enlace de Internet para obtener informacin 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 librera 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 fcilmente extensible. Es mantenido por varias empresas y centros de investigacin.
PLIB/SSG. (http://plib.sf.nef).

PLib es un conjunto de libreras multiplataforma diseadas para ayudar a los desarrolladores de aplicaciones 3D interactivas. Es tambin distribuida bajo los principios de OpenSource. SSG (Simple Scene Graph) es uno de sus mdulos que proporciona un grafo de escena implementado sobre la base de OpenGl y C++.
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 libreras multiplataforma desarrolladas en C++ y que operan sobre OpenGl, gestiona de forma adecuada la seleccin de objetos y clculo de intersecciones, permite cargar distintos tipos de formatos de imagen, y dispone de varios mtodos 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 independiente de plataforma. Internamente dispone de un grafo de escena que introduce algunos conceptos comnmente no considerados como parte del entorno de simulacin tales como sonido espacial 3D.

2.1.5 Motores de Videojuegos


2.1.5.1 Motores de Visualizacin 2.1.5.1.1 3D GameStudio
3D GameStudio es un kit de desarrollo comercial de juegos de ordenador. Consta de un motor 3D, un motor 2D, un editor de niveles y modelos, un compilador de scripts y libreras de modelos, texturas,... Manipula con igual rendimiento escenas de interior y de exterior. Tiene un 38

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

motor de iluminacin que soporta sombras verdaderas y fuentes de luz en movimiento. El principal objetivo que esta aplicacin persigue es que el desarrollador del juego no necesite ser un programador experimentado. Se reduce al mximo el esfuerzo de desarrollo a costa de perder flexibilidad en el diseo del juego. La ltima versin (v5) es de marzo de 2002. Ofrece tres posibilidades para crear un juego: 1) Juegos diseados a base nicamente de controles, para usuarios con pocos conocimientos de programacin. 2) Juegos o efectos diseados con algo de programacin utilizando C-scripts. 3) Juegos o efectos programados en C++ o Delphi, para programadores con experiencia. Incorpora un ncleo de videojuegos, llamado A5. Pero lo que aqu se entiende por ncleo es un sistema de desarrollo que se encarga de generar efectos 3D y controlar la inteligencia artificial del juego.
Figura 2-12. Captura del editor de 3D Gamestudio.

2.1.5.1.2 Crystal Space


Cristal Space es un kit de desarrollo gratuito de juegos 3D libre y portable escrito en C++. Soporta seis grados de libertad, luces de colores, mipmapping, portales, espejos, transparencias, superficies reflectivas, sprites 3D (basados en frames o animaciones de esqueleto), texturas procedurales, radiosidad, sistemas de partculas, halos, niebla volumtrica, lenguaje de script (Python y otros), soporte para visualizacin a 8-bits, 16-bits y 32-bits, Direct3D, OpenGL, Glide, y visualizacin por software, soporte para fuentes, transformaciones jerrquicas,... Actualmente Crystal Space puede ejecutarse sobre GNU/Linux, Windows, Windows NT, OS/2, BeOS, NextStep, OpenStep, MacOS/X Server, DOS, y Macintosh entre otros. Crystal Space es un gran proyecto para el desarrollo de software abierto. Hay alrededor de 600 personas subscritas a sus listas de correo. Es un paquete orientado a eventos. La cola de eventos gestiona los eventos del sistema y enva eventos a quien proceda. El gestor de eventos se encarga de lanzar la visualizacin (evento cscmdProcess) y gestiona los eventos de usuario. Aunque existe cierto paso de mensajes en la aplicacin, se limita a mensajes de visualizacin y eventos de usuario.

2.1.5.1.3 Genesis3D
Genesis3D es un motor de cdigo libre para la visualizacin de escenas tridimensionales en tiempo real y que permite construir aplicaciones graficas 3D de altas prestaciones. Ha sido diseado principalmente para la visualizacin de escenas de interior logrando una elevada tasa de fotogramas por segundo siempre y cuando estn compuestas por una cantidad moderada de polgonos. Tambin puede ser utilizado para escenas de exterior si el diseo de las escenas se realiza tomando ciertas precauciones. Sus principales caractersticas son la deteccin rpida de colisiones, iluminacin precalculada y chequeo de la visibilidad. Su principal inconveniente es la visualizacin de escenarios exteriores sin imponer algn tipo de restriccin o lmite al tamao de la escena.

39

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

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

2.1.5.1.4 The Nebula Device


The Nebula Device (RadonLabs) es un nuevo motor de juegos gratuito de calidad profesional. Sus creadores, son el equipo que desarrollo Urban Assault (publicado por Microsoft en 1998). Utilizado tambin para desarrollar The Nomads (Xbox). Nebula es un motor de arquitectura moderna. Desarrollado en C++ y orientado a objetos, sus clases (DLLs) se cargan de forma independiente en tiempo de ejecucin. El motor puede ejecutarse en Linux, Windows 9X, Windows NT. Permite intercambiar sin interrupcin la visualizacin con OpenGL y Direct3D. Nebula utiliza como lenguaje de script el estndar tcl/tk. Los principales objetivos de Nebula son los siguientes:

Independencia de la plataforma. Gestin de la base de datos del juego: jerarquas 3D, texturas, materiales, luces, sonidos, animaciones, estados y sus relaciones. Proporcionar herramientas bsicas 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 diseado para hacer ms simple e intuitiva a los desarrolladores la produccin de juegos utilizando hardware de aceleracin 3D. La librera de clases permite abstraer los detalles asociados a las libreras de bajo nivel (OpenGL o Direct3D), proporcionando una interfaz basada en objetos.

Figura 2-13. Juego de billar desarrollado con OGRE

2.1.5.1.6 Shark3D
Shark3D es un kit de desarrollo de alto nivel para aplicaciones 3D en tiempo real. Esta orientado

a juegos, aplicaciones de realidad virtual y visualizacin. Optimizado para aplicaciones multiusuario a travs de una red de computadores o internet. Distribuido. Contiene un servidor de mltiples escenas. Incluye gestin de eventos de usuario y paso de mensajes para comunicacin en red y como comunicacin entre los diferentes elementos de su arquitectura.

40

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 simulacin de misiones militares, incluye

utilidades para la creacin de terrenos, superficies acuticas, interiores estilo portal y sistemas de partculas. Tambin incluye soporte multiplataforma (Windows, Mac OS y Linux), soporte para red, creacin de interfaces de usuario y lenguaje de script estilo C++. Permite importar objetos desde 3D Studio MAX y dispone de libreras matemticas, de deteccin de colisiones, de fsica de vehculos y una base de datos espacial. Incluye gestin de eventos de usuario y paso de mensajes para comunicacin en red.

Figura 2-14. Editor de Torque Game Engine

2.1.5.1.8 CDX Game Development Kit


CDX Game Development Kit es un kit de desarrollo de videojuegos de cdigo libre. Consta de un conjunto de clases de C++ para crear juegos para Windows y utilizando DirectX. Permite la creacin de juegos sencillos. Contiene rutinas de gestin de los eventos de entrada.

2.1.5.1.9 Artist
Artist (Animation Package for Real-Time Simulation) es un paquete de animacin de bajo coste

para el desarrollo de aplicaciones 3D complejas e interactivas en tiempo real: juegos, simulacin y realidad virtual. Artist permite generar grficos 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 cdigo necesario para ejecutar la simulacin del comportamiento. Puede generar bases de datos graficas optimizadas para mejorar la velocidad de visualizacin que permite maximizar el uso del hardware grafico disponible. Estas estructuras jerrquicas permitirn mantener una frecuencia de cuadro uniforme, sobre los 30 fps, consiguiendo la continuidad visual necesaria en el juego. Incluye las siguientes herramientas: Modelador de objetos geomtricos de propsito general. Base de datos jerrquica grafica. Conversores de fichero desde los formatos grficos usuales. 41

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Interfaz 3D para aadir objetos interactivos en las escenas de los juegos. Editor de jerarqua grafica para la configuracin de los parmetros de la gestin de la base de datos y la incorporacin de descripciones de comportamiento a los objetos geomtricos de la base de datos. Descripcin de alto nivel orientada a objeto del comportamiento de los objetos y las caractersticas del juego.

Figura 2-15. Captura del programa Artist.

2.1.6.2 Motores de Videojuegos

2.1.6.2.1 Fly3D
Fly3D es un motor de juegos gratuito que acompaa al libro 3D Games de Alan Watt y Fabio

Policarpo. El motor se encuentra actualmente en la segunda versin v2.0 (disponible en el segundo volumen del libro). Es un ncleo de videojuegos de reciente creacin, altamente estructurado y comentado y orientado a objetos. Ambas versiones estn desarrolladas en C++ y todo el cdigo especfico del juego se encuentra desarrollado con DLLs plugins (se incluye una herramienta para crear plugins). Contiene una amplia gama de herramientas y utilidades que facilitan el proceso de desarrollo del juego. El motor permite crear videojuegos y aplicaciones graficas en tiempo real de forma fcil y sencilla. Para ello se crean nuevos plugins que se enlazan con la aplicacin, sin necesidad de recompilar el ncleo y permitiendo un desarrollo modular. Se pueden implementar mltiples aplicaciones sin necesidad de replicar el ncleo. La implementacin del comportamiento visual y dinmico esta tambin modularizada, debiendo implementar para cada objeto una funcin especfica de visualizacin y otra de comportamiento (simulacin). 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 de funciones virtuales que los objetos del juego deben redefinir. Es un motor de cdigo libre y los videojuegos creados usando Fly3D v.1 pueden incluso comercializarse.

42

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.1.6.3 Videojuegos Completos


La informacin existente sobre videojuegos es muy abundante en la red. Gran parte de esta informacin hace referencia a trucos de juego, manuales, modificaciones de cdigo, creacin de ficheros de configuracin, evaluaciones, mdulos de desarrollo concretos e incluso, a veces, el cdigo fuente. No obstante, la informacin sobre la implementacin de videojuegos es mnima, en algunos casos se limita a algn fichero cabecera, algn API o cierta informacin sobre las primitivas utilizadas. En cualquier caso, esta informacin, adems de ser escasa, se suele limitar a la parte grafica del juego. Solo en contadas ocasiones se dispone del cdigo del juego para poder estudiar como se gestionan los eventos del sistema. La mayor parte de la investigacin en el campo de los videojuegos se lleva a cabo en las compaas desarrolladoras de juegos. La investigacin que se ha llevado a cabo en las universidades y centros de investigacin se centra en aspectos como visualizacin o en la aplicacin de tcnicas de inteligencia artificial para la gestin del comportamiento de los personajes, siendo el modelo de simulacin algo implcito, a lo que no se ha prestado mucha importancia. Existen numerosos juegos con cdigo abierto. La mayor parte de ellos corresponde a pequeos juegos creados por aficionados y que no pueden considerarse como motores de videojuegos. Muy pocos son los videojuegos complejos (habitualmente comerciales) con cdigo publicado. Dentro de estos se han elegido como base del estudio los videojuegos Doom y Quake por las siguientes razones: Son juegos de cdigo libre. Ciertas versiones de Doom y Quake tienen el cdigo liberado, disponible para su predistribucin y modificacin bajo licencia GNU. Su cdigo esta completamente liberado. En otros videojuegos de cdigo libre, ciertas partes del cdigo son bibliotecas de cdigo cerrado, pueden usarse pero no modificarse (como Serious Sam o Unreal Tournament ). Doom y Quake marcaron un hito en la historia de los videojuegos y son ampliamente conocidos y utilizados. Despiertan inters 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 creacin de otros videojuegos fue Doom. El autor de Doom mejoro e incorporo caractersticas 3D a este motor, creando Quake, que a su vez sirvi tambin para la creacin de nuevos videojuegos. Adems, se ha incluido en el estudio el videojuego Unreal Tournament, porque a pesar de no tener el cdigo liberado, despierta un gran inters en la comunidad cientfica.

2.1.6.3.1 Doom
Doom es un juego de laberintos en primera persona creado por John Carmack en 1993. Es un

juego 2D, aunque simula cierta profundidad. La nica versin del juego liberada es la v1.1 para Linux (Idsw). Utiliza como entidades bsicas 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 informacin sobre la parte fsica de la entidad, como posicin de la entidad o tipo. Las entidades no incluyen informacin sobre los eventos del sistema.

43

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 cuando suceda el evento. Los eventos se ejecutan comenzando por la cabeza de la lista hasta alcanzar la cola, ejecutando para cada evento las acciones asociadas. Los eventos no tienen tiempos asociados, se ejecutan todos y en el orden en que aparecen en la lista. La lista de eventos se recorre desde la cabeza hasta la cola. Todos los eventos son evolucionados obligatoriamente a la mxima velocidad que el sistema pueda obtener. El sistema analiza desde el ltimo estado, cual es el nuevo estado en el que se debe encontrar el sistema en funcin del tiempo transcurrido. Este esquema de simulacin obliga a que un objeto nunca pueda programar eventos situados a varios intervalos de muestreo. Por ejemplo, en Doom no existe la bomba de relojera. Para que una granada estalle, esta debe ser disparada y estallara cuando colisione con el suelo, una pared u otro personaje. La gestin de eventos discretos debe realizarse de forma explcita por el programador al margen del ncleo del videojuego y cada objeto debe gestionarla de forma independiente. La ordenacin de los eventos en la lista no es cronolgica sino que depender del orden en que se gestione el sistema. La insercin de nuevos eventos se realiza en cabeza de la lista, por ello, los nuevos eventos se trataran siempre en el siguiente ciclo, independientemente de que algn evento corresponda al ciclo actual. Cualquier evento que se produzca con una frecuencia superior a la frecuencia de muestreo, es sencillamente obviado.

Figura 2-16. Captura del juego Doom 3.

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 versin objeto de este estudio ha sido la v2.3. El elemento bsico de Quake para la gestin 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 esttico por el que se mueven los personajes. En la entidad confluyen una serie de propiedades fsicas y otras propiedades que determinan sus reglas de comportamiento. Al comportamiento de las entidades se le denomina dentro del juego inteligencia artificial, aunque no utilicen tcnicas propiamente de inteligencia artificial. La inteligencia artificial utiliza tres propiedades de la entidad para gestionar los eventos: Tiempo en el que debe suceder el siguiente evento relacionado con la entidad, momento en el que cambiara de algn modo su comportamiento. Funcin que define el comportamiento justo antes de modificar fsicamente la entidad (como moverla o hacer que dispare). Funcin que define el comportamiento de la entidad despus de modificar su parte fsica.

La descripcin de la escena esta constituida por un vector de entidades. El vector se recorre en orden, comenzando por la entidad world (primera posicin del vector), y se comprueba si cada

44

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

una de las entidades tiene que modificar su comportamiento en el instante actual, comprobando si el tiempo asociado al evento vencer en el prximo intervalo de tiempo. Este intervalo lo predefine el programador.

2.1.6.3.3 Unreal Tournament


Unreal Tournament es un motor grafico comercial desarrollado por la empresa Epic Games, altamente modular y orientado a objetos. Es multijugador, basado en arquitectura 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 cdigo fuente, a las herramientas y juegos. Cierto cdigo y las libreras del ncleo estn disponibles gratuitamente. Para trabajos y desarrollos que hagan uso del motor grafico sin tratar modificar el ncleo (como son los desarrollos y proyectos de inteligencia artificial e interfaces) el motor es una herramienta posible, por lo que se utiliza ampliamente en investigacin (Gamebots o CaveUT). Utiliza el sistema DSG (Dynamic Scene Graph Technology) que es una extensin natural del renderizado en portales, interpolacin de meshes, radiosidad, arboles BSP, LOD, superficies curvas y superficies reflectantes. Incorpora luces multicolores, dinmicas, lightmaps, raytracing y enveloped lighting. Soporta el formato DXF. Incorpora texture mapping, mapas de sombras, mapas de niebla, textura detallada para definir objetos muy detallados, texturas procedurales, texturas en tiempo real de ondas, 12 niveles de mipmapping, animacin de texturas, texturas procedurales, dinmicas y multitextura. De entre otros detalles destacamos: deteccin de colisiones cilndrica, superficies curvas con LOD, mapas de entorno, inteligencia artificial avanzada, sistema fsico 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 lgica 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

El desarrollo de juegos y herramientas que hacen uso del editor de mapas UnrealED. La orientacin a objetos de Unreal permite aadir nuevos objetos y funcionalidades una vez terminado el desarrollo. La maquina virtual de Unreal esta compuesta de: servidor, cliente, motor de visualizacin y motor de soporte de cdigo. El servidor controla el juego y las interacciones entre los jugadores y 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. El bucle de actualizacin sigue los siguientes pasos: 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 enva al servidor la peticin de movimiento. El servidor le contesta con el nuevo estado del juego. El cliente comienza el proceso de visualizacin de su escena. 3. El cliente realiza la operacin de actualizacion (Tick()) del estado del juego, tomando en consideracin el tiempo desde la ultima actualizacin (ultima llamada a la funcin Tick()). Para gestionar el tiempo, Unreal divide cada segundo del juego en ticks. El estado del videojuego se actualiza con cada tick. Un tick es la menor unidad de tiempo con la cual el actor puede ser actualizado. Normalmente la frecuencia de ticks suele estar entre 10 y 100 veces por segundo, aunque este valor depende de la potencia de la CPU. Las funciones que necesitan mas de un tick para su ejecucin se llaman funciones latentes (como Sleep, FisnishAnim o MoveTo). Mientras un actor esta ejecutando una funcin latente, la ejecucin del actor se paraliza hasta que termina de ejecutarse. Sin embargo, otros actores o la maquina virtual puede seguir ejecutndose. Cada actor tiene su propio hilo de ejecucin. Pero, estos hilos son virtuales. Unreal simula la utilizacin de hilos. Los scripts se ejecutan en paralelo. En la operacin de actualizacin de los actores, se les informa de los eventos pendientes, ejecutando el cdigo del script asociado. Todo el cdigo asociado a la actualizacin de los actores se disea para que el tiempo que ha pasado desde la ultima actualizacin pueda ser variable (igual que en Fly3D, pero diferente a Doom y Quake, quienes actualizan el sistema suponiendo que el intervalo desde la ultima actualizacin es fijo). La clase Actor es la clase padre de todos los objetos de un juego en Unreal. La clase Actor contiene todas las funcionalidades necesarias para que el actor se mueva, interacciones con otros actores, afecte al entorno y se relacione con los objetos del juego. Pawn es la clase padre de todas las criaturas y jugadores en Unreal, las cuales son capaces de tener un control a alto nivel definido por su inteligencia artificial o por el control del jugador.

2.1.6.3.4 Source Engine


Source Engine (oficialmente Valve Source Engine) es un motor 3D de videojuego desarrollado por Valve Corporation. Entre sus caractersticas cabe destacar su alto grado de modularidad y flexibilidad, renderer con shaders, tecnologa de expresin facial, y un eficiente sistema fsico en red. Source soporta tanto entornos de 32 bit como 64 bit y plataformas Microsoft Windows, Xbox, Xbox 360 y Playstation 3. Debut en noviembre de 2004 con Half Life 2 y Counter-Strike: Source.

46

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Source est diseado ascendentemente para ser altamente modular. Esto permite una fcil actualizacin y modificacin de ciertos aspectos sin tener que romper otras reas del motor, o romper la continuidad del motor. Una de las tecnologas desarrolladas para la versin de Xbox de Half Life 2 fue el File Streaming, consistente 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 carga a tan solo 15 segundos. Este sistema era una expansin del sistema de cacheado, ya implementado. Source Engine utiliza un sistema de cacheado, a travs del cual la carga de ciertos recursos est manejada y administrada al vuelo, en lugar de una nica operacin mediante la tpica pantalla de carga. Los datos de texturas y sonidos son las principales reas donde esto ocurre. Las texturas se cargan en memoria, pero solo se mueven a la tarjeta grafica del sistema cuando son necesarias, y los ficheros de sonido son cargados con un inusual sistema de cacheado de sonido: solo los primeros 0.125 segundos de cada fichero son pre-cacheados.

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

Ambos sistemas mantienen los datos en la pila hasta que no hay ms espacio y los recursos antiguos se liberan, y cuando est atascado o ralentizado, el motor se queda parado o entra en un bucle hasta que los datos llegan. El resultado de estas pausas es una especie de molesto tartamudeo del juego. Mientras que este tartamudeo puede ser causado por un mal rendimiento del sistema, se ha observado tambin en algunas configuraciones de hardware que deberan ser lo suficiente potentes para manejar esta tasa de datos, y a pesar de muchas teoras , la causa precisa continua siendo desconocida al publico, incluso dos aos despus del debut del motor. La mayor parte de

47

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

las soluciones encontradas apuntan a evitar el sistema de cacheado, ya que no puede ser deshabilitado directamente. En Febrero de 2006, se introdujeron unos cambios en el motor Source, con el objetivo de reducir el problema. Esta actualizacin se caracteriz por una implementacin limitada del sistema de file streaming, y la respuesta fue bastante positiva. Renderer Shaders versin 2.0, bump mapping, LOD sobre modelos y el mundo. Author Shaders con HLSL. Cube mapping y enviroment mapping. Luces dinmicas, vertex lighting y light maps, muchos tipos de luces incluyendo parpadeantes, de pulso, etc. Iluminacin de alto rango dinmico. Agua con refraccin y efectos. Avanzado sistema de partculas que puede emitir sprites o modelos. Proyeccin de sombras permisible por gran numero de personajes por escena. Entornos abiertos/cerrados. o Terreno deformable. o Materiales dinmicamente renderizados (csped, rboles). Superficies de subdivisin, bump maps difuso y especular. Iluminacin por radiosidad en tiempo real. Efectos de partculas, destellos, humo, rayos, sangre, y efectos ambientales como niebla o lluvia. Escalabilidad.

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 material especifica como se romper un objeto al ser golpeado, como sonar al romperse o al ser arrojado sobre otra superficie, y cual es la masa y la flotabilidad de este objeto. Este sistema es mucho ms flexible que cualquier otro sistema basado nicamente en texturas. Los materiales pueden interactuar con objetos o NPCs como barro o hielo sobre vehculos.

Personajes Personajes detallados. Ojos realistas. o Enfocado automtico 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 animacin basado en esqueletos. El sistema de animacin basado en capas puede sintetizar complejas animaciones de varias partes.

Fsica

48

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Mundo ms receptivo con interacciones realistas. Sonidos y grficos enlazados con la fsica. La IA de los personajes puede interactuar con los objetos simulados fsicamente. Cuerdas/cables, maquinas, sistemas de restriccin. Controladores de procedimientos fsico personalizados. Vehculos. o Las ruedas resbalan y patinan. o Suspensin realista en cada rueda. o Inclinacin realista en aceleraciones/deceleraciones y giros. o Parmetros configurables individualmente tales como caballos de potencia, velocidad, aceleracin, material de los neumticos, friccin de los neumticos, tensin de la amortiguacin, etc.

Programacin Todo el cdigo est escrito en C/C++ usando Visual Studio 6.0. Se pueden derivar nuevas entidades de manera fcil y rpida desde las clases base existentes. Sistema de monitorizacin interno. Herramientas de medida del rendimiento grfico. El diseo modular del cdigo (mediante DLLs) permite intercambiar componentes del ncleo para una fcil actualizacin o reemplazamiento de cdigo. Shaders de DirectX9 escritos en HLSL. Exportadores XSI, Max y Maya .smd para exportar modelos 3D.

2.1.7 Editores 3D
El proceso de creacin de grficos 3D por computador puede ser dividido en estas tres fases bsicas: Modelado Composicin de la escena Rnder (creacin de la imagen final)

Modelado La etapa de modelado consiste en ir dando forma a objetos individuales que luego sern usados en la escena. Existen diversas tcnicas de modelado; Constructive Solid Geometry, modelado con NURBS y modelado poligonal son algunos ejemplos. Los procesos de modelado puede incluir la edicin de la superficie del objeto o las propiedades del material (por ejemplo, color, luminosidad, difusin, especularidad, caractersticas de reflexin, transparencia u opacidad, o el ndice de refraccin), agregar texturas, mapas de relieve (bump-maps) y otras caractersticas. El proceso de modelado puede incluir algunas actividades relacionadas con la preparacin del modelo 3D para su posterior animacin. 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 ayuda al proceso de animacin, en el cual el movimiento del esqueleto automticamente afectara las porciones correspondientes del modelo. Vase tambin animacin por Cinemtica Directa (Forward Kinematic animation) y animacin por Cinemtica Inversa (Inverse Kinematic animation). El modelado puede ser realizado por programas dedicados (como Lightwave 3D, Rhinoceros 3D o Moray), un componente de una aplicacin (Shaper, Lofter en 3D Studio) o por un lenguaje de descripcin de escenas (como en POV-Ray). En algunos casos, no hay una distincin estricta 49

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

entre estas fases; en dichos casos, el modelado es slo una parte del proceso de creacin de escenas (por ejemplo, con Caligari trueSpace).

Composicin de la escena Esta etapa involucra la distribucin de objetos, luces, cmaras y otras entidades en una escena que ser utilizada para producir una imagen esttica o una animacin. Si se utiliza para Animacin, esta fase, en general, hace uso de una tcnica llamada Keyframing, que facilita la creacin de movimientos complicados en la escena. Con la ayuda de la tcnica de keyframing, en lugar de tener que corregir la posicin de un objeto, su rotacin o tamao en cada cuadro de la animacin, solo se necesita marcar algunos cuadros clave (keyframes). Los cuadros entre keyframes son generados automticamente, lo que se conoce como 'Interpolacin'. La iluminacin es un aspecto importante de la composicin de la escena. Como en la realidad, la iluminacin es un factor importante que contribuye al resultado esttico y a la calidad visual del trabajo terminado. Por eso, puede ser un arte difcil de dominar. Los efectos de iluminacin pueden contribuir en gran medida al humor y la respuesta emocional generada por la escena, algo que es bien conocido por fotgrafos y tcnicos de iluminacin teatral. Renderizado Se llama Render al proceso final de generar la imagen 2D o animacin a partir de la escena creada. Esto puede ser comparado a tomar una foto o en el caso de la animacin, a filmar una escena de la vida real. Generalmente se buscan imgenes de calidad fotorrealista, y para este fin se han desarrollado muchos mtodos especiales. Las tcnicas van desde las ms sencillas, como el rnder de alambre (wireframe rendering), pasando por el rnder basado en polgonos, hasta las tcnicas ms modernas como el Scanline Rendering, el Raytracing, la radiosidad o el Mapeado de fotones. El software de rnder puede simular efectos cinematogrficos 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 mecnicas de la fotografa fsica, pero como el ojo humano est acostumbrado a su presencia, la simulacin de dichos efectos aportan un elemento de realismo a la escena. Se han desarrollado tcnicas con el propsito de simular otros efectos de origen natural, como la interaccin de la luz con la atmsfera o el humo. Ejemplos de estas tcnicas incluyen los sistemas de partculas que pueden simular lluvia, humo o fuego, el muestreo volumtrico para simular niebla, polvo y otros efectos atmosfricos, y las custicas para simular el efecto de la luz al atravesar superficies refractantes. El proceso de rnder necesita una gran capacidad de clculo, pues requiere simular gran cantidad de procesos fsicos complejos. La capacidad de clculo se ha incrementado rpidamente a travs de los aos, permitiendo un grado superior de realismo en los rnders. Estudios de cine que producen animaciones generadas por ordenador hacen uso, en general, de lo que se conoce como render farm (granja de rnder) para acelerar la produccin de fotogramas. A pesar de haber muchos paquetes de modelado y animacin 3D, solo nombraremos los ms importantes, o aquellos que as lo requieran por su similitud o relacin con el actual proyecto.

50

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.1.7.1 Maya
Maya es la culminacin de 3 lneas de software 3D: Wavefront's The Advanced Visualizer (en California), Thomson Digital Image Explore (en Francia) y Alias Power Animator (en Canad). En 1993 Wavefront adquiri TDI, y en 1995 Silicon Graphics Incorporated (SGI) adquiri Alias y Wavefront(debido a la presin de Microsoft por adquirir Softimage ese mismo ao) y las combin en una sola compaa, produciendo un nico paquete de sus dos fuentes. A mediados de los 90, la pipeline ms popular en las pelculas de Hollywood era una combinacin de herramientas: Alias Studio para el modelado, Softimage para la animacin y Photorealistic RenderMan para el rendering. Esta combinacin se us en numerosas pelculas, tales como Jurassic Park, The Abyss y Terminator 2: El juicio final. A la compaa resultante de combinar Alias y Wavefront le llev mas de dos aos lanzar Maya. Maya es un paquete de modelado 3D, creado originalmente por Alias Systems Corporation, pero adquirido actualmente por Autodesk bajo su divisin Media and Entertainment. Autodesk adquiri el software en Octubre de 2005 tras adquirir Alias. Normalmente se usa en la industria cinematogrfica y de la TV, as como en los videojuegos. Maya, es usado en la mayor parte de las pelculas de hoy da. Esta disponible en dos versiones Maya Complete (el paquete menos potente) y Maya Unlimited. Maya Unlimited tiene hoy en da un precio similar a cualquier otro paquete 3D, pero sola ser considerablemente ms caro. Maya Personal Learning Edition (PLE) est disponible para uso no comercial, totalmente gratuito. Las imgenes generadas por esta versin contienen una marca de agua. Maya fue desarrollado por Alias y lanzado para Microsoft Windows, Linux, IRIX, y Mac OS X. La ultima versin de Maya, versin 8.0, fue lanzada en agosto de 2006. La versin 6.5 fue la ltima versin que soport IRIX, debido a la cada de popularidad de dicha plataforma en los ltimos aos. En la adquisicin, la preocupacin de los usuarios de Maya era si Autodesk fusionara Maya con su software 3D Studio Max, creando alguna especie de hbrido llamado Mayax. En subsecuentes entrevistas se clarific que se mantendran separados : Maya para soluciones 3D de alta fidelidad, y max para baja fidelidad. La adquisicin se complet en Enero de 2006.

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

51

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

La caracterstica mas importante de Maya es su posibilidad de software de terceros, que puede hacer que cambien su apariencia estndar y, usando solo el ncleo de Maya, puede transformarlo en un software altamente personalizable. Aparte de su intrnseca potencia y flexibilidad, esta caracterstica en s ha hecho que Maya atraiga a grandes estudios que tienden bastante a escribir cdigo personalizado para sus producciones usando el SDK proporcionado. Tambin cabe destacar de Maya su lenguaje de Script potente e independiente de la plataforma llamado Maya Embedded Language (MEL), similar a Tcl. No se proporciona nicamente como lenguaje Script, sino tambin para personalizar la funcionalidad de su ncleo (muchos de los entornos de Maya y herramientas estn escritas en este lenguaje). Adicionalmente, las interacciones de usuario estn implementadas y guardadas como scripts MEL, que los usuarios pueden ver y arrastrar a una barra de herramientas donde pueden crear nuevas macros instantneamente. Esto proporciona a los animadores el poder de aadir funcionalidad a Maya sin tener experiencia en programacin C o C++ ni sus compiladores, aunque esta opcin est incluida con el SDK. Los ficheros, que incluyen todos los datos de geometra, se guardan como secuencias de operaciones MEL, que pueden ser guardados opcionalmente como ficheros legibles (.ma, para Maya ASCII), editables en cualquier fichero de texto externo al entorno Maya, y permite un tremendo nivel de flexibilidad al trabajar con herramientas externas. Tambin pueden ser editados para permitir al fichero ser abierto por versiones anteriores del software. Caractersticas de modelado: NURBS. Modelado Poligonal. SubDivision Surface Modeling. Es una manera sencilla de crear objetos complicados tales como manos humanas. Combina las mejores caractersticas de las nurbs con el modelado poligonal. Subdivision surfaces permite usar una sola superficie para modelar formas complejas. Una nica superficie de subdivisin puede tener diferentes niveles de detalles en sus diferentes regiones. Esto es, una regin que tiene una forma compleja puede tener mas puntos de control para permitir un mayor detalle, mientras que una regin simple o plana necesita muchos menos puntos de control. Ventajas de las Subdivision Surfaces : o Permiten mayor nivel de control sobre formas que sobre polgonos. o Permiten usar geometra compleja nicamente en las regiones complejas del modelo. o Permiten pliegues y topologa arbitraria. o La continuidad de las Subdivision Surfaces elimina muchos de los problemas que pueden ocurrir en las uniones al animar usando NURBS. o Se pueden enlazar Subdivision Surfaces a esqueletos en nivel grueso y los efectos se traducirn suavemente a los niveles ms finos.

Caractersticas de animacin, configuracin de personajes y deformadores: Animacin basada en Keyframes (Fotogramas clave) o Animacin no lineal. Tras animar un personaje con Keyframes o motion Capture, se puede muestrear su animacin en una secuencia editable llamada clip de animacin. o Animacin de camino (Path Animation). Este tipo de animacin controla la posicin y rotacin de un objeto a lo largo de una curva. Se debe de asociar el objeto a la curva. Animacin de captura de movimiento.

52

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

o o

o o

Animacin 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 lo hace con el cuerpo humano. Tal como en el cuerpo humano, la ubicacin de las uniones (joints) y el nmero de uniones a aadir al esqueleto determina como se mover el modelo. Cuando se enlaza un modelo a un esqueleto, se le denomina Skinning. Existen varios mtodos de animacin: Cinemtica Directa Cinemtica Inversa Full body IK Solver Skinning. Es el proceso de configurar un personaje o modelo de manera que pueda ser deformado por un esqueleto. Restricciones. Posibilitan aadir restricciones a la posicin, orientacin o escalado de un objeto respecto de otros. Adems, con restricciones se pueden imponer lmites especficos a los objetos y automatizar el proceso de animacin. Character Sets. Es un nodo que contiene un conjunto de atributos que se pueden aplicar a distintos objetos a los que quieras aplicar la misma animacin. Deformers. Son herramientas de alto nivel que se pueden usar para manipular (al modelar) o llevar (al animar) los componentes de bajo nivel de cierta geometra. Los Deformers, son conocidos en otro tipo de paquetes como Modifiers.

Caractersticas sobre dinmica y simulacin: Partculas: se pueden animar y visualizar movimiento de partculas con varias tcnicas. Campos: el movimiento de fuerzas naturales se puede simular con campos dinmicos. Simulacin de Cuerpo Blando: se puede recrear un objeto geomtrico como un objeto flexible llamado cuerpo blando. Simulacin de Cuerpo Rgido: un cuerpo rgido es una superficie poligonal o NURBS convertida en una forma. A diferencia de las superficies convencionales, los cuerpos rgidos colisionan entre si en lugar de atravesarse durante una animacin. Para animar un cuerpo rgido, se usan campos, claves, expresiones, restricciones de cuerpo rgido, o colisiones con partculas. Efectos: Lo efectos en Maya son mdulos que facilitan crear efectos de animacin complejos tales como humo o fuego. Cada efecto de Maya ofrece gran nmero de opciones y atributos para modificar los resultados. Caractersticas de rendering : Shading(sombreado): en Maya, la apariencia de una superficie est definida por como est sombreada. El sombreado de una superficie es una combinacin del material bsico de un objeto y las texturas aplicadas al mismo. En Maya, los materiales (tambin llamados Shaders), definen la sustancia del objeto. Algunos de los atributos ms bsicos de materiales incluyen color, transparencia y brillo. Toon Shading: da una apariencia 2D o de animacin cartoon usando modelos 3D. Iluminacion: en el mundo real, cuando la luz brilla sobre una superficie, las partes de la superficie que estn 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 partculas en una superficie 2D o sobre geometra 3D en el entorno 3D. Mental Ray : Mental Ray renderer. RenderMan for Maya : Renderer de Pixar para Maya.

53

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Caractersticas adicionales de la versin Unlimited : Maya Fluid : simulador de fluidos, efectos atmosfricos, pirotcnicos, de viscosidad y ocenicos. Maya Cloth: Simulacin de ropa y telas, cualquier objeto textil, incluidas velas, forros, tiendas, cortinas y ropa de cama. Usado el la pelcula Spiderman 2. Maya Fur: Simulacin de piel animal, vello, lana y hierba en superficies NURBS, de subdivisin o modelos poligonales. Maya Hair: Simulacin para cabello humano, cabellos totalmente dinmicos en objetos poligonales y NURBS. Maya Live: Combina la accin en vivo 2D con elementos 3D. Proporciona un secuenciador 2D integrado y un solver de fotograma raz interactivo. Tambin permite reconstruir elementos de grabaciones en vivo como geometra 3D, adems de generar la salida 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 sucesor de 3D Studio para DOS, pero para la plataforma Win32. Ms tarde Kinetix se fusion con la ltima adquisicin de Autodesk, Discreet Logic. Actualmente, en su 8 versin en Junio de 2006. El 3D Studio original fue creado por Yost Group y publicado por Autodesk. 3D Studio Max fue tambin originalmente creado por Yost Group. Autodesk adquiri el producto en su segunda publicacin e interiorizo su desarrollo completamente durante las dos siguientes publicaciones. 3ds Max es uno de los programas de animacin 3D mas usados. Tiene gran capacidad de modelado y una potente arquitectura de plugins. Esta usado ampliamente por desarrolladores de videojuegos, pero puede ser tambin usado para producciones pre-renderizadas tales como pelculas, efectos especiales y presentaciones arquitectnicas. Aparte de sus herramientas de modelado y animacin, la ultima versin de 3ds Max tambin incluye shaders (tales como ambient occlusion y subsurface scattering), simulacin dinmica, sistema de partculas, radiosidad, creacin y render de normal map, iluminacin global, un interfaz intuitivo y totalmente personalizable, su propio lenguaje de Script (MaxScript) y mucho ms. Tambin existen cantidad de plugins especializados que pueden ser comprados por separado, tales como Brazil r/s y FinalRender. El modelado de polgonos es mucho mas comn en el diseo de juegos que en cualquier otra tcnica de modelado, ya que el control muy especifico sobre polgonos de manera individual permite una mxima optimizacin. Tambin es relativamente ms rpido de calcular en tiempo real. Normalmente, el modelador comienza con una primitiva, y haciendo uso de herramientas como bevel, extrudo y corte de polgonos, aade detalles y refina el modelo.

54

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

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

3ds Max venia normalmente con distintos emisores de partculas. Como en su version 8, existen 6 emisores de partculas bsicos, mostrando comportamientos especficos. Los emisores de partculas tradicionales son Spray, Nieve, Ventisca, PArray, PCloud, y Super Spray. Particle Flow es un sistema de partculas sofisticado, no lineal, basado en eventos, desarrollado por Oleg Bayborodin como uno de los siete emisores de partculas de MAX. A diferencia de la mayoria de sistemas de partculas disponibles en los paquetes 3D, Particle Flow permite al usuario disear el comportamiento de la partcula basado en una serie de eventos definidos por el usuario (Procedimientos), usando un GUI intuitivo. 3ds Max incluye un motor fsico, llamado Reactor, originalmente creado por Havok. Reactor puede simular cuerpos rigidos, cuerpos blandos, ropa, gravedad, y otras fuerzas. Como muchos motores fsicos, Reactor utiliza un envoltorio convexo simplificado, pero puede ser personalizado para usar todos los vrtices. Existen varios renderers para generar imgenes, estos son: Scanline rendering. Es el renderer por defecto. Es bastante robusto, soporta iluminacin global, radiosidad y ray tracing. 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, con bucket rendering (similar al Satelling Rendering de Maya) que distribuye la carga del render entre distintas maquinas mas eficientemente. Mental Ray tambin viene con cantidad de herramientas que permiten gran nmero de efectos para ser creados con relativa facilidad. RenderMan. Herramienta de conexin a la pipeline Renderman para aquellos que necesiten integrar Max con renders de Renderman.

55

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.1.7.3 LightWave 3D
LightWave 3D es un programa para el modelado 3D, render y animacin. Aunque el programa se origin en el Commodore Amiga, ha sido migrado para funcionar en Mac OS X, Windows, Sgi IRIX, y el motor de render tambin ha sido portado a Linux. Actualmente desarrollado completamente por NewTek. LightWave ha sido durante tiempo bien conocido por su excelente capacidad para el render y su inusual interfaz de usuario (por ejemplo, no se usan iconos; en su lugar se usan funciones con su titulo descriptivo). Como muchos otros paquetes 3D, Lightwave est compuesto por dos partes, un entorno de modelado de objetos donde los modelos o las mallas se crean y un entorno de animacin donde los modelos se preparan y animan para el render. A diferencia de otros paquetes, estas dos partes son programas independientes. Tambin existe una aplicacin independiente para el render, que puede ser ejecutada en mltiples mquinas. 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 caractersticas de LightWave usando un SDK que se incluye con el paquete, as como un lenguaje especial de Script llamado LScript. Este SDK est basado en el lenguaje C, y se puede crear casi cualquier cosa, desde un shader personalizado hasta distintos formatos de exportadores de escena. LightWave en si incluye docenas de plugins gratuitos y se pueden obtener muchos mas de distintos desarrolladores de todo el mundo. En 1988, Allen Hastings cre un programa de render y animacin llamado Videoscape, y su amigo Stuart Ferguson cre un programa de modelado 3D complementario llamado Aegis Modeler. Estos dos programas seran lo que actualmente se conoce como LightWave 3D. Newtek planeaba incorporar Videoscape y Aegis en su paquete de edicin de video, Video Toaster. Segn Hastings, Newtek pretenda 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: Intelligent Light 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

LightWave 3D ha estado disponible como una aplicacin independiente desde 1994, y la version 9.0 ahora corre bajo Max OS X y cualquier PC con Windows. LightWave gan fama como el programa usado para crear efectos especiales para las series de ciencia ficcion Babylon 5 y Seaquest DSV; El programa tambin se utiliz en la produccin de pelculas como Titanic, y las recientes Sin City y Star Wars. En 2001, se origin un problema entre el mantenimiento de NewTek y un grupo dirigido por el videpresidente de desarrollo 3D, Brad Peebler, entre los que figuraban desarrolladores como Allen Hastings o Stuart Ferguson. Por segunda vez en su historia NewTek sufri un importante abandono de ingenieros y programadores. Tras meses de confusin, este grupo form una nueva compaa, Luxology. Fue entonces cuando lanzaron su propio paquete 3D, Modo. NewTek y LightWave has sido galardonados con premios Emmy desde 1993 y ganaron sus 10 y 11 galardones en 2004. En 2003 NewTek fue galardonado con un Emmy por la tecnologa que tuvo mayor impacto en televisin. Ahora en su novena versin, su mercado abarca desde los aficionados (dado su bajo precio), hasta el desarrollo de alto nivel como videojuegos, televisin y cine. La compaa recientemente lanz su versin para 64 bit de LightWave 3D. Esta versin incluye nuevas caractersticas como un editor se superficie basado en nodos Subdivision Adaptativa de Pixel (APS) que permite a la malla variar su complejidad dependiendo de los criterios definidos por el usuario, incluyendo la distancia a la cmara, maximizando la eficiencia de render.

2.1.7.4 SoftImage XSI


El contrincante ms grande de Maya. En 1987, Softimage Inc, una compaa situada en Montreal, escribi Softimage 3D, que se convirti rpidamente en el programa de 3D ms popular de ese perodo. En 1994, Microsoft compr Softimage Inc. y comenzaron a reescribir Softimage 3D para Windows NT. El resultado se llam Softimage XSI. En 1998 Microsoft vendi Softimage a Avid. La versin a mediados del 2003 era la 3.5.
Figura 2-23. Imagen generada por el programa SoftImage XSI.

2.1.7.5 Multigen Creator


Multigen 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. Creador est diseado para construir bases de datos 3D en tiempo real. No existen comandos ni lenguaje de Script; Tan solo una estructura de base de datos jerarquizada controlada completamente a travs de un interfaz visual. Los usuarios controlan las estructuras de los objetos 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 opcin Terrain permite a los usuarios convertir datos USGS DEM y NGA DTED a una superficie de terreno, usando triangulacin de Delaunay en una proyeccin plana de la superficie. Las herramientas incluyen controles para mltiples LOD, criterio de concordancia de

57

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

bordes, etc. Tiene capacidad para detectar lneas de costa, cabos, y valles para una representacin exacta y eficiente. Las herramientas de mapeado de texturas (Texture Mapping) posibilitan a los usuarios a aplicar colores, texturas y materiales de manera automtica e interactiva. El editor de texturas esta integrado con una Paleta personalizable. Durante el proceso de construccin de la base de datos se mantiene doble precisin interna. La opcin Terrain es compatible con las herramientas Poblar y Dispersar (Poblate and Scatter), que permiten a los usuarios colocar modelos de manera aleatoria y automtica sobre el terreno. Creador puede importar ficheros DXF, 3Ds y OBJ. Para abrir ficheros SHP en Creador, el usuario tiene tres opciones: Usar la API OpenFlight para escribir un conversor propio; Usar Multigen Paradigms SiteBuilder3D para trabajar con los datos en ArcView, y luego exportarlos a OpenFlight; Usar el software FME para convertir ficheros SHP a DFD. Creator incluye FlightViewer, un plug-in para previsualizacion. FlightViewer posibilita el modo de vuelo en tiempo real o modo de rotacin, visualiza modelos con texturas, materiales, luces y sombras, carga de puntos de vista guardados en Creador ,vista en diferentes modos (wireframe, solido y puntos), actualizacin constante de la estadsticas de render, tales como tringulos por segundo o fotogramas por segundo (FPS). Los productos Multigen-Paradigm estn siendo usados para proporcionar una base de datos 3D en tiempo real en un proyecto de una autopista de California. Creador se usa para modelado 3D, RoadPro se usa para construir carreteras en 3D, y Vega se usa para realizar aplicaciones de visualizacin 3D interactivas. Creador tambin se ha usado para desarrollar un modelo 3D del desarrollo de proyecto de lnea de costa en Vallejo, CA. El modelo inclua tiendas, hoteles, terreno y calles. MultiGen-Paradigms Urban Simulation Services Group entreg un modelo 3D en tiempo real para el Centennial Center a la ciudad de Las Vegas. La base de datos 3D comprenda 160 acres y fue hecha a partir de planos, datos de elevaciones, imgenes digitales y datos de sistemas de informacin geogrfica (GIS). Sitebuilder 3D se uso para convertir mapas digitales 3D y fotografas areas 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 hosting de Source Forge y el respaldo de la comunidad OpenSceneGraph (OSG). De entre sus caractersticas, debera permitir montar escenas, hacer pequeos ajustes, y ejecutar procesos tpicos de un grafo de escena. Aunque la idea evolucion en cierto modo, el desarrollo contina enfocndose en hacer un compositor de escenas, no una herramienta completa de creacin de contenidos con modelado, animacin, etc., puesto que ya existen bastantes herramientas de este tipo en el mundo. El diseo de OSGEdit ha evolucionado bastante desde su nacimiento, desde un interfaz rgido hecho completamente a mano hasta el actual, generado dinmicamente casi en su totalidad. Cada paso del diseo fue hecho con la ayuda de Ricardo Rodrguez y la contribucin de gente repartida por todo el mundo, como es usual en este tipo de proyectos de cdigo abierto.

58

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

La generacin del GUI est automatizada, ya que esta es la nica manera de soportar cualquier caracterstica de OSG en un tiempo razonable de tiempo. No obstante, esta caracterstica del interfaz se ve penalizada con un incremento de la inestabilidad del programa. La generacin automtica de la GUI se realiza utilizando una descripcin XML proporcionando meta-datos sobre las clases OSG. Los meta-datos separan los detalles OSG del interfaz de usuario, proporcionando un mecanismo genrico para conocer los atributos de cada clase, y las caractersticas 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, relacionadas con la opcin undo/redo del programa. Desde la versin 0.6.0, tanto la barra de men como la barra de herramientas se generan automticamente desde una descripcin XML. Esto reduce el coste de desarrollo al aadir nuevas herramientas al GUI, ya que no necesitar escribir, compilar y depurar cdigo fuente. Otra de las novedades de esta ultima versin es la implementacin tanto para entorno X como para Win32 utilizando la librera GTK+.
Figura 2-24. Captura del programa OSGEdit.

Caractersticas de OSGEdit : El grafo de escena se representa mediante un rbol donde se pueden seleccionar los nodos para cualquier operacin. Este rbol es realmente un grafo, un mismo nodo puede colgar de distintas ramas, aunque realmente represente un nodo compartido, no una copia. Cada tipo de nodo tiene un dialogo de propiedades integrado en la ventana (la mayora soportadas). Se pueden manipular las transformaciones visualmente, hay herramientas para mover, escalar, y rotar nodos de transformacin visualmente con el ratn. Todas las operaciones excepto new/open/save y zoom se pueden deshacer y rehacer sin lmite. Se pueden crear nodos tipo Group/Transform/Switch/LOD unicamente. Se pueden abrir todos los formatos que soporta OSG as como guardar en todos los formatos que soporta OSG. Se pueden unir ficheros, aadindolos como nodos hijo. Se pueden copiar, cortar y pegar nodos.

2.1.7.7 Valve Hammer Editor


El Valve Hammer Editor era antes conocido con el nombre de Worldcraft. Valve Hammer es el editor oficial de la empresa Valve para el juego Half-Life y todos sus mods. Es un editor gratuito, se puede descargar de cualquier pgina oficial. Con el se pueden crear mapas para Half-Life, Counter-Strike, etc... su funcionamiento es sencillo, tiene una interfaz intuitiva, y su puesta en funcionamiento es sencilla. Ahora mismo la versin oficial es la 4.0. Esta en ingls, aunque hay una versin no-oficial en espaol.

59

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Actualmente la versin oficial de este software de la desarrolladora Valve es la 4.0. Esta versin ya si es de "pago", se adquiere cuando se compra una copia original de los siguientes videojuegos: 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 compaa desarrolladora del Half-Life, Valve. Una vez registrada nuestra copia de software en dicha plataforma se nos dara la posibilidad para acceder al Kit de desarrollo de mods para el Source Engine. La herramienta se llama Source SDK (Software Development Kit) donde dispondremos de las siguientes herramientas: Valve Hammer Editor 4.0 HL2 Model Viewer HL2 Face Poser

2.1.7.8 UnrealED
UnreadED, es el software editor de niveles usado para crear niveles para Unreal, otros juegos de Unreal series , y juegos basados en el motor Unreal, como puede ser Deus Ex. Este tipo de juegos utilizan su propia versin del mismo programa. Todos los juegos Unreal en PC tenan en editor de niveles incluido de manera gratuita, y algunos otros juegos que usaban su motor hicieron lo mismo con una versin mas especifica del mismo. Esto extendi la longevidad de los juegos. Los diseadores amateur podan ahora crear contenidos adicionales para el juego. Adems, el lenguaje Script llamado UnrealScript permita a los editores personalizar el contenido del juego. UnrealED tiene un interfaz de usuario personalizable, pero lo mas comn son las cuatro vistas, con la vista superior en la parte superior izquierda, y en sentido de las agujas del reloj la vista frontal, la vista lateral, y una vista en perspectiva. Tiene una fila de botones con distintas opciones de salvado, guardado, as como para funciones de editado. Han existido varias versiones de UnrealED, la primera en aparecer fue la versin 1.0, la cual ya visualizaba la barra de herramientas con sus 4 vistas. Esta versin era extremadamente inestable, particularmente al reconstruir mapas. En la actualizacin a la versin 2.0, se mejor su aspecto visual con unos botones ms coloridos y un interfaz ms atractivo. Se aadieron nuevas herramientas y caractersticas (tales como opciones de bsqueda, y un nuevo editor de formas 2D), y experiment una actualizacin significante de escalabilidad, y aunque el editor continuaba con sus extraa inestabilidad, no lo era tanto como la versin 1.0. Junto con Unreal Tournament 2003 estaba UnrealED 3.0, mucho mas estable q los anteriores. Mantena los colores de su interfaz, y el aspecto de su versin 2.0. Al editor se aadi un navegador de mallas estticas para soportar mallas estticas, y combinado con varios navegadores en un nico navegador con pestaas para alternar entre texturas, mallas, actores, etc Esta es la versin actual de UnrealED.

Figura 2-25. Captura de UnrealED

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

60

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

personalizadas (como prismas y otros poliedros). Usando operaciones CSG (Constructive Solid Geometry), se pueden crear objetos y habitaciones complejas aadiendo, sustrayendo e intersectando brushes entre si. Los brushes aditivos pueden ser slidos, semislidos o no-slidos. UnrealED trata el mundo como una masa gigante. Para crear espacio, los brushes son sustrados de la masa, de modo que se crea un espacio hueco por donde pasar. Inversamente, la adicin de masa crea espacio slido dentro del espacio hueco. Un nivel se construye con una mezcla de suma y resta de brushes. Estos brushes se usan para compilar un nivel en un rbol BSP (Binary Space Partitioning) para render y deteccin de colisiones. Desafortunadamente, a medida que los niveles se complican, ms propensos a error son los BSP, dando como resultado errores de visualizacin y de colisiones. De aqu el uso de Mallas Estticas introducido en la versin 2.0 del motor. Las mallas estticas son geometra pre-renderizada, creada con algn software como Maya o 3D Studio Max, que puede ser importada y posicionada dentro de los niveles. Aunque los niveles se construyen con brushes, las mallas estaticas se pueden usar para crear edificios y formas complejas que los brushes tienen difcil para emular. Puesto que las mallas estticas solo se cargan en memoria una vez, aunque sean usadas mltiples veces en la escena, son una mejor forma de usar recursos. Algunos diseadores de edificios, para poder proporcionar una visita en tiempo real de sus creaciones, con gravedad y deteccin de colisiones, han comenzado a construir modelos usando UnreadED, y asi poner en practica sus ideas. Permitir al pblico visitar un edificio antes de su construccin puede desarrollar un mejor resultado previo a la construccin del mismo. El problema es la conversin de medidas desde programas de diseo tales como Autocad y 3D Studio Max a UnrealED.

2.2 Arquitectura de Plugins.


Un plugin (o plug-in) es un programa que interacta con la aplicacin principal (un navegador o un programa de correo, por ejemplo), para proporcionar una funcin especifica. Por ejemplo: Leer o editar tipos especficos de fichero (por ejemplo, ficheros multimedia). Encriptar o desencriptar emails (por ejemplo, PGP). Filtrar imgenes en programas de tratamiento de imgenes.

La aplicacin principal proporciona los servicios que permite a los plugins usar, incluyendo la manera en que los plugins se registran a s mismos en la aplicacin principal, y el protocolo por el cual los datos se intercambian con el plugin. Los plugins son dependientes de estos servicios que proporciona la aplicacin principal, y no suelen funcionar por s solos. En cambio, la aplicacin principal es independiente de los plugins, haciendo posible que los plugins se aadan o se actualicen dinmicamente sin que sea necesario hacer cambios en la aplicacin principal. Los plugins sin ligeramente diferentes de las extensiones, que modifican o aaden funcionalidad. La principal diferencia es que los plugins generalmente dependen del interfaz de usuario de la aplicacin principal, y tienen bien definidos los lmites 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 tamao de la aplicacin principal, y ofrecer funciones adicionales.

61

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Quiz el primer software en incluir la funcin 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 eran implementados como libreras compartidas, que deban instalarse en una ruta indicada en la aplicacin principal. Las APIs de cdigo abierto suelen proporcionar un interfaz estndar, permitiendo a otros desarrolladores crear plugins que interacten con la aplicacin principal. Un API estable permite que los plugins de otros desarrolladores funcionen perfectamente aunque la versin original cambie, y prolonga el ciclo de vida de las aplicaciones obsoletas. Adobe Photoshop y el API de plugins After Effects se han convertido en un estndar y se ha adoptado hasta cierto punto por aplicaciones de su competencia.

Los Plugins le dan a una aplicacin la capacidad de agregar funcionalidades nuevas en tiempo de ejecucin. De entre sus ventajas podemos destacar: Hace posible el personalizar la aplicacin de maneras no pensadas por el autor, o que al menos no tena la intencin de hacer. Da la posibilidad de difundir la responsabilidad. Mucha gente trabaja en proyectos de software abierto ya que ser autor de una pieza de cdigo les brinda cierta satisfaccin personal. Utilizando plugins, una persona puede desarrollar un plugin, y reclamar su autora. Es posible compartir cdigo entre aplicaciones sin mucho que ver entre ellas si estas comparten una infraestructura de plugins entre si. Un ejemplo seran los visores de imgenes. Existen muchos visores. Teniendo una infraestructura de plugins en comn, sera posible desarrollar plugins que funcionen en cada uno de estos visores. Finalmente, hace posible que slo cierta funcionalidad este disponible si alguna librera de o aplicacin de terceros no est disponible en el sistema.

Existen dos tipos de plugins: El primer tipo de plugins implementa una interfaz especificada por la aplicacin padre (la aplicacin principal). Esto es similar a implementar una clase virtual pura, con la excepcin de que la clase se encuentra en una biblioteca compartida cargable en tiempo de ejecucin. Este tipo de plugins tambin se les llama mdulos cargables. Ejemplos de mdulos cargables son mdulos de soporte para nuevos formatos de imgenes, destacadores de sintaxis, y mdulos para importar y/o exportar datos a diferentes formatos. Las ventajas de este tipo de plugins es que terceros fabricantes pueden aadir nuevos formatos a la aplicacin. Ej: Un editor para programadores puede destacar cdigo escrito en lenguaje VDM-SL, an cuando el autor del editor no tiene idea que ese lenguaje siquiera existe. El segundo tipo de plugins brinda nueva funcionalidad y acciones para la barra de mens y la barra de herramientas. Ejemplos para este tipo de plugins sera la clsica opcin para exportar una galera HTML desde un visor de imgenes (an cuando este no tena esta funcionalidad anteriormente), verificacin y correccin de ortografa en un editor, validacin de pginas Web en un navegador Web. La ventaja de este tipo de plugins es que nueva funcionalidad puede ser aadida por terceros, con las consecuencias descritas anteriormente.

62

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.3 Bibliotecas de enlace dinmico


DLL es el acrnimo de Dynamic Linking Library (Bibliotecas de Enlace Dinmico), trmino con el que se refiere a los archivos con cdigo ejecutable que se cargan bajo demanda del programa por parte del sistema operativo. Esta denominacin se refiere a los sistemas operativos Windows siendo la extensin con la que se identifican los ficheros, aunque el concepto existe en prcticamente todos los sistemas operativos modernos. El propsito inicial de las DLL era ahorrar tanto espacio de disco como memoria que requeran las aplicaciones, guardndolas en el disco duro. En una librera convencional no compartida, los fragmentos de cdigo se aaden tal cual al programa que la necesita. Si dos programas llaman a la misma rutina, ese cdigo estar duplicado. Por el contrario, cualquier cdigo 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 de Windows funcionar bajo condiciones ajustadas de memoria. Las DLLs proporcionan los beneficios tpicos de las libreras compartidas, tales como modularidad. La modularidad permite hacer cambios al cdigo y los datos de una DLL compartida por distintas aplicaciones sin tener q modificar ninguna de estas aplicaciones. Esta forma bsica de modularidad permite aplicar parches y service packs a grandes aplicaciones, tales como Microsoft Office, Microsoft Visual Studio, incluso el propio Microsoft Windows.

Creacin de una biblioteca de enlace dinamico A menudo es ms sencillo crear una biblioteca de enlace dinmico que crear una aplicacin. La razn es que habitualmente una DLL consta de un conjunto de funciones autnomas que pueden ser utilizadas por cualquier aplicacin. Lo normal es que en las DLLs no haya cdigo que se encargue del procesamiento de bucles de mensaje o de la creacin de ventanas. Una biblioteca de enlace dinmico es simplemente un conjunto de mdulos de cdigo fuente, cada uno de los cuales contiene un conjunto de funciones. Estas funciones se escriben con la esperanza de que les llame una aplicacin (archivo EXE) u otra DLL. Despus de compilar todos los archivos de cdigo fuente, se enlazan igual que el archivo EXE de una aplicacin. Sin embargo, para una DLL se debe especificar al enlazador la opcin /DLL. Esta opcin provoca que el enlazador genere una informacin 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 una aplicacin. Para que una aplicacin (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 implcito en tiempo de carga o con enlazado explcito en tiempo de ejecucin. Una vez se ha proyectado la imagen de un archivo DLL en el espacio de direcciones del proceso llamante, las funciones de la DLL estn disponibles para todos los hilos que se ejecutan en el proceso. De hecho, la DLL pierde casi toda su identidad como DLL: para todos los hilos del proceso, el cdigo y los datos de la DLL simplemente parecen cdigo y datos adicionales que estn en el espacio de direcciones del proceso. Cuando un hilo llama a cualquier funcin de la DLL, esta funcin toma los parmetros que le han pasado en la pila del hilo y tambin utiliza esta pila para guardar las variables locales que pudiera necesitar. Adems, el hilo o proceso llamante posee todos los objetos creados por el cdigo de las funciones de la DLL: una DLL nunca posee nada en Win32. Por ejemplo, si una funcin de una DLL llama a VirtualAlloc, la regin se reserva en el espacio de direcciones del proceso del hilo llamante. Si ms adelante se elimina la proyeccin de la DLL del espacio de direcciones del proceso, la regin del espacio de direcciones permanece

63

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

reservada porque el sistema no es consciente del hecho de que una funcin de la DLL ha reservado la regin. La regin reservada la posee el proceso y slo ser liberada si un hilo llama a la funcin VirtualFree o si termina el proceso. Como ya sabemos, las variables globales y estticas de un archivo EXE no se comparten entre los mltiples ejemplares en ejecucin del mismo EXE. Cuando un proceso proyecta una imagen de archivo DLL en su espacio de direcciones, el sistema crea tambin ejemplares de las variables globales y estticas. Existe una tcnica que permite que una DLL comparta sus variables globales y estticas entre mltiples proyecciones de la DLL. Sin embargo, esta tcnica 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 funcin 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 implcitamente las funciones de la DLL y cargando explcitamente la DLL. Enlazado implcito El enlazado implcito es el mtodo ms habitual de proyectar la imagen de un archivo DLL en el espacio de direcciones del proceso. Cuando se enlaza una aplicacin, 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 aplicacin (u otra DLL). Cuando el enlazador ve que la aplicacin llama a una funcin incluida en el archivo LIB de una DLL, incrusta informacin 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 aplicacin se ejecute. Entonces, el sistema intenta proyectar las imgenes de archivo DLL requeridas en el espacio de direcciones del proceso. Cuando busca el archivo DLL, el sistema examina los siguientes directorios: 1. 2. 3. 4. 5. El directorio que contiene la imagen del archivo EXE. El directorio actual del proceso. El directorio de sistema de Windows. El directorio de Windows. 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 mtodo, no se elimina la proyeccin de todas las imgenes de archivo DLL proyectadas en el espacio de direcciones del proceso hasta que se termina el proceso.

Enlazado explcito La imagen de un archivo DLL se puede proyectar explcitamente en el espacio de direcciones de un proceso cuando uno de los hilos del proceso llama a la funcin 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 bsqueda mencionado anteriormente) e intentan proyectar la imagen del archivo DLL

64

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

en el espacio de direcciones del proceso llamante. El valor HINSTANCE que devuelven estas funciones identifica la direccin 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 funcin LoadLibraryEx tiene dos parmetros adicionales: hFile y dwFlags. El parmetro hFile est reservado para una utilizacin futura y por el momento debe ser NULL. Para el parmetro dwFlags, se debe especificar un 0 o una combinacin de DONT_RESOLVE_DLL_REFERENCES, LOAD_LIBRARY_AS_DATAFILE y LOAD_WITH_ALTERED_SEARCH_PATH. Estos flags se tratan brevemente a continuacin. 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 funcin 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 funcin DllMain. Adems, una DLL podra importar las funciones contenidas en otra DLL. Cuando el sistema proyecta una DLL en el espacio de direcciones del proceso, el sistema tambin comprueba si la DLL requiere otras DLLs y tambin las carga automticamente. Cuando se especifica el flag DONT_RESOLVE_DLL_REFERENCES, el sistema no carga automticamente 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 ms tiempo en prepararse para ejecutar el cdigo del archivo. Por ejemplo, cuando una DLL se proyecta en el espacio de direcciones del proceso, el sistema examina la informacin de la DLL para determinar qu atributos de proteccin de pgina se deberan asignar a las diferentes secciones del archivo. Cuando no se especifica este flag, el sistema establece los atributos de proteccin de pgina como si fuese a ejecutar el cdigo de ese archivo. Este flag es til por varias razones: Si tenemos una DLL que contiene slo recursos y ninguna funcin, 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. Tambin se puede utilizar este flag si se desean utilizar recursos que estn contenidos en un archivo EXE. Normalmente, al cargar un archivo EXE se inicia un nuevo proceso, pero tambin se puede utilizar la funcin 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 funcin 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 bsqueda 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. 2. 3. 4. El directorio especificado en el parmetro lpszLibFile. El directorio actual del proceso. El directorio de sistema de Windows. El directorio de Windows.

65

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.

Los directorios enumerados en la variable de entorno PATH.

Cuando se carga explcitamente una DLL, la imagen de archivo se puede eliminar explcitamente la proyeccin del espacio de direcciones del proceso en cualquier momento llamando a la funcin 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 utilizacin asociado a la biblioteca especificada, y la funcin 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 utilizacin con un valor 1. Si un hilo del mismo proceso llama ms 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 utilizacin asociado a la DLL. Para que se elimine la proyeccin 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 utilizacin de la DLL a 1, y la segunda llamada lo decrementa a 0). Cuando el sistema ve que el contador de utilizacin de una DLL ha llegado a O, elimina la proyeccin de la imagen del archivo DLL del espacio de direcciones del proceso. Despus de eliminar la proyeccin de la imagen de archivo, si un hilo intenta llamar a una funcin de la DLL, provocar una violacin de acceso porque el cdigo de la direccin especificada ya no est proyectado en el espacio de direcciones del proceso. El sistema mantiene un contador de utilizacin de una DLL para cada proceso. Es decir, si un hilo de un Proceso A realiza la llamada
HINSTANCE hinstDll = LoadLibrary("MiLib.DLL");

y despus un hilo del Proceso B realiza la misma llamada, se proyecta MILIB.DLL en los espacios de direcciones de ambos procesos (el contador de utilizacin de la DLL en el Proceso A y en el Proceso B es 1 en ambos). Si un hilo del proceso B llama ms tarde a
FreeLibrary(hinstDll);

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

para determinar si una DLL est proyectada en el espacio de direcciones de su proceso. Por ejemplo, el cdigo siguiente carga MILIB.DLL slo si no est ya proyectada en el espacio de direcciones del proceso:
HINSTANCE hinstDll; hinstDll = GetModuleHandle("MiLib"); if (hinstDll == NULL) { hinstDll = LoadLibrary("MiLib"); } // se asume la extensin DLL // se asume la extensin DLL

66

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Tambin 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 funcin GetModuleFileName:
DWORD GetModuleFileName(HINSTANCE hinstModule, LPTSTR IpszPath, DWORD cchPath);

El primer parmetro es el HINSTANCE de la DLL (o EXE). El segundo, IpszPath, es la direccin del bfer en el que la funcin pondr el nombre de trayecto completo de la imagen de archivo. El tercer y ltimo parmetro, cchPath, especifica el tamao del bfer en caracteres. Hay otra funcin de Win32 que se puede utilizar para decrementar el contador de utilizacin 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 proyeccin de la DLL del espacio de direcciones del proceso. Para que el hilo elimine la proyeccin de la DLL debe llamar a FreeLibrary y despus 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 proyeccin de la DLL del espacio de direcciones del proceso. En el mo-ment en que vuelve la llamada a FreeLibrary, el cdigo que contiene la llamada a ExitThread ya no est disponible y el hilo no intentar ejecutar nada. Esto provocar que se lance una violacin de acceso y que termine el proceso completo! Sin embargo, si el hilo llama a FreeLibraryAndExitThread, esta funcin llama a FreeLibrary, provocando que se elimina la proyeccin de la DLL inmediatamente. La siguiente instruccin que se ejecuta se encuentra en KERNEL32.DLL, no en la DLL que se acaba de eliminar. Esto significa que el hilo puede continuar ejecutndose 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 funcin de entrada/salida. El sistema llama a esta funcin en varias ocasiones que veremos ms adelante. Estas llamadas son informativas y habitualmente son utilizadas por una DLL para realizar tareas de inicializacin y liberacin para cada proceso o cada hilo. Si la DLL no necesita estas notificaciones, no es necesario implementar esta funcin en el cdigo fuente de la DLL. Por ejemplo, si creamos una DLL que slo contiene recursos, no es necesario implementar esta funcin. Si existe esta funcin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
// Se elimina la proyeccin de la DLL del // espacio de direcciones del proceso. break; } return(TRUE); } // Slo se utiliza para DLL_PROCESS_ATTACH

El sistema operativo llama a esta funcin de entrada/salida en varios momentos. Cuando se llama a esta funcin, el parmetro hinstDll contiene el descriptor del ejemplar de la DLL. Como el parmetro hinstExe para WinMain, este valor identifica la direccin de memoria virtual en la que se proyect la imagen del archivo DLL en el espacio de direcciones del proceso. Habitualmente, se guardar este parmetro en una variable global para poder utilizarlo en las llamadas que cargan recursos, como DialogBox y LoadString. El ltimo parmetro, flmpLoad, es un valor distinto de cero si la DLL se carga implcitamente o cero si se carga explcitamente. El parmetro fdwReason indica la razn por la que el sistema llama a la funcin. Este parmetro 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 funcin DllMain de la DLL, pasando el valor DLL_PROCESS_ATTACH como parmetro fdwReason. Esto slo sucede cuando se proyecta por primera vez la imagen del archivo DLL. Si un hilo llama despus 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 utilizacin de la DLL; no llama de nuevo a la funcin DllMain de la DLL con el valor DLL_PROCESS_ATTACH. Cuando procesa DLL_PROCESS_ATTACH, una DLL debera realizar todas las inicializaciones relativas al proceso que necesiten las funciones contenidas en la DLL. Por ejemplo, la DLL podra contener funciones que tengan que utilizar su propio Heap (creado en el espacio de direcciones del proceso). La funcin DllMain de la DLL podra crear este Heap llamando a HeapCreate durante el procesamiento de la notificacin DLL_PROCESS_ATTACH. El descriptor del Heap creado se podra guardar en una variable global a la que tuviesen acceso las funciones de la DLL. Cuando DllMain est procesando la notificacin DLL_PROCESS_ATTACH, el valor de retorno de DllMain indica si la inicializacin de la DLL ha tenido xito. Por ejemplo, si la llamada a HeapCreate ha tenido xito, DllMain debera 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 algn hilo en el sistema que sea el responsable de ejecutar el cdigo de la funcin DllMain. Cuando se crea un nuevo proceso, el sistema proyecta el espacio de direcciones del proceso y despus proyecta la imagen del archivo EXE y todas las imgenes de archivo DLL requeridas en el espacio de direcciones del proceso. A continuacin, 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. Despus de que todas las DLLs proyectadas hayan respondido a esta notificacin, el sistema provoca que el hilo primario del proceso comience a ejecutar el cdigo de inicio en tiempo de ejecucin de C del EXE, seguido de la funcin WinMain del EXE. Si alguna de las funciones DllMain de DLL devuelven FALSE, indicando que la inicializacin no ha tenido xito, el sistema termina todo el proceso, eliminando todas las imgenes 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. Despus, el sistema llama a la funcin DllMain de la DLL con el valor DLL_PROCESS_ATTACH,

68

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

utilizando el hilo que realiz la llamada a LoadLibrary o LoadLibraryEx. Despus de que la funcin DllMain de la DLL haya procesado la notificacin, el sistema permite que vuelva la llamada a LoadLibrary o LoadLibraryEx, y el hilo contina su procesamiento con normalidad. Si la funcin DllMain devuelve FALSE, indicando que la inicializacin no tuvo xito, el sistema elimina automticamente la proyeccin 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 proyeccin de una DLL del espacio de direcciones de un proceso, el sistema llama a la funcin DllMain de la DLL, pasando DLL_PROCESS_DETACH como valor fdwReason. Una DLL debera realizar todas las liberaciones relativas al proceso cuando procese este valor. Por ejemplo, una DLL podra llamar a HeapDestroy para destruir un Heap que ha creado durante la notificacin DLL_PROCESS_ATTACH. Si se llama a la funcin DllMain de una DLL con un valor fdwReason igual a DLL_PROCESS_ATTACH y DllMain devuelve FALSE, indicando que la inicializacin no ha tenido xito, el sistema no dejar de llamar a DllMain con el valor DLL_PROCESS_DETACH. Por esta razn, debe asegurarse de que no intenta liberar nada que no se haya inicializado con xito. Si se est eliminando la proyeccin de la DLL porque el proceso est terminando, el hilo que llama a ExitProcess es el responsable de ejecutar el cdigo de la funcin DllMain. Bajo circunstancias normales, ste es el hilo primario de la aplicacin. Cuando la funcin DllMain vuelve al cdigo de inicio de la biblioteca de tiempo de ejecucin de C, este cdigo llama explcitamente a la funcin ExitProcess para terminar el proceso. Si se est eliminando la proyeccin de la DLL porque un hilo del proceso ha llamado a FreeLibrary, este hilo ejecuta el cdigo de la funcin DllMain. La llamada a Fre-eLibrary no volver hasta que la funcin DllMain haya terminado de ejecutarse. Si un proceso termina porque algn hilo del sistema llama a TerminateProcess, el sistema no llama a la funcin DllMain de la DLL con el valor DLL_PROCESS_DETACH. Esto significa que las DLLs proyectadas en el espacio de direcciones del proceso no tendrn la oportunidad de realizar ninguna liberacin antes de que el proceso termine. Esto podra provocar la prdida de datos. Slo se debera utilizar la funcin TerminateProcess como ltimo recurso.

69

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

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

70

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 Cuando se crea un hilo en un proceso, el sistema examina todas las imgenes de archivo DLL proyectadas actualmente en el espacio de direcciones del proceso y llama a cada una de las funciones DllMain de estas DLLs con el valor DLL_THREAD_ATTACH. Esta notificacin indica a todas las DLLs que realicen todas las inicializaciones de cada hilo. Por ejemplo, la versin DLL de la biblioteca de tiempo de ejecucin de C asigna un bloque de datos para que una aplicacin multihilo pueda utilizar de forma segura las funciones contenidas en la biblioteca de tiempo de ejecucin de C. El hilo recin creado es el responsable de ejecutar el cdigo de todas las funciones DllMain de la DLL. Slo despus de que todas las DLLs hayan tenido la oportunidad de procesar esta notificacin, permitir el sistema que el nuevo hilo comience a ejecutar la funcin de su hilo. Si un proceso ya tiene varios hilos ejecutndose en l cuando se proyecta una nueva DLL en su espacio de direcciones, el sistema no llama a la funcin DllMain de la DLL con el valor DLL_THREAD_ATTACH para ninguno de los hilos ya existentes. El sistema llama a la funcin DllMain de la DLL con un valor DLL_THREAD_ATTACH slo si la DLL est proyectada en el espacio de direcciones del proceso en el momento en que se crea el hilo nuevo. Observe tambin 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 estn proyectadas en el espacio de direcciones del proceso cuando se llama al proceso por primera vez reciben la notificacin DLL_PROCESS_ATTACH, pero no la DLL_THREAD_ATTACH.

71

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

DLL_THREAD_DETACH Cuando un hilo termina llamando a ExitThread, el sistema examina todas las imgenes 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 notificacin les indica a todas las DLLs que realicen todas las liberaciones correspondientes al hilo. Por ejemplo, la versin de DLL de la biblioteca de tiempo de ejecucin 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 tendrn la oportunidad de realizar ninguna liberacin antes de que termine el hilo. Esto podra provocar que se perdiesen datos. Igual que TerminateProcess, solo se debe utilizar TerminateThread como ltimo recurso. Si se est ejecutando algn hilo cuando se elimina la proyeccin de la DLL, no se llama a DllMain con DLL_THREAD_DETACH para ninguno de los hilos. Se podra comprobar esto en el procesamiento de DLL_PROCESS_DETACH para realizar cualquier liberacin 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 funcin de DLL pasa a estar disponible para un archivo EXE o de otra DLL, se dice que la funcin est exportada. Win32 hace posible que se exporten variables de datos globales adems de funciones. Ahora veremos los pasos que se deben seguir para exportar las funciones y variables globales de una DLL. El cdigo siguiente (tomado de un archivo fuente de DLL) muestra cmo exportar una funcin 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 cdigo debera resultarle nuevo a excepcin de _declspec(dllexport). El compilador de Microsoft C/C++ la reconoce como una nueva palabra clave. Cuando el compilador compila la funcin Add y la variable g_nUsageCount, incrusta alguna informacin adicional en el archivo .OBJ resultante. El objeto de esta informacin es que el enlazador la analice sintcticamente y la procese cuando enlaza todos los objetos OBJ de la DLL. Cuando se enlaza la DLL, el enlazador detecta esta informacin incrustada acerca de la funcin y de la variable exportada, y genera automticamente un archivo LIB que contiene la lista de smbolos exportados por la DLL. Este archivo LIB, claro est, se necesitar para enlazar cualquier EXE que llame a las funciones exportadas de la DLL. Adems de crear el archivo LIB, el enlazador incrusta una tabla de nombres exportados de funcin o de variable y la direccin en la cual est situada la funcin o variable dentro de la imagen de archivo DLL. El enlazador asegura que la lista est ordenada alfabticamente en funcin del nombre de smbolo.

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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

estn contenidas en una DLL. Por ejemplo, el fragmento de cdigo siguiente muestra cmo importar la funcin 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 funcin Add y la variable g_nUsageCount estn contenidas en una DLL a la que el EXE tendr acceso cuando se cargue. Esto provoca que el compilador genere cdigo especial para estos smbolos importados. Cuando se desea importar un smbolo, no se tiene que utilizar la palabra clave _declspec(dllimport). En su lugar, basta con utilizar la palabra clave extern estndar de C. Sin embargo, el compilador es capaz de generar un cdigo ligeramente ms eficiente si conoce por adelantado que el smbolo 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 smbolos de funciones y de datos importados. Un hilo puede obtener la direccin de la funcin o variable exportada por una DLL llamando a la funcin GetProcAddress:
FARPROC GetProcAddress (HINSTANCE hinstDll, LPCSTR IpszProc);

El parmetro hinstDll especifica el descriptor de la DLL. El valor que devuelve LoadLibrary o LoadLibraryEx identifica este valor de descriptor. El parmetro IpszProc puede tomar dos formas. En primer lugar, puede ser la direccin de una cadena terminada en cero que contiene el nombre de la funcin cuya direccin deseamos:
Ipfn = GetProcAddress (hinstDll, "AlgunaFuncEnDll");

Observe que el parmetro IpszProc aparece en el prototipo como LPCSTR, en vez de LPCTSTR. Esto significa que la funcin GetProcAddress slo aceptar cadenas ANS no se le puede pasar una cadena Unicode a esta funcin. La razn es que los smbolos de funcin y variable se almacenan siempre como cadenas ANS en la tabla de exportaciones de la DLL. La segunda forma del parmetro IpszProc indica el nmero ordinal de la funcin cuya direccin deseamos:
Ipfn = GetProcAddress (hinstDll, MAKEINTRESOURCE(2));

Esta utilizacin asume que conocemos que el creador de la DLL le ha asignado a la funcin AlgunaFuncEnDll el valor ordinal 2. Los dos mtodos proporcionan la direccin de la funcin AlgunaFuncEnDll contenida en la DLL. Si no se puede encontrar la funcin, GetProcAddress devuelve NULL.

Archivo de cabecera de una DLL Habitualmente, cuando se crea una DLL, tambin 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 cdigo fuente del EXE, se incluir este archivo de cabecera. A menudo tambin desearemos incluir este archivo de cabecera cuando se compilen los archivos de cdigo fuente de la DLL.

73

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 crear objetos a partir de las clases e implementar mtodos para permitir la comunicacin entre el plugin y el sistema. Adems de utilizar las clases proporcionadas por el SDK, se pueden integrar nuevas clases al framework del SDK de manera similar. El motivo de profundizar en la metodologa que utiliza 3D Studio Max para la programacin de plugins, es que se ha tomado como principal referencia para el desarrollo de la arquitectura de plugins de este proyecto, aunque no de manera literal, si en cuanto a la filosofa de la utilizacin de los bloques de parmetros y los mapas de parmetros, as como la manera de implementar la DLL internamente, ya que se ha considerado como un mtodo potente, sencillo y flexible para los programadores de plugins. La mayora de las clases del SDK heredan de tres clases abstractas. La clase raz de estas tres es la clase Animatable. Define la mayor parte de los mtodos de animacin. De Animatable deriva ReferenceMaker. Esta clase permite hacer referencias a otros objetos. De ReferenceMaker deriva ReferenceTarget. Una referencia es un enlace bidireccional entre objetos de una escena. Crea un registro oficial de las dependencias entre el ReferenceMaker y ReferenceTarget. Su funcin principal es permitir que un ReferenceTarget informe de algn modo a su ReferenceMaker dependiente que ha cambiado.

2.3.1.1 Funciones que debe implementar un plugin en 3ds Max


Las siguientes funciones deben ser implementadas por los desarrolladores de plugins de 3ds max. Estas funciones son invocadas por 3ds max o Windows en tiempo de carga y proporcionan informacin sobre la DLL cargada y las distintas clases del plugin que proporciona la DLL. Estas funciones son: DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) LibNumberClasses() LibClassDesc(i) LibDescription() LibVersion()

2.3.1.2 La funcion DllMain()


Los plugins de 3ds max se implementan como DLLs. Cuando los desarrolladores compilan y enlazan el cdigo de su plugin, se genera una DLL. La funcin DllMain() la implementa un desarrollador y es llamada por Windows cuando se carga el plugin. La mayora de los plugins tan solo hacen dos llamadas dentro de esta funcin. Estas llamadas son: inicializar los controles personalizados del interfaz de usuario, e inicializar los controles comunes de Windows. El cdigo siguiente muestra un ejemplo.
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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 hay q controlar que los controles no se inicialicen mas de una vez.

2.3.1.3 LibNumberClasses
Cuando 3ds max arranca, busca DLLs para cargarlas. Cuando encuentra una, necesita determinar el nmero de clases tipo plugin dentro de la DLL. El programador proporciona esta informacin a 3ds max definiendo la funcin LibNumberClasses(). Por ejemplo:
__declspec(dllexport) int LibNumberClasses() { return 1; }

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

2.3.1.4 LibClassDesc
El plugin debe proporcionar al sistema algn mecanismo para obtener los Descriptores de Clases definidos por el plugin. Los Descriptores de Clases proporcionan al sistema de la informacin sobre las clases plugin en el DLL. La funcin LibClassDesc(i) permite al sistema acceder a los Descriptores de Clases. Una DLL puede tener varios Descriptores de Clases, uno para cada clase plugin. La funcin 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 funcin que permita al sistema tratar con versiones obsoletas de plugins. Debido que la arquitectura de 3ds max mantiene una relacin muy estrecha con sus plugins, el sistema puede en algn punto evitar cargar algunos plugins demasiado antiguos. Para permitir que 3ds max cumpla esto, la DLL debe implementar una

75

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

funcin llamada LibVersion(). Esta funcin simplemente devuelve una constante indicando la versin del sistema bajo la cual fue compilada. Las versiones futuras de 3ds max podran actualizar esta constante, incluso las DLLs mas antiguas siempre devolvern el valor. Con esta funcin 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 versin 2 para incluir informacin sobre la versin actual de max, as como el numero de la versin actual de la API y el numero de versin del 3ds max SDK. La palabra ms alta contiene el nmero de la versin de 3ds max multiplicado por 100, y la palabra baja es el nmero de API y la revisin del SDK. 3ds max solo cargar DLLs que tengan el numero de API actual.
#define VERSION_3DSMAX ((MAX_RELEASE<<16)+(MAX_API_NUM<<8)+MAX_SDK_REV)

MAX_RELEASE Numero de versin de 3ds max multiplicado por 1000. MAX_API_NUM Numero de API de 3ds max. Cuando un cambio en la API requiere ser recompilada, este numero se incrementa y MAX_SDK_REV se pone a 0. Esto har que todas las DLLs con el MAX_API_NUM antiguo dejen de poder cargarse. MAX_SDK_REV Esto indica la revisin del SDK para una API dada. Este numero se incrementa cuando la funcionalidad del SDK cambia de manera significante (por ejemplo se aade un nuevo valor de retorno de la funcin GetProperty() ), pero las cabeceras no han cambiado. 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 mtodo del descriptor de clase es tambin 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 mtodos. Debajo hay un ejemplo de un descriptor de clase y la declaracin de una nica instancia esttica.
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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Los siguientes seis mtodos del descriptor de clase se describen a continuacin.


IsPublic()

Este mtodo 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 debera aparecer en listas para que los usuarios los elijan. Estos plugins devolvern FALSE.
Create(BOOL loading=false)

3ds max llama esta funcin cuando necesita un puntero a una nueva instancia de la clase plugin. Por ejemplo, si 3ds max est cargando un fichero de disco conteniendo un plugin anteriormente utilizado, llamar a la funcin Create() del plugin. El plugin responder reservando una nueva instancia de su clase plugin. Como en el ejemplo del descriptor de clase anterior, tan solo implica el uso del operador new. El parmetro opcional de la funcin Create(), es un flag indicando si la clase a crear va a ser cargada de un fichero de disco. Si el flag es TRUE, el plugin probablemente no tenga que realizar ninguna inicializacin del objeto ya que el proceso de carga se encajar de ello. Cuando el sistema necesita eliminar una instancia de una clase plugin, usualmente llama al mtodo DeleteThis(). Los desarrolladores de plugins tambin deben implementar este mtodo. Puesto que un desarrollador usa el operador new para reservar memoria, deber usar el operador delete para liberarla. Por ejemplo, el desarrollador podra implementar DeleteThis() de esta manera :
void DeleteThis() { delete this; }

This method returns the name of the class. This name appears in the button for the plug-in in the 3ds max user interface.
SuperClassID()

Este mtodo devuelve la constante definida por el sistema describiendo la clase de la cual deriva este plugin. Por ejemplo, el plugin Bend revuelve OSM_CLASS_ID. Este ID se usa por todos los modificadores de objetos.
ClassID()

Este mtodo debe devolver el ID nico para el objeto plugin. El SDK proporciona un programa para generar este ClassID, es importante usar este programa para no provocar ningn conflicto de IDs.
Category()

Indica la categora del plugin. De esta manera el plugin se mostrar en una u otra lista de categoras del interfaz de usuario. Si la categora no existe, se crea una nueva.

Los bloques de parmetros

77

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

La clase de bloque de parmetros proporciona un mecanismo para almacenar valores para los parmetros de los plugins. Cuando se crea un bloque de parmetros, el desarrollador especifica el nmero de parmetros y el tipo de cada parmetro. El tipo de cada parmetro consiste en un rango de tipos predefinidos como entonces, coma flotante, punto 3D, y color. Para acceder a los valores del bloque de parmetros, el desarrolladores usan los mtodos GetValue() y SetValue(). Un descriptor de bloque de parmetros se usa para describir cada parmetro. Se inicializa pasando tres argumentos por parmetro.
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

Cuando un desarrollador necesita obtener un valor del bloque de parmetros, se usa la funcin GetValue(). Existe una funcin sobrecargada para cada tipo de valor a obtener (int, float, point y RGBA). Cada mtodo tiene cuatro parmetros. A continuacin se muestra la funcin para el tipo float:
BOOL GetValue( int i, TimeValue t, float &v, Interval &ivalid );

Cuando un desarrollador necesita almacenar un valor en el bloque de parmetros, se usa la funcin SetValue(). Igual que en GetValue(), existe una funcin sobrecargada para cada tipo de dato.
BOOL SetValue( int i, TimeValue t, float v );

Puesto que los bloques de parmetros derivan de ReferenceTarget, los plugins pueden crear referencias a ellos. Creando una referencia a un bloque de parmetros, el plugin puede ser notificado siempre que alguno de sus parmetros tome un nuevo valor. Cuando cambia un valor del bloque de parmetros, el plugin necesita ser informado. Esta notificacin la hace el mtodo NotifyDependents() de la clase ReferenceMaker. Hay dos mtodos que se invocan cuando un usuario comienza y termina de modificar los parmetros de un elemento. Estos son BeginEditParams() y EndEditParams().

78

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

2.3.1.8 Mapas de parmetros


Los mapas de parmetros en 3ds max se usan para minimizar el esfuerzo de programacin que requiere mantener el interfaz de usuario de un plugin. Un simple plugin, tal como una esfera procedural, tiene un interfaz de usuario consistente en varios controles como spinners, radios y check-boxes. Cada uno de estos controles tiene una correspondencia uno a uno con una variable o un parmetro de un bloque de parmetros. Los mapas de parmetros se pueden usar para mapear los controles del interfaz de usuario en manejadores del tipo apropiado de dato. El uso de los mapas de parmetros tienes varias ventajas: El desarrollador no necesita escribir cdigo de procesado de mensajes para manejar los eventos generados por el usuario. Por ejemplo, si un desarrollador no utiliza mapas de parmetros, debe proporcionar una funcin del dialogo que procese los mensajes enviados a los controles cada vez que el usuario interacta con ellos. Por ejemplo el control spinner enva un mensaje cuando el usuario pulsa sobre las flechas de arriba y abajo o introduce nuevos valores. Los mapas de parmetros manejan estos mensajes procesndolos internamente. El desarrollador se libera de tratar con la complejidad de tener que manejar controladores para controlar la animacin de los valores del interfaz de usuario. El tipo apropiado de controlador se asigna y se maneja por el bloque de parmetros que controla el mapa de parmetros. El desarrollador tan solo usa las funciones GetValue() y SetValue() para obtener o almacenar valores. El Undo y Redo se manejan automticamente cuando el valor de un parmetro cambia. La carga y el guardado de los parmetros a disco y desde disco se manejan automticamente.

2.4 Conclusiones.
En este captulo se han mostrado las diferencias entre la informtica grfica tradicional y la informtica grfica en tiempo real, mostrando la necesidad de utilizacin de hardware especializado en la generacin de imgenes, y en consecuencia, de libreras de bajo nivel que proporcionen control sobre dicho hardware. En este sentido, se ha realizado un recorrido histrico por las distintas libreras que proporcionan un API para el renderizado de grficos 3D, finalizando con la librera OpenGl, un standard empleado por la gran mayora de los sistemas grficos actuales. Se ha presentado de forma abreviada los principales aspectos que definen la forma de funcionamiento de la librera OpenGl, realizando tambin una introduccin sobre la forma en la que opera con las matrices de transformacin. Se ha descrito como las libreras de bajo nivel proporcionan buenos mtodos para controlar las capacidades del hardware grfico, pero resultan demasiado elementales si se desea implementar una escena de simulacin compleja, siendo en este caso necesaria la utilizacin de una librera grfica de alto nivel basada en la utilizacin de un Grafo de Escena. Los grafos de escena estn diseados para optimizar el proceso de dibujado y contribuir a la organizacin de la base de datos, resultando de especial importancia sus procesos de culling y seleccin de nivel de detalle, y su capacidad para actuar como soporte para la aplicacin jerrquica de transformaciones afines. Se han presentado los tipos de nodos bsicos empleados en la definicin de estos grafos, y tambin la forma en la que estas libreras de alto nivel actan en el caso de disponer de un sistema con varios procesadores. Tambin se ha realizado un recorrido por los grafos de escena actuales, profundizando en aquellos que han tenido una mayor influencia en la evolucin de esta rama de la informtica grfica (OpenGl Performer, Open Inventor y VRML). El resto de los grafos de escena presentan 79

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

unas caractersticas bsicas 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 estn siendo distribuidos como cdigo abierto, como es el caso de OpenSceneGraph. Hemos hecho del mismo modo un recorrido sobre los distintos editores 3D y su importancia en el mundo de la informtica grafica, la simulacin, realidad virtual, videojuegos etc., y hemos visto como la mayor parte de los motores de videojuegos son o bien motores de visualizacin o bien motores completos, siendo cada vez mas estandarizados. La simulacin y la visualizacin estn fuertemente acopladas, y en las aplicaciones de realidad virtual existe una fuerte componente de simulacin y exigencias elevadas de velocidad interaccin con el usuario. De las aplicaciones vistas, tan solo permiten trabajar en tiempo real UnrealED y Hammer Editor. Las libreras de enlace dinmico permiten el desarrollo de plugins en las aplicaciones, las cuales nos proporcionan una mayor personalizacin, modularidad, mantenibilidad y flexibilidad, incluso puede prolongar la vida de nuestro software. Como ejemplo de aplicacin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE III

TECNOLOGIA Y MATERIALES

81

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

82

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

INDICE

PARTE III......................................................................................................
3.1 Metodologa ...................................................................... Error! Marcador no definido. 3.2 Materiales .......................................................................... Error! Marcador no definido. 3.3 Planificacin temporal....................................................... Error! Marcador no definido. 3.3.1 Diagrama de Gant....................................................... Error! Marcador no definido.

83

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

3.1 Metodologa
El primer paso en todo proyecto es la investigacin del estado de las tecnologas implicadas en el mismo, con el objetivo de adquirir un conocimiento sobre la tarea a realizar, encontrar otros estudios o aplicaciones existentes que estn relacionados con el mismo campo. Tras este estudio, documentado detalladamente en la parte II de este proyecto, es momento de planificar en detalle las tareas que se van a realizar dentro del proyecto.

3.2 Materiales
El recurso ms importante para el desarrollo de este proyecto ser un PC convencional. En dicho PC ser necesaria la instalacin de un compilador de C++. Se ha elegido para esta ocasin el compilador Microsoft Visual Studio .NET, versin 7.1 ya que su versin anterior presentaba distintas incompatibilidades con la librera OpenSceneGraph necesaria para el desarrollo del proyecto. La licencia de uso de esta plataforma de desarrollo de aplicaciones ha sido adquirida por la Universidad de Valencia, por lo que no ha sido necesaria su compra, puesto que la universidad lo utiliza como apoyo para la docencia en las distintas asignaturas de programacin de la carrera. Una vez instalado dicho compilador no queda ms que instalar la librera OpenSceneGraph en el sistema operativo as como configurar el compilador adecuadamente para compilar adecuadamente sus fuentes. El software generado ser dependiente del sistema operativo (en este caso Microsoft windows), ya que se har uso de las MFCs (Microsoft Foundation Classes). Debido al motivo de uso del compilador de Microsoft el uso del software generado deber correr bajo sistemas operativos de Microsoft.

3.3 Planificacin temporal.


El proyecto, siguiendo las tcnicas de desarrollo de software aprendidas en la asignatura IS2, puede dividirse en 6 fases bien definidas: 1) Bsqueda bibliogrfica. En esta etapa se ha recopilado toda la informacin necesaria para poder saber el alcance del proyecto al que nos enfrentamos. Con esta bsqueda se documenta el proyecto para tener una base de conocimiento adecuada al problema que se aborda en este estudio. Se investigan las tecnologas existentes, trabajos realizados, y posibles soluciones ya implementadas, que sirvan de posible punto de partida en el desarrollo de este proyecto. 2) Anlisis. 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 anlisis por separado, viendo cual es la solucin ms adecuada para nuestro caso en particular. En el anlisis se utilizar la notacin UML apropiada para cada apartado: casos de uso, diagramas entidad-relacin, etc. 3) Diseo de cada una de las partes. Una vez analizado el sistema, se especifica la arquitectura software del sistema y se ofrece una primera aproximacin algortmica al sistema global, que sea capaz de cumplir con todas las conclusiones alcanzadas en el anlisis anterior. De nuevo en este apartado se utilizarn los diagramas UML que se requieran. 4) Implementacin. Una vez definidos requerimientos y funcionalidades de nuestro sistema, solo queda

84

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

codificar el sistema convenientemente, teniendo en cuenta no solo los apartados de anlisis y diseo realizados con anterioridad, sino tambin las decisiones tomadas en cuanto al lenguaje de programacin, 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) Redaccin. Es la ltima parte del proyecto, pero esto no indica que se realice en ltimo lugar. La redaccin del proyecto es un proceso creciente y continuo desde el comienzo del proyecto, redactando en cada momento los detalles y aspectos de inters que han aparecido en el transcurso del proyecto. Esta es la parte ms 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.3.1 Diagrama de Gant.


Una vez explicadas las diferentes fases en las que se va a dividir este proyecto, se puede realizar una representacin grfica de la planificacin temporal. Para este propsito se muestra a continuacin el diagrama de Gant, utilizado para indicar la duracin y posicin en el tiempo de cada una de las tareas principales. En el diagrama se utiliza una divisin temporal en un total de 44 semanas, comenzando en el mes de octubre, y planificando el final del proyecto en el mes de agosto.
Documentacin bibliogrfica Anlisis del sistema de informacin Diseo del sistema Implementacin Diseo interfaz de usuario Sistema automtico de generacin de controles Control del grafo de escena mltiple Interaccin escena/usuario Sistema undo/redo Sistema de soporte de plugins Pruebas y depuracin Redaccin 60 das 15 das 15 das 115 das 20 das 14 das 35 das 20 das 15 das 10 das 12 das 24 das

oct '05 60 das

nov '05

dic '05

ene '06

feb '06

mar '06

abr '06

may '06

jun '06

jul '06

ago '06

sep '06

oct '06

Documentacin bibliografica 15 das Analisis del sistema de informacion 15 das Diseo del sistema 115 das 20 das Diseo interfaz de usuario 14 das Generacion automatica de controles 35 das Control del grafo de escena multiple 20 das Interaccion escena/usuario 15 das Sistema undo/redo 10 das Soporte de plugins 12 das Pruebas y depuracion 24 das Redaccion Implementacin

85

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Los materiales necesarios para el proyecto y sus costes son los siguientes:

PC Pentium 4 con 1GB de memoria RAM, tarjeta grfica aceleradora GeForce MX y tarjeta de red utilizado durante la elaboracin del proyecto Sistema Operativo Windows XP (cedido por el Instituto de Robtica). Herramientas de desarrollo Visual Studio .NET (cedido por el Instituto de Robtica). Licencia de Visual .NET Conexin a Internet, utilizando para ello la red de la Universidad de Valencia. Librera grafica OpenSceneGraph (open source).

700.00 -

96.15 0

Todo este proyecto se engloba en la nueva lnea de investigacin del grupo ARTEC acerca de la recreacin y simulacin de escenarios virtuales, para simulaciones en tiempo real. Por tanto, todo el material arriba mencionado, se utilizar posteriormente en otros proyectos, amortizando dicho coste en un corto periodo de tiempo. Por tanto, el coste amortizado se calcular en 24 meses, habiendo utilizado para este proyecto 11 meses.
CONCEPTO IMPORTE

PC Pentium 4, 1GB RAM, Ge-Force MX, tarjeta red, etc. Licencia Visual .NET Base imponible IVA 16% TOTAL: Coste amortizado = (923.54 / 24) * 11 = 423.28

700.00 96.15 796.15 127.39 923.54

A estos costes es necesario aadir el sueldo de un Ingeniero Informtico. Suponiendo un sueldo de 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.54 Si ha este precio aadimos un 10 % para cubrir posibles imprevistos, obtenemos una cantidad final: TOTAL = Precio + 10 % = 25,264.3

86

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

87

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

88

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE IV

ANALISIS

89

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

INDICE
PARTE IV ......................................................................................................
4.1 Introduccin ...................................................................... Error! Marcador no definido. 4.2 Anlisis de Requisitos. ...................................................... Error! Marcador no definido. 4.2.1 Requisitos generales del sistema. ............................... Error! Marcador no definido. 4.2.2 Requisitos de la representacin del grafo de escena .. Error! Marcador no definido. 4.2.3 Requisitos de la representacin de tipos de datos en el interfaz..... Error! Marcador no definido. 4.2.4 Requisitos de la manipulacin sobre la representacin 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.

90

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4.2.6 Requisitos del Manejador de Vista Activa ................. Error! Marcador no definido. 4.3 Anlisis.............................................................................. Error! Marcador no definido. 4.3.1 Anlisis de la representacin de los datos del grafo en el interfaz .. Error! Marcador no definido. 4.3.1.1 Grupos de parmetros.......................................... Error! Marcador no definido. 4.3.1.2 Descriptores de parmetros ................................. Error! Marcador no definido. 4.3.1.3 El gestor de parmetros ....................................... 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 Anlisis de la representacin 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 mltiples 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 informacin de un nodo del grafo...... Error! Marcador no definido. 4.3.3 Anlisis de la interaccin con el visor del editor........ Error! Marcador no definido. 4.3.3.1 El gestor de seleccin .......................................... Error! Marcador no definido. 4.3.3.2 El eje manipulador .............................................. Error! Marcador no definido. 4.3.3.3 Creacin automtica de Matrices de Transformacin ......... Error! Marcador no definido. 4.3.3.4 Traslacin de objetos usando el eje manipulador Error! Marcador no definido. 4.3.3.5 Representacin de objetos independientes a la escena del editor................Error! Marcador no definido. 4.3.4 Anlisis del sistema deshacer / rehacer. ..................... Error! Marcador no definido. 4.2.7 Anlisis del sistema de plugins. ................................. Error! Marcador no definido. 4.2.8 Anlisis 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 Descripcin de alto nivel de los Casos de Uso........... Error! Marcador no definido. Iniciar la aplicacin. ........................................................ 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 parmetros de un TabOutput........ Error! Marcador no definido. Cargar Plugins. ................................................................ Error! Marcador no definido. Cerrar aplicacin. ............................................................ 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 segn el nombre de su NodeType. .......... Error! Marcador no definido. Crear una nueva instancia de un nodo segn su nombre. Error! Marcador no definido.

91

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 informacin de un nodo ................................. Error! Marcador no definido. Crear los dilogos de un TabOutput................................ Error! Marcador no definido. Crear un dilogo a partir de un grupo de parmetros ...... 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 seleccin de un ObjectType................... Error! Marcador no definido. Mostrar los datos de un TabOutput ................................. Error! Marcador no definido. Seleccionar nodo en el visor............................................ Error! Marcador no definido. Agregar nodo a la seleccin del visor ............................. Error! Marcador no definido. Crear Matriz de Transformacin como padre de un nodo............... Error! Marcador no definido. Actualizar la seleccin. ................................................... Error! Marcador no definido. Actualizar el eje manipulador. ........................................ Error! Marcador no definido. Copiar nodo..................................................................... Error! Marcador no definido. Replicar seleccin. .......................................................... Error! Marcador no definido. Mover nodo. .................................................................... Error! Marcador no definido. Duplicar Nodo. ................................................................ Error! Marcador no definido. Duplicar Seleccion. ......................................................... Error! Marcador no definido. Eliminar nodo.................................................................. Error! Marcador no definido. Activar modo seleccin. .................................................. Error! Marcador no definido. Activar modo traslacin de objetos................................. Error! Marcador no definido. Activar modo escalado de objetos................................... Error! Marcador no definido. Activar modo rotacin de objetos. .................................. Error! Marcador no definido. Activar modo rotar vista.................................................. Error! Marcador no definido. Activar modo trasladar vista. .......................................... Error! Marcador no definido. Escalar seleccin. ............................................................ Error! Marcador no definido. Comenzar escalado de seleccin. .................................... Error! Marcador no definido. Realizar escalado de seleccin. ....................................... Error! Marcador no definido. Finalizar escalado de seleccin. ...................................... Error! Marcador no definido. Rotar seleccin. ............................................................... Error! Marcador no definido. Comenzar rotacin de seleccin...................................... Error! Marcador no definido. Realizar rotacin de seleccin......................................... Error! Marcador no definido. Finalizar rotacin de seleccin........................................ Error! Marcador no definido. Trasladar seleccin.......................................................... Error! Marcador no definido. Comenzar traslacin de seleccin. .................................. Error! Marcador no definido. Realizar traslacin de seleccin. ..................................... Error! Marcador no definido. Finalizar traslacin de seleccin. .................................... Error! Marcador no definido. Centrar la vista en la seleccin........................................ Error! Marcador no definido. Modificar el zoom de la vista. ......................................... Error! Marcador no definido. Aadir un StateAttribute a un StateSet............................ Error! Marcador no definido. Eliminar un StateAttibute de un StateSet. ....................... Error! Marcador no definido. Aadir un Modo a un StateSet. ....................................... Error! Marcador no definido. Eliminar un Modo de un StateSet. .................................. Error! Marcador no definido. Modificar un Modo de un StateSet. ................................ Error! Marcador no definido. Modificar el parmetro de un control del panel de comandos. ....... Error! Marcador no definido. Establecer el valor de un parmetro. ............................... Error! Marcador no definido. Establecer el valor de un parmetro. ............................... 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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. 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. ...................... Error! Marcador no definido. 4.4.3 Casos de Uso siguiendo la notacin UML. ................ Error! Marcador no definido.

93

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4.1 Introduccin
Cualquier trabajo que requiere de un proceso de Ingeniera del Software, requiere una fase de anlisis del problema a resolver, de forma que se obtengan todas las caractersticas del sistema que se analiza.

94

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

En primer lugar se realizar un anlisis general del sistema, describiendo el problema y las necesidades o requerimientos del sistema global, gracias a lo cual conoceremos qu debe hacerse para solucionarlo. Esto no implica definir la solucin al problema, sino simplemente la forma de abordarlo. Al analizar el sistema en conjunto, se puede realizar una divisin para desglosar el sistema en distintas partes bien definidas: 1. Por una parte, analizaremos como plasmar la informacin de un grafo acclico en una estructura manejable desde el interfaz de usuario. 2. En segundo lugar, estudiaremos un sistema que nos permita generar automticamente controles para mostrar la informacin de los tipos de datos del grafo, entre otros. 3. Deberemos definir las acciones que vamos a permitir al usuario sobre la representacin 3D de la escena. 4. Continuaremos viendo un sistema de historia de las acciones, conocido comnmente como deshacer / rehacer. 5. Veremos 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 atencin en realizar un anlisis dentro de la perspectiva de los objetos, para posteriormente implementarlos en un lenguaje de programacin orientado a objetos (C++). Se utilizara UML ya que rene una coleccin de las mejores practicas en la ingeniera que han sido utilizadas hasta el momento, es trata de la unificacin de los diversos sistemas que haba hasta el momento, con las mejores caractersticas de cada uno de ellos.

4.2 Anlisis de Requisitos.


4.2.1 Requisitos generales del sistema.
Orientacin a objetos: nos permite utilizar una forma de programacin en base a objetos que responden a eventos, adems de potenciar los conceptos de modularidad y reutilizacin de cdigo consiguiendo aplicaciones que posean abstraccin (representar las caractersticas 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 ningn otro objeto necesite conocer nunca su estructura interna), herencia (mecanismo por el cual somos capaces de compartir automticamente mtodos y atributos entre clases y subclases) y por ltimo el polimorfismo (que nos da la capacidad de poder implementar mltiples formas de un mismo mtodo, dependiendo cada una de ellas de la clase sobre la que se realice la implementacin). Adaptabilidad: De forma que sea un sistema fcilmente adaptable tanto a nuevos cambios, como cambios sobre la estructura actual, adems de ser fcilmente 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 representacin del grafo de escena

95

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 mltiples vistas del control en el interfaz de usuario, para aquellos casos en los que trabajemos con grafos muy grandes, y necesitemos trabajar simultneamente 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.

Tambin 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 representacin de tipos de datos en el interfaz.


Tenemos que encontrar un mtodo sencillo, flexible y lo ms genrico posible que nos permita representar la informacion de los nodos y modificarla desde el interfaz de usuario. Hemos descartado directamente crear un dilogo 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 manera dinmica los controles que necesitemos para cada tipo de nodo, crear las estructuras de datos adecuadas para poder manipular este tipo de datos, y un 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 manipulacin sobre la representacin 3D del grafo.


Nuestra aplicacin tendr una ventana de representacin 3D, con el aspecto final que presenta el grafo que estamos manipulando en tiempo real. Se podra manipular el grafo completamente tan solo haciendo uso del control del rbol, no obstante, esto puede ser algo incmodo a la hora de desplazar objetos por pantalla, por ejemplo, ya que tendramos que editar las propiedades de un nodo de transformacin y escribir manualmente sus coordenadas exactas donde queremos colocar el objeto en el espacio 3D. Puesto que uno de los objetivos de esta aplicacin ser hacer ms sencillo al usuario la manipulacion del grafo de escena, este ser un punto de gran importancia en el proyecto.

96

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Deberemos intentar proporcionar al usuario las herramientas que mayor comodidad y flexibilidad puedan darle.

4.2.5 Requisitos del sistema de deshacer / rehacer


Hoy da prcticamente cualquier aplicacin posee un sistema que almacena la historia de las acciones que se van llevando a cabo, de manera que en un momento dado, el usuario pueda retroceder o avanzar en esta historia. Puesto que estamos continuamente expuestos a cometer errores, algunas veces irreversibles, otras veces tediosas de reparar, estos sistemas se han convertido en una caracterstica casi imprescindible para cualquier software medianamente aceptable, ahorrndonos mucho tiempo innecesario por el hecho de haber cometido cualquier 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 cualquier tipo de accin que se pueda realizar en la aplicacin.

4.2.5 Requisitos del sistema de plugins


Los Plugins dan a una aplicacin la capacidad de agregar funcionalidades nuevas en tiempo de ejecucin. Puesto que OpenSceneGraph es una librera en continuo desarrollo y ampliacin, deberemos poder agregar plugins con nuevos tipos de datos del grafo de escena, entre otras cosas. Ms concretamente deberemos de poder desarrollar plugins: Con nuevos tipos de Nodo. Con nuevos tipos de Atributos de Estado. Con nuevos tipos de Objeto. Con nuevas salidas en la pestaa principal del interfaz de usuario que nos permitir manipular prcticamente cualquier aspecto de la aplicacin.

Necesitamos un sistema que nos permita cargar estos fragmentos de cdigo en la memoria de nuestro programa en tiempo de ejecucin. Para ello necesitaremos un interfaz comn que permita comunicarse a la aplicacin con todas estos plugins.

4.2.6 Requisitos del Manejador de Vista Activa


Nuestro sistema deber ser capaz de coordinar los distintos modulos de la aplicacin, y permitir una comunicacin entre ellos. Este sistema, que actar como la columna vertebral de la aplicacin, deber ser el encargado 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 aplicacin. Permitir comunicar unos mdulos con otros. Permitir invocar funciones globales de la aplicacin.

97

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4.3 Anlisis.

Figura 4-1. Diagrama de clases de la aplicacin

4.3.1 Anlisis de la representacin de los datos del grafo en el interfaz


Los nodos del grafo de escena son estructuras de datos, que a su vez contienen datos que pueden ser datos ms simples u otras estructuras de datos. Por tanto vamos a tener que proporcionar un mecanismo mediante el cual generemos los controles de interaccin con el usuario de manera dinmica para cada tipo de dato. Vamos a implementar una estructura de datos que nos permita almacenar o indicar de alguna manera los parmetros que queremos crear, y a ser posible, indicar con qu tipo de datos estamos tratando.

98

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Para el anlisis de este problema nos hemos basado en los Parameter Blocks (bloques de parmetros) que hemos explicado anteriormente que utiliza 3ds max, y los hemos adoptado, aunque de manera modificada y adaptada mas concretamente a nuestras necesidades.

4.3.1.1 Grupos de parmetros


Un Grupo de Parmetros identificar un conjunto de parmetros comunes, como puede ser el caso de los parmetros de una estructura de datos ms compleja. El grupo de parmetros se representar en el interfaz de usuario como un grupo de controles agrupados, con un botn desplegable que permitir mostrarlos u ocultarlos. Por tanto, cada uno de estos grupos de parmetros estar compuesto por un conjunto de parmetros, que vendrn identificados en el interfaz de usuario por controles Win32, que llamaremos Descriptores de Parmetros.

4.3.1.2 Descriptores de parmetros


Un descriptor de parmetro describe e identifica de manera nica un parmetro, que puede pertenecer a una estructura de datos compleja que estemos manejando en nuestro editor. Cada uno de estos parmetros deber estar compuesto por: El nombre o conjunto de nombres del parmetro. El tipo de dato que maneja. Su id que lo identifique de manera nica. El grupo al que pertenece.

Puesto que estamos trabajando con estructuras de datos relacionadas con la informtica grfica, deberemos dar soporte a los tipos bsicos de datos y adems otros ms especficos de este campo. Estos son: Entero Coma flotante Texto Booleano Enumeraciones Matrices Color Vector XYZ Vector XYZW Rango de Enteros Rango en coma flotante

4.3.1.3 El gestor de parmetros


Llegados a este punto vamos a necesitar un gestor que se encargue de: Crear cada unos de estos parmetros en su correspondiente control Win32. Registrar cada uno de estos parmetros internamente

99

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Identificar de manera unvoca cada uno de los controles que se asocia a cada parmetro. Adems, 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 consistira el proceso de plasmar una estructura de datos Material , que contendra informacin sobre un material (tipo de color, color ambiental, difuso, especular y de emisin), en un grupo de parmetros utilizando descriptores de parmetros para obtener la salida por el interfaz de usuario.

Figura 4-2. Ejemplo de un proceso de parametrizacin de una estructura de datos mediante el gestor de parmetros.

Ya tenemos analizado un sistema que nos convierte automticamente grupos de parmetros en controles, y nos gestiona incluso su paso de mensajes. En la figura 4.4 anterior hemos parametrizado una estructura de datos Material, no obstante, no existe todava ningn mecanismo mediante el cual estos parmetros se modifiquen al modificarse en el interfaz o nos permitan consultar el valor de estos datos. Tenemos que relacionar ambas cosas de alguna manera. Aqu es donde surge el concepto de TabOutput, esta clase ser una clase virtual pura, que se deber implementar para cada tipo de dato que queramos poder parametrizar. Las funciones que deberemos implementar sern: Crear controles: en esta funcin deberemos indicar los grupos de parmetros que vamos a utilizar. Mostrar datos de la clase: Podremos establecer los valores de nuestra estructura de datos en los controles del interfaz.

100

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Notificacin de evento modificado: Se invocar a esta funcin cuando un valor del interfaz sea modificado, de esta manera podremos actualizar los datos de nuestra estructura de datos.

Adems, nos deber proporcionar funciones para intercambiar datos con los controles. Estas funciones de asignar u obtener valores debern estar sobrecagadas para cada tipo de dato que soporten los Descriptores de parmetros. De esta manera, el proceso de la figura anterior quedara como se muestra en la figura 4.5.

Figura 4.3 Proceso de parametrizacin y utilizacin del gestor de parmetros para establecer y obtener valores, as como para su paso de mensajes.

Pero con esta estructura de datos TabOutput tan solo podemos indicar qu parmetros queremos que tenga nuestro descriptor de grupo para un tipo de datos en concreto, y podemos obtener notificacin de que los controles han sido manipulados, y obtener el valor actual del control manipulado, as como establecer su valor, pero todava no tenemos ninguna relacin que asocie automticamente todos estos controles con una instancia en particular del tipo de dato, para as actualizar su valor. En OpenSceneGraph existen 3 clases base que nos interesa diferenciar. Estas son: Object: Cualquier tipo de dato que no es ni Node ni StateAttribute. Node: Son los nodos que pertenecen al rbol. StateAttribute: Son los atributos que pueden tener los nodos y otros tipos de datos.

As pues, vamos a derivar 3 tipos de TabOutput: ObjectType, NodeType y AttributeType uno para cada tipo de clase respectivamente. Partiremos de ObjectType, puesto que Object es la clase base para todo objeto en OpenSceneGraph. Esta distincin nos interesa para poder asociar un objeto a los eventos al TabOutput, y tratar los datos en el interfaz de usuario de manera distinta, incluso para manejar algun tipo de evento concreto.

101

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 mostrarn sus parmetros en la salida de interfaz de usuario, y as de manera recursiva hasta que no exista ms herencia. Esto nos ahorrar memoria, y mucho trabajo a la hora de implementar todos y cada uno de los tipos de Nodo, Atributo y Objeto, puesto que nos evitar tener que parametrizar de nuevo aquellos elementos de clases que ya hemos implementado anteriormente, por el hecho de tener parientes en comn. 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 ObjectType cuando nos convenga. Esto implica recibir notificaciones de eventos del ObjectType vinculado. Crear una nueva instancia del tipo de dato que estamos manejando. Esta caracterstica nos ofrecer 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 Seleccin: Esta nueva notificacin le llega al ObjectType que est siendo editado para indicar que el objeto va a dejar de ser mostrado, para mostrar en su lugar otro ObjectType distinto. Esto permite realizar ajustes de reset en la clase antes de que se muestre otra.

La clase NodeType y AttributeType solo diferirn de ObjectType en su constructor (para indicar que es un objeto tipo NodeType o AttributeType respectivamente). La clase AttributeType permite adems asignar el tipo de StateAttribute con el que estamos tratando. Ahora, cuando obtengamos una notificacin de que un parmetro ha sido modificado, obtendremos tambin un puntero a la instancia del elemento que estamos modificando, para que nosotros actualicemos el valor en funcin de nuestros requisitos. Esto no permitir desarrollar los tipos de objeto de una manera mucho ms rpida, y nos facilitar el posterior proceso de adaptacin a la arquitectura de plugins de la aplicacin.

102

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 segn proceda. Puesto que existen gran variedad de estos datos, vamos a implementar solo los que consideramos ms importantes, estos son: Nodes: Billboard DOFTransform Emitter BumpMapping Cartoon Effect SpecularHighlights Geode Group Impostor LightSource LOD MatrixTransform Emitter Node PagedLOD ParticleProcessor ParticleSystemUpdater PositionAttitudeTransform Projection Sequence Switch Transform

StateAttributes : BlendFunc Fog FragmentProgram Light Material TexEnv TexGen Texture Texture2D

Objects necesarios, utilizados por los Nodes y StateAttributes: ConstantRateCounter Counter Drawable StateSet Geometry Particle ParticleSystem RandomRateCounter ShapeDrawable Text VariableRateCounter

103

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 registrarlos globalmente en el sistema para saber en todo momento que tipos de datos estn implementados y cuales no lo estn. 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 dato, sin necesidad de conocer el dato que estamos manipulando. De aqu surgen el Gestor de ObjectTypes, el gestor de NodeTypes y el gestor de AttributeTypes.

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 funcin de mostrar datos al mostrar los de la clase Geometry.

4.3.2 Anlisis de la representacin del grafo de escena


Puesto que la estructura de datos que maneja OpenSceneGraph es el grafo de escena, el grafo de escena deber estar representado en nuestro programa de alguna manera que nos permita manipularlo y trabajar con l. Esto implica construir una estructura de datos y una imagen del grafo que permita manejar el grafo de escena de OpenSceneGraph desde el editor, asociando cada uno de nuestros propios nodos con el nodo correspondiente en el grafo de escena. El problema surge a la hora de representar el grafo en un control de la API de Windows. Puesto que no es uno de los objetivos principales crear un nuevo tipo de control para poder representar este tipo de estructuras en la interfaz de usuario, debido al tiempo que podra llevar su estudio e implementacin, haremos uso de los controles que la API de win32 nos proporciona, por lo que mostraremos el grafo en forma de rbol (concretamente un TreeCtrl).

104

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 4-6. Equivalencia entre la representacin de un grafo y un rbol.

La principal diferencia entre el rbol y el grafo de escena es que un nodo puede tener ms de un padre, la solucin 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 mltiple.

Figura 4-7. Representacin de los enlaces en las estructuras del editor

Puesto que cada uno de los nodos del grafo puede estar representado en varios elementos del rbol (aunque solo est identificado con un solo nodo del grafo) necesitamos tener el grafo duplicado en nuestro editor, usando nuestra propia estructura de datos Nodo, que llamaremos TreeNodeInfo, y que contendr: Enlaces a sus padres y a sus hijos Enlaces a los distintos elementos del rbol (sus mltiples instancias). De esta manera sabremos inmediatamente las distintas instancias de un mismo nodo. Enlace a su nodo equivalente en el grafo de escena de OpenSceneGraph. Enlace al NodeType correspondiente a ese tipo de nodo.

Del mismo modo, cada elemento del rbol mantendr un puntero a su nodo del grafo del editor. Esto lo podemos ver reflejado en la figura 4.3.

4.3.2.1 Crear un rbol a partir de un grafo


105

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Ya hemos analizado las estructuras de datos adecuadas para tener nuestro grafo de escena clonado y relacionado con su representacin de rbol, ahora necesitamos un mtodo que construya dicho grafo y dicho rbol. 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 informacin de cada uno de los nodos que hemos encontrado encapsulados en nuestra propia estructura de datos, y su relacin de sus padres e hijos. 1. Recorrer el grafo completamente y obtener informacin 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 elementos obtenido asignamos los punteros apropiados a los padres y a los hijos, obteniendo asi una estructura de grafo (nuestro grafo clonado).

4.3.2.2 Mostrar el grafo en mltiples 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 TreeBar, que son las que contienen las vistas TreeCtrl conteniendo el rbol del grafo de escena del editor (uno por cada escena, ver Figura 4.8).

Figura 4-8. Diagrama de clases relacionado con la vista mltiple del grafo

MultiTreeBar nos debe permitir : Crear (clonar) una nueva imagen del rbol (TreeBar). Establecer y obtener el TreeBar activo. Establecer y obtener la escena activa. Obtener el nmero de TreeBar de cada rbol. Obtener el nmero de escenas de cada rbol. Copiar al portapapeles una rama de cualquier TreeBar. Pegar del portapapeles una rama de cualquier TreeBar sobre un nodo de cualquier otro.

Cabe aclarar una cosa, y es que tenemos que diferenciar entre escenas y TreeBars. Una escena identifica un grafo de escena, equivaldra a un TreeCtrl. Un TreeBar identifica un conjunto de 106

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

escenas, que, en caso de haber ms de una, sera imgenes clonadas las escenas de otra TreeBar. As pues, una escena puede estar clonada en varios TreeBars.

Figura 4-9. Ejemplo de MultiTreeBar para con dos escenas y tres vistas simultneas.

La figura 4.9 Muestra un grfico explicando la relacin de MultiTreeBar con TreeBar y las distintas escenas que puede contener en el editor.

4.3.2.3 Acciones sobre el rbol


Vamos a poder permitir distintas acciones directamente sobre el rbol: Cambiar el nombre de un elemento 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 movindolo o copindolo (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 subgrafo) desde el portapapeles sobre cualquier nodo grupo de cualquier TreeBar (instanciado o duplicado). Seleccionar mltiples elementos del rbol simultneamente

Debemos aqu introducir dos conceptos que ya hemos utilizado: Nodo instanciado: Consiste en aadir un nodo a mltiples padres. Cuando un nodo tiene dos o ms padres lo denominaremos instanciado compartido. Si un nodo est instanciado, todo su subgrafo lo estar tambin. Puesto que cada padre comparte el mismo nodo, cualquier cambio hecho al nodo, ser apreciable del mismo modo por todos sus padres.

107

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Nodo duplicado: consiste en duplicar el contenido del nodo, de manera que sea asignado a un solo padre. El contenido de cada uno de estos nodos duplicados ser independiente de los dems.

Figura 4-10. Los dos mtodos de instanciado y duplicado posibles en el editor.

4.3.2.4 Mostrar la informacin de un nodo del grafo


Cuando un usuario seleccione un nodo del control de rbol, se mostrar en el interfaz de usuario siguiendo los siguientes pasos: 1. Si el NodeType del nodo a mostrar no ha creado todavia sus dilogos, indicamos al gestor de parmetros que los cree recursivamente (recorriendo su rbol de herencia). 2. Si exista ya un nodo mostrado en pantalla a. Si el tipo de nodo a mostrar es distinto que el que exista, ocultamos los controles del antiguo NodeType y mostramos los del nuevo. b. Adems, si los nodos asociados a los respectivos NodeTypes son distintos, notificamos Fin de Seleccin al NodeType, puesto que vamos a mostrar otro nodo distinto. 3. Sin, simplemente mostramos el contenido del dilogo (su Grupo de parmetros) asociado al NodeType. 4. Asignamos este nodo como el nodo actual asociado al NodeType y mostramos los valores de sus parmetros en los controles del dilogo.

4.3.3 Anlisis de la interaccin con el visor del editor


Ya hemos analizado la representacin en rbol del grafo, y como mostrar y poder manipular los parmetros de los nodos y de otros tipos de datos. Tambin dispondremos de un visor con el resultado en tiempo real del grafo de escena. Es decir, cualquier cambio realizado sobre los parmetros de los nodos, o sobre la estructura del grafo en s (manipulando el rbol), se ver automticamente reflejado en el visor. El visor nos debera permitir: Seleccionar objetos usando el ratn. Desplazar objetos usando el ratn. Rotar objetos usando el ratn. Escalar objetos usando el ratn. Duplicar objetos usando el ratn.

108

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Enfocar a un objeto. Mover / Rotar la cmara usando el ratn. 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 representacin en alambre de la escena. Mostrar una representacin slida de lo objetos. Mostrar un sombreado plano de la escena. Mostrar un sombreado suavizado de la escena.

4.3.3.1 El gestor de seleccin


El gestor de seleccin ser una estructura que gestione los objetos que hay visualmente seleccionados en el visor, y presentar distintas funcionalidades: o o o o o o o Encontrar los objetos que intersecten con el puntero del ratn. Establecer la seleccin actual Consultar elementos seleccionados. Se encargar de actualizar las cajas de seleccin. Se encargar de actualizar el eje manipulador. Procesar los eventos del ratn sobre el visor. Gestionar las operaciones aplicables a una seleccin: Traslacin Rotacin Escalado Duplicado Borrado

Puesto que un objeto puede identificarse como mltiples instancias en un mismo nodo del grafo de escena, los objetos de la seleccin vendrn identificados por los distintos elementos del rbol que ocupen. 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 interseccin de una linea con los distintos objetos de la escena. Esta clase nos devuelve una 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 grafo desde la raz hasta llegar al un nodo descendiente, en este caso un nodo hoja. El NodePath es la manera que tiene OpenSceneGraph de identificar de manera nica un nodo instanciado. Por tanto, tendremos q crear un mtodo por el cual obtengamos un elemento del rbol a partir del NodePath del grafo de escena.

4.3.3.2 El eje manipulador


El eje manipulador no es ms que una representacin visual de los tres ejes de coordenadas, que permitirn al usuario realizar transformaciones sobre los objetos de manera muy sencilla e intuitiva. Este manipulador es muy comn en los ltimos editores de modelado 3D.

109

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

De esta manera se agiliza a la hora de realizar transformaciones sobre uno o dos ejes simultneamente. Este eje se mostrar siempre en el centro de la seleccin, y ser el gestor de seleccin el encargado de actualizarlo.

Figura 4-11. Eje manipulador en 3ds max (conocido como translate guizmo).

4.3.3.3 Creacin automtica de Matrices de Transformacin


En OpenSceneGraph son necesarias las matrices de transformacin (MatrixTransform) para aplicar cualquier transformacin 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 transformacin, en el objeto no se apreciar ningun cambio a no ser que exista alguna matriz de transformacin asociada al nodo. La solucin pues, consiste en crear automticamente una matriz de transformacin como padre del objeto que acabamos de seleccionar. El problema surje cuando, al seleccionar un objeto y crear automticamente su MatrixTransform, aadimos otro hijo a esta matriz. En ese caso, cuando intentemos transformar el primero objeto de nuevo, la transformacin afectar al segundo objeto que hemos aadido. La solucin a esto es comprobar siempre, al seleccionar un objeto, si existe la matriz de transformacin como padre del objeto y adems solo tiene un hijo. En caso contrario, tendremos que crear una matriz nueva justo encima del objeto. La figura 4-12 explica visualmente la solucin a este problema.

110

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 4-12. Creacin automatica de la Matriz de Transformacin para la seleccin de objetos. 1. Tenemos dos objetos sin nimguna matriz de transformacion. 2. Seleccionamos la piramide, entonces se crear una matriz de transformacion como su padre (MT1). 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 operacin que en el paso 2. Y lo mismo ocurrir cuando seleccionemos la pirmide.

4.3.3.4 Traslacin de objetos usando el eje manipulador


Vamos a hacer un anlisis profundo sobre la traslacin de objetos usando el eje manipulador, puesto que queremos que esta sea lo ms intuitiva posible. Algunos de los editores que permiten modificar la traslacin de un objeto, tan solo toman las coordenadas X e Y del ratn y las aplican al eje que estemos modificando. Esto da como resultado un comportamiento poco realista, incluso desde algunos puntos de vista de la cmara puede ser incmodo, y a veces puede hasta ocurrir que el desplazamiento del objeto en el visor sea justamente el contrario del desplazamiento del ratn. Sin embargo la mayora de editores comerciales se han preocupado bastante ms en que esto no ocurra. Si queremos desplazar un objeto, el objeto ir justo donde vaya el puntero del ratn. Puesto que el eje manipulador solo permite seleccionar como mximo dos ejes simultneamente, sabremos exactamente donde desplazar el objeto a lo largo de un plano imaginario formado por estos dos ejes y la interseccin entre la linea que forma el puntero del ratn con la perpendicular a la pantalla, y dicho plano.

1. Partimos de un punto de la pantalla que representa la posicin actual del puntero del ratn, este punto representar el punto donde queremos desplazar el objeto. 2. Debemos convertir ese punto en una lnea en el espacio 3D 3. Hallamos un plano imaginario en funcin de los ejes que estamos modificando, que pase por el centro del objeto que queremos modificar.

111

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4. Hallaremos la interseccin de esa lnea con el plano imaginario que acabamos de calcular, obteniendo un punto en el espacio 3D. 5. Moveremos el objeto seleccionado hasta ese punto. De esta manera el usuario tendr la sensacin de estar moviendo el objeto exactamente donde quiere. En la figura 4-13 podemos ver una imagen que representa visualmente el algoritmo explicado.

Figura 4-13. Clculo de la posicin 3D de un objeto en el plano ZY en funcin de las coordenadas de pantalla.

4.3.3.5 Representacin de objetos independientes a la escena del editor


El objetivo del editor es construir un grafo de escena con todas las herramientas que el editor proporciona, cualquier elemento que vayamos aadiendo o modificando en el grafo se ver automticamente 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 existan en el grafo, ya que son necesarios por el editor, el usuario no debe de ser consciente de tales elementos existen, y su grafo tan solo est compuesto por aquellos nodos que l ha decidido. Existen dos posibilidades a esta situacin, la primera consistira 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 debern mostrar. Esta solucin 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 contendra la informacion que necesitamos. Esto se podria solucionar implementando nuestra propia clase NodeVisitor, pero supondra un coste bastante alto.

112

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Adems, todas las funciones de copiado de nodos, que se realizan de manera recursiva, tendrian que ser modificadas, complicandose bastante. La otra solucin 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 informacin 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 solucin.

Figura 4-14. Estructura del grafo del editor.

4.3.4 Anlisis del sistema deshacer / rehacer.


Necesitamos construir un sistema de historia que almacene todas las posibles acciones invertibles de nuestra aplicacin, que nos permita avanzar y retroceder en la historia. Este debe ser un sistema que permita almacenar cualquier tipo de accin, de manera flexible. Por tanto deberemos analizar unas estructuras de datos adecuadas para ello.
El concepto de Accin

Usaremos este trmino para referirnos al conjunto de comandos o modificaciones en los datos de nuestra aplicacin que se realizan agrupados como uno solo, es decir, de manera nica e indivisible. Por ejemplo, mover un objeto puede ser una accin, pero mover 15 objetos simultneamente es tambin una accin indivisible, aunque internamente implique realizar 15 movimientos de distintos objetos. Sabiendo esto, crearemos una clase virtual pura con las siguientes funciones virtuales puras: Ejecutar: Aqu ir el cdigo que ejecute de manera indivisible la accin. Obtener el nombre de la accin: devolver una cadena con el nombre representativo de la accin. Deshacer: Aqu ir el cdigo que invierta la accin ejecutada.

113

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

El gestor de Historia

Ser el encargado de almacenar las acciones, ejecutarlas, deshacerlas y/o rehacerlas. Esta clase deber mantener un puntero a la posicin actual de la historia.

4.2.7 Anlisis del sistema de plugins.


Como ya hemos mencionado anteriormente, basaremos este sistema en el sistema que utiliza 3ds max, con algunas modificaciones. Escribir un plugin implica crear objetos a partir de las clases e implementar mtodos para permitir la comunicacin entre el plugin y el sistema. La clase que utilizaremos para los plugins ser 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 debern estar precedeidas de la directiva __declspec(dllexport). Estas funciones son invocadas por el gestor de plugins y proporcionan informacin 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 comunicacin con la DLL, comprobar su versin, y obtener una instancia de cada una de las clases implementadas, almacenandola segn su nombre, y guardando una asociacion al manejador de la DLL de la cual proviene, y procesndolas para mandarlas al Gestor del tipo de clase apropiado segn su tipo. La figura 4-15 ilustra grficamente el funcionamiento del gestor de plugins.

114

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 4-15. Funcionamiento del gestor de plugins.

4.2.8 Anlisis del Manejador de Vista Activa


Como hemos dicho anteriormente, para que todo esto funcione de manera conjunta, necesitamos un sistema que sea capaz de coordinar los distintos modulos de la aplicacin, y permitir una comunicacin entre ellos, asi como inicializar los datos necesarios en el editor, asi como los de cada escena. Este sistema actar como la columna vertebral de la aplicacin. Este contendr: Una instancia del Gestor de historia. Una instancia del Gestor de TabOutputs. Una instancia del Gestor de Parmetros. Una instancia del Gestor de AttributeTypes. Una instancia del Gestor de ObjectTypes. Una instancia del Gestor de NodeTypes. Una instancia del Gestor de ventanas dockables (Bars). Una instancia del Gestor de plugins. Una instancia de MultiTreeBar. Una referencia a la escena activa. Una referencia al visor de la escena activa. Referencia a la raz del grafo de escena activo. Funciones de mbito global: o Crear e inicializar las estructuras de datos pertinentes al abrir una escena o Liberar memoria al cerrar una escena o Cambiar la vista activa o Guardar la escena actual en disco

115

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

o o o o o o o o

Inicializar los ObjectTypes, Nodetypes y AttributeTypes iniciales en la aplicacin. Inicializar los plugins. Inicializar las ventanas dockables de la aplicacin. Inicializar el rbol. Insertar nodos en el arbol Copiar nodos del arbol Ejecutar una accin Mostrar la informacin de un Nodo del grafo.

En la figura 4-16 se puede ver un dibujo que representa la funcionalidad del manejador de vista activa (Active View Handler).

Figura 4-16. Esquema general de la arquitectura del sistema.

116

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4.4 Casos de uso


4.4.1 Funciones del sistema.
Referencia

Nombre funcin
Iniciar aplicacin Iniciar Barras Crear barra de paneles de comandos Iniciar Tipos de objeto Registrar un TabOutput Registrar un ObjectType Mapear los grupos de parmetros de un TabOutput Cargar Plugins Cerrar aplicacin Cerrar TreeBar Cerrar Escena Cargar Escena Establecer un grafo sobre un elemento del rbol Replicar una escena de una TreeBar a otra Clonar un TreeCtrl a partir de otro Nueva Escena Crear grafo por defecto Nuevo rbol Insertar fichero Cambiar escena activa Deshacer Rehacer Crear Nodo Crear un nodo segn el nombre de su NodeType Crear nueva instancia de un nodo segn su nombre Seleccionar elemento en rbol Seleccionar todas las instancias de un elemento Seleccionar todos los mirrors de un elemento Mostrar la informacin de un nodo Crear los dilogos de un TabOutput Crear un dialogo a partir de un grupo de parmetros Generar el contenido de un TabOutput Vaciar el contenido de un TabOutput Notificar fin de seleccin de un ObjectType Mostrar los datos de un TabOutput Seleccionar nodo en visor Agregar nodo a la seleccin del visor Crear Matriz de Transformacin como padre de un nodo

Categora
Evidente Oculta Oculta Oculta Oculta Oculta Oculta Oculta Evidente Evidente Evidente Evidente Oculta Oculta Oculta Evidente Oculta Evidente Evidente Evidente Evidente Evidente Evidente Oculta Oculta Evidente Oculta Oculta Evidente Oculta Oculta Oculta Oculta Oculta Oculta Evidente Evidente Oculta

F.1 F.1.1 F.1.2 F.1.3 F.1.4 F.1.5 F.1.6 F.1.7 F.2 F.2.1 F.3 F.4 F.4.1 F.4.2 F.4.3 F.5 F.5.1 F.6 F.7 F.8 F.9 F.10 F.11 F.11.1 F.11.2 F.12 F.12.1 F.12.2 F.12.3 F.12.4 F.12.5 F.12.6 F.12.7 F.12.8 F.12.9 F.13 F.13.1 F.13.2

117

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.13.3 F.13.4 F.14 F.14.1 F.15 F.16 F.16 F.17 F.18 F.19 F.20 F.21 F.22 F.23 F.24 F.24.1 F.24.2 F.24.3 F.25 F.25.1 F.25.2 F.25.3 F.26 F.26.1 F.26.2 F.26.3 F.27 F.28 F.29 F.30 F.31 F.32 F.33 F.34 F.34.1 F.34.2 F.35 F.36 F.37 F.38 F.39 F.40 F.41 F.42 F.43 F.44 F.45 F.46

Actualizar la seleccin Actualizar el eje manipulador Copiar nodo Replicar seleccin Mover nodo Duplicar nodo Duplicar seleccin Eliminar nodo Activar modo seleccin Activar modo traslacin de objetos Activar modo escalado de objetos Activar modo rotacin objetos Activar modo rotar vista Activar modo trasladar vista Escalar seleccin Comenzar escalado de seleccin Realizar escalado de seleccin Finalizar escalado de seleccin Rotar seleccin Comenzar rotacin de seleccin Realizar rotacin de seleccin Finalizar rotacin de seleccin Trasladar seleccin Comenzar traslacin de seleccin Realizar traslacin de seleccin Finalizar traslacin de seleccin Centrar vista en seleccin Modificar el zoom de la vista Aadir StateAttribute a StateSet Eliminar un StateAttribute de un StateSet Aadir un Modo a un StateSet Eliminar un Modo de un StateSet Modificar un Modo de un StateSet Modificar parmetro de un control del panel de comandos Establecer el valor de un parmetro Obtener el valor de un parmetro Establecer el contenido del portapapeles Pegar el contenido del portapapeles Visualizar escena en modo de alambre Visualizar escena en modo relleno Visualizar sombreado en modo plano Visualizar sombreado en modo suavizado Mostrar vista superior de la escena Mostrar vista inferior de la escena Mostrar vista anterior de la escena Mostrar vista posterior de la escena Mostrar vista lateral izquierda de la escena Mostrar vista lateral derecha de la escena

Oculta Oculta Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Oculta Oculta Oculta Evidente Oculta Oculta Oculta Evidente Oculta Oculta Oculta Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Oculta Oculta Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente Evidente

118

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4.4.2 Descripcin de alto nivel de los Casos de Uso.

F.1
Caso de uso: Actores: Tipo: Descripcin:

Iniciar la aplicacin. Inicio Usuario. Evidente. Se realiza esta funcin o secuencia de funciones, cuando el usuario arranca la aplicacin, la cual iniciar el nico objeto global de la aplicacin (ActiveViewHandler), y generar una vista vaca, la cual iniciar los datos del grafo por defecto. Cuando el ActiveViewHandler arranque iniciar todos los gestores de la aplicacin, se crearan las barras de herramientas (la principal y la de creacin de nodos) iniciar la barra principal de paneles de comandos y el rbol que contendr la representacin del grafo, y adems iniciar los tipos de datos que soporta la aplicacin aadindolos a sus respectivos gestores. Es en esta fase donde se realizar tambin la carga de los plugins.

F.1.1
Caso de uso: Actores: Tipo: Descripcin:

Iniciar Barras. Inicio Usuario. Oculta. Esta es la funcin que invoca al iniciar la aplicacin, crea la barra principal que contiene los paneles de comandos, la barra de depuracin, y el rbol del grafo de escena.

F.1.2
Caso de uso: Actores: Tipo: Descripcin:

Crear barra de paneles de comandos. Inicio Usuario. Oculta. Esta funcin es invocada por la funcin de iniciar las barras. En concreto inicia el panel principal de comandos que consta de cinco pestaas, cada una con una funcionalidad caracterstica en la aplicacin, asignando un icono representativo a cada una de ellas. Inicialmente el contenido de estas pginas ser propertysheets vacos,

119

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

que mas adelante sern rellenados con dilogos desplegables q sern los que contendrn los controles.

F.1.3
Caso de uso: Actores: Tipo: Descripcin:

Iniciar tipos de objeto. Inicio Usuario. Oculta. En esta funcin se crean las instancias de los TabOutput iniciales, entre los que se encuentra el panel de plugins, los cuales se cargan al iniciarse, as como los tipos de objeto soportados por el editor, los tipos de nodo y los StateAttributes.

F.1.4
Caso de uso: Actores: Tipo: Descripcin:

Registrar un TabOutput. Inicio Usuario. Oculta. Esta funcin registra un objeto tipo TabOutput en la aplicacin. Esta funcin aade 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 funcin de mapeo de los grupos de parmetros que tenga el objeto.

F.1.5
Caso de uso: Actores: Tipo: Descripcin:

Registrar un ObjectType. Inicio Usuario. Oculta. Esta funcin registra un objeto tipo ObjectType en la aplicacin. Aade a sus tablas internas la referencia a esta nueva instancia a registrar, y la indexa por su nombre, adems averigua el ObjectType de su padre (si lo tiene) y le asigna el enlace pertinente. Por ultimo realiza una llamada a la funcin de mapeo de los grupos de parmetros que tenga el objeto.

F.1.6
Caso de uso:

Mapear los grupos de parmetros de un TabOutput. Inicio

120

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Actores: Tipo: Descripcin:

Usuario. Oculta. Esta funcin se invoca al registrar un TabOutput, ObjectType, NodeType o AtributeType. Realiza la llamada a la creacin de los grupos de parmetros del TabOutput en cuestin. Una vez hecha, se mapea en la tablas hash el id de cada uno de sus descriptores de los grupos de parmetros asociando como clave en descriptor en s. De esta manera tenemos una tabla hash que asocia Ids de parmetros con sus respectivos descriptores.

F.1.7
Caso de uso: Actores: Tipo: Descripcin:

Cargar Plugins. Inicio Usuario. Oculta. Al iniciar la aplicacin se realiza una llamada a Iniciar los tipos de objeto, entre ellos los TabOutput con los que cuenta la aplicacin inicialmente. Uno de ellos es el creador de nodos, disponible en la primera pestaa, y otro es la pestaa de visualizacin de plugins. Este TabOutput es quien, al iniciar, realiza el escaneo del directorio de plugins, el gestor de plugins los guarda en sus tablas y se encarga de cargarlos en memoria, una vez cargados, los objetos que contiene cada plugin las distribuye entre sus distintos gestores de elementos, segn su tipo.

F.2
Caso de uso: Actores: Tipo: Descripcin:

Cerrar aplicacin. Cerrar aplicacin Usuario. Evidente. Al cerrar la aplicacin se realizan llamadas a Cerrar para todos los TreeBar del programa. Puesto que cada TreeBar contiene el rbol del grafo de escena de una o varias escenas, se cierran estas escenas, que implican liberar sus recursos, as como se vaca toda la historia de todas las escenas. Del mismo modo, se liberan todos los recursos adquiridos por la librera OpenSceneGraph.

121

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.2.1
Caso de uso: Actores: Tipo: Descripcin:

Cerrar treebar Cerrar aplicacin Usuario. Oculta Al cerrar un nico TreeBar tendremos que liberar tan solo la memoria referente a los mirror de las escenas actuales. Dado que la TreeBar que estamos cerrando no es ms 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 aplicacin a los HTREEITEMS correspondientes, puesto que ya no van a existir ms. Por ultimo, deberemos eliminarla de la lista de MultiTreeBar

F.3
Caso de uso: Actores: Tipo: Descripcin:

Cerrar escena. Cerrar escena Usuario. Evidente. Esta funcin se invoca al cerrar una vista de la escena. Por tanto, deberemos vaciar la seleccin actual, liberar los recursos de la escena de OpenSceneGraph que todava queden sin liberar, vaciar la historia de esta escena (cada escena tiene su propia historia). Al cerrar la escena se debern eliminar todos los rboles de esta escena pertenecientes a cada una de las TreeBar, as como limpiar cualquier informacin de el ltimo nodo que se seleccion y pueda estar representado en pantalla para evitar que el usuario intente modificarlo despus de haberse liberado de la memoria.

F.4
Caso de uso: Actores: Tipo: Descripcin:

Cargar escena. Cargar escena Usuario. Evidente. Cargar una escena implica seleccionar un fichero del disco duro. Una vez hecho, se realizar la carga del fichero mediante las funciones que proporciona OpenSceneGraph de carga de ficheros. Seguidamente se iniciar un grafo por defecto para colgar esta informacin. El grafo no deber ser el fichero en s, puesto que el editor necesita ms elementos para visualizar de manera axiliar. Por tanto, el grafo inicial estar dividido en dos ramas principales, la primera ser la escena donde colgaremos el fichero que acabamos de cargar, y en la segunda

122

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

almacenaremos aquellos nodos que nos sern tiles en el editor para manipular otros nodos, como puede ser el eje manipulador, las cajas de seleccin de objetos, e incluso la rejilla. Una vez hecho esto, deberemos aadir una nueva escena al editor, esto implica crear nuestro propio grafo de escena (copia del de OpenSceneGraph), y aadir un nuevo control de rbol en cada una de las TreeBar, clonando su contenido tantas veces como sea necesario. Tambin aqu ser donde inicialicemos los datos de la seleccin, y el StateSet global, que nos servir para cambiar el modo de visualizacin de la escena.

F.4.1
Caso de uso: Actores: Tipo: Descripcin:

Establecer un grafo sobre un elemento del rbol. Cargar escena Usuario. Oculta. Permite establecer un grafo colgando de un elemento de un rbol. Este elemento puede ser la raz del rbol, por lo que el rbol no debe necesariamente contener algn elemento. Esta funcin internamente establece el grafo de escena sobre una de las vistas del rbol (suponiendo que haya varias simultneas) y realiza rplicas del mismo sobre las dems. 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 subrbol sobre el rbol que queremos y completando nuestro grafo interno. Esta funcin 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
Caso de uso: Actores: Tipo: Descripcin:

Replicar una escena de una TreeBar a otra. Cargar escena Usuario. Oculta. 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 aadir la informacin 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.

123

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.4.3
Caso de uso: Actores: Tipo: Descripcin:

Clonar un TreeCtrl a partir de otro. Cargar escena Usuario. Oculta. Esta funcin 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 padre deber existir en el rbol destino como tem equivalente o mirror. La replica o clonacin 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.

F.5
Caso de uso: Actores: Tipo: Descripcin:

Nueva escena. Nueva escena Usuario. Evidente. Cuando el usuario desea crear una nueva escena vaca puede pulsar sobre el botn de nueva escena o acceder al men y crear una nueva escena. Es entonces cuando se inician las estructuras de datos necesarias para una escena (al igual que al cargar una escena). Se iniciar un grafo por defecto para colgar esta informacin. Una vez hecho esto, deberemos aadir una nueva escena al editor. Esto implica crear nuestro propio grafo de escena (copia del de OpenSceneGraph), y aadir un nuevo control de rbol en cada una de las TreeBar, clonando su contenido tantas veces como sea necesario. Tambin aqu ser donde inicialicemos los datos de la seleccin, y el StateSet global, que nos servir para cambiar el modo de visualizacin de la escena.

F.5.1
Caso de uso: Actores: Tipo: Descripcin:

Crear grafo por defecto. Nueva escena Usuario. Oculto. El grafo no deber ser la escena en s, puesto que el editor necesita ms elementos para visualizar de manera axiliar. Por tanto, el grafo inicial (raz) estar dividido en dos ramas principales, la primera ser la escena que vamos a crear, y en la segunda colgaremos aquellos nodos que nos

124

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

sern tiles en el editor para manipular otros nodos, como puede ser el eje manipulador, las cajas de seleccin de objetos, e incluso la rejilla.

F.6
Caso de uso: Actores: Tipo: Descripcin:

Nuevo rbol. Nuevo rbol Usuario. Evidente. Esta funcin se invoca cuando el usuario desea crear una nueva vista de rbol que representa el grafo de escena. Lo que esta funcin hace es crear una nueva TreeBar, inicialmente vaca, y replicar todos y cada uno de las escenas que contiene esta TreeBar en la que acabamos de crear. La funcin para replicar esto ya la hemos analizado en F.4.2.

F.7
Caso de uso: Actores: Tipo: Descripcin:

Insertar fichero. Insertar Fichero Usuario. Evidente. Cuando el usuario desea colgar de una rama un grafo completo, almacenado en el disco duro, entonces se invocar esta funcin. El usuario seleccionar del disco duro un fichero compatible con la aplicacin, 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 F4.1 ya que nos permite establecer un grafo sobre cualquier elemento de un rbol.

F.8
Caso de uso: Actores: Tipo: Descripcin:

Cambiar escena activa. Cambiar Escena Activa Usuario. Evidente. Se produce esta llamada a esta funcin cuando el usuario realiza un cambio de la escena activa, ya sea mediante alguna combinacin del teclado o usando el men de seleccin 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 seleccin, puesto que son independientes en cada escena, y cada escena tiene las suyas.

125

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.9
Caso de uso: Actores: Tipo: Descripcin:

Deshacer. Deshacer Usuario. Evidente. El usuario realiza esta accin cuando quiere deshacer la ltima accin ejecutada. El gestor de historia ser en encargado de realizar la llamada a deshacer sobre la ltima accin y de retroceder el cursor de posicin sobre la historia.

F.10
Caso de uso: Actores: Tipo: Descripcin:

Rehacer. Rehacer Usuario. Evidente. El usuario realiza esta accin cuando quiere rehacer la ltima accin deshecha. El gestor de historia ser en encargado de realizar la llamada a rehacer sobre la ltima accin y de avanzar el cursor de posicin sobre la historia.

F.11
Caso de uso: Actores: Tipo: Descripcin:

Crear Nodo. Crear Nodo Usuario. Evidente. El usuario podr crear un nodo sobre el elemento que est actualmente seleccionado en el rbol del grafo de escena, seleccionndolo desde una lista de nodos del panel de comandos, o pulsando un botn en forma de icono que identifica tal nodo.

F.11.1
Caso de uso: Actores:

Crear un nodo segn el nombre de su NodeType. Crear Nodo Usuario.

126

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Tipo: Descripcin:

Oculta. Esta funcin 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 funcin que devuelva una nueva instancia del tipo de nodo que devuelve en NodeType en cuestin. Este nodo deberemos aadirlo al grafo de escena del editor y de OpenSceneGraph, as como aadirlo a todas las vistas que haya abiertas en el editor y aadir la informacin necesaria en las tablas de ndices de las estructuras de datos del grafo y de los rboles.

F.11.2
Caso de uso: Actores: Tipo: Descripcin:

Crear una nueva instancia de un nodo segn su nombre. Crear Nodo Usuario. Oculta. Cada NodeType debe de tener implementada la funcin NewInstance, que debe de devolver una nueva instancia del tipo de nodo que est representando. Cuando el gestor de NodeTypes quiere obtener una nueva instancia de un tipo de nodo a partir de su nombre (por ejemplo cuando el usuario quiere crear un tipo de nodo al seleccionarlo de la lista, por su nombre), busca entre sus ndices si existe el NodeType segn el nombre, y en ese caso, invoca a la funcin NewInstance, que devolver el objeto deseado.

F.12
Caso de uso: Actores: Tipo: Descripcin:

Seleccionar elemento en rbol. Seleccionar elemento en rbol Usuario. Evidente. Un usuario puede seleccionar un tem del rbol tan solo pulsando sobre l para mostrar sus propiedades. Al seleccionar un elemento del rbol el editor tiene acceso directamente al tem del rbol seleccionado. Puesto que el rbol mantiene una correspondencia de cada tem con su nodo del grafo del editor, podremos saber qu nodo, y en consecuencia qu tipo de nodo (NodeType) hemos seleccionado. Es entonces cuando marcaremos en cierto color todas las instancias de ese mismo nodo, y en rojo las equivalencias de esas mismas instancias en los dems TreeBars. Adems, ya disponiendo del tipo de nodo que estamos tratando, pasaremos a visualizar en el panel de comandos, todos los grupos de parmetros asociados a ese tipo de nodo, ocultando previamente los del nodo anteriormente seleccionado, y rellenaremos la informacin de salida con la informacin del nodo en cuestin.

127

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.12.1
Caso de uso: Actores: Tipo: Descripcin:

Seleccionar todas las instancias de un elemento. Seleccionar elemento en rbol Usuario. Evidente. Esta funcion simplemente sirve como ayuda visual para que el usuario pueda 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 parmetro que modifique de este elemento del rbol, afectar a todas sus instancias, que podr apreciar marcadas de distinto color.

F.12.2
Caso de uso: Actores: Tipo: Descripcin:

Seleccionar todos los mirrors de un elemento. Seleccionar elemento en rbol Usuario. Evidente. Esta funcin simplemente sirve como ayuda visual para que el usuario pueda identificar de una manera sencilla e intuitiva la correspondencia de un elemento de un rbol con su equivalente en las dems vistas del mismo rbol.

F.12.3
Caso de uso: Actores: Tipo: Descripcin:

Mostrar la informacin de un nodo Seleccionar elemento en rbol Usuario. Evidente. Esta funcin se invoca cuando hemos seleccionado un nodo del rbol. Para mostrar la informacin de un nodo necesitamos su NodeType. Una vez adquiridos ambos, podemos comenzar a mostrar la salida. Si es la primera vez que un NodeType se muestra, se realiza la llamada a generar sus dilogos en tiempo real. Esto se hace para intentar ahorrar recursos y no crear aquellos dilogos que no se lleguen a utilizar durante la ejecucin del programa. Si exista algn NodeType anterior mostrado, y distinto al actual, entonces lo ocultamos y mostramos el nuestro. Al mostrar el NodeType mostraremos de manera recursiva el contenido de los controles de este, y el de su padre, de manera que el pare siempre se muestre por encima de su hijo. Del mismo nodo, si hemos cambiado el NodeType deberemos lanzar una notificacin de fin

128

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

de seleccin, y por ltimo, rellenaremos los controles con los datos del nodo que queremos mostrar.

F.12.4
Caso de uso: Actores: Tipo: Descripcin:

Crear los dilogos de un TabOutput Seleccionar elemento en rbol Usuario. Oculta. Como hemos comentado en F12.3 la primera vez que se llama a mostrar un NodeType se crean dinmicamente los dilogos que contendrn los controles que mostrarn los datos del nodo. Esta funcin es recursiva y se llamar del mismo modo sobre su tipo padre, si as lo requiere. Para ello, se accede al vector del grupo de parmetros que debe de contener el NodeType por la funcin 1.6. Este vector contiene informacin de los distintos grupos o agrupaciones de parmetros que puede tener un nodo. Normalmente solo tendr un grupo, podr indicar de manera opcional en que pestaa del panel de comandos aparecer, y cada grupo estar compuesto por un conjunto de descriptores de parmetros. Por tanto, para cada grupo crearemos un dilogo que ir contenido dentro de lo que llamaremos una pgina desplegable (o Rollup Page, puesto que tendr un botn que permitir plegar o desplegar el contenido del dilogo) que se mostrar en alguna de las pestaas del panel de comandos.

F.12.5
Caso de uso: Actores: Tipo: Descripcin:

Crear un dilogo a partir de un grupo de parmetros Seleccionar elemento en rbol Usuario. Oculta. Esta funcin se invoca al crear los dilogos de un TabOutput. Cada uno de los grupos de parmetros que forman un TabOutput est formado a su vez por un conjunto de descriptores de parmetros. Cada uno de estos descriptores contendr informacin sobre cada uno de los controles que deber contener el dilogo que se va a construir dinmicamente. Entre esta informacin encontraremos, el nombre del control, el tipo de control, y si es editable o no, por ejemplo. Por tanto, en cada tipo de descriptor realizaremos una llamada distinta para crear un tipo de control distinto. Por ltimo, realizaremos una ltimos ajustes a los controles, como por ejemplo ajustar el numero mximo de caracteres en los campos de texto, o si deshabilitaremos el control inicialmente en caso de que as lo indique el descriptor.

129

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.12.6
Caso de uso: Actores: Tipo: Descripcin:

Generar el contenido de un TabOutput Seleccionar elemento en rbol Usuario. Oculta. Esta funcin es invocada directamente por la funcin 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 pgina desplegable o Rollup a partir de un dilogo ya generado. Una vez hecho esto, el dilogo estar contenido en un deplegable que el usuario podr plegar siempre que quiera tan solo pulsando un botn, para ahorrar espacio en el interfaz, y desplegar cuando quiera mostrar su contenido de nuevo.

F.12.7
Caso de uso: Actores: Tipo: Descripcin:

Vaciar el contenido de un TabOutput Seleccionar elemento en rbol Usuario. Oculta. Es la funcin inversa a la anterior. Suele invocarse cuando queremos limpiar la salida del panel de comandos, bien para dejarlo vaco, bien para dar paso a generar el contenido de otro TabOutput. Esta llamada desvincula el dilogo que identifica en grupo de parmetros del Rollup en el que est contenido, pero no destruye en dilogo que hemos creado de la memoria.

F.12.8
Caso de uso: Actores: Tipo: Descripcin:

Notificar fin de seleccin de un ObjectType Seleccionar elemento en rbol Usuario. Oculta. El ObjectType tiene la particularidad de que es notificado cuando su contenido que est actualmente siendo mostrado por pantalla va a ser eliminado y sustituido por otro, ya sea del mismo tipo o de un tipo distinto, pero de contenido distinto. Esta funcin se invoca de manera recursiva, de modo que la notificacin llegar tanto el ObjectType como a sus precedentes en la jerarqua de herencia que se haya establecido. Esta notificacin se realiza para que el desarrollador de ObjectTypes pueda realizar los ajustes que crea convenientes al ser consciente de que el objeto va a dejar de editarse.

130

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.12.9
Caso de uso: Actores: Tipo: Descripcin:

Mostrar los datos de un TabOutput Seleccionar elemento en rbol Usuario. Oculta. Esta es la funcin culminante en el proceso de mostrar el contenido de un nodo. 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 funcin es la que realizar la llamada a la funcin que implemente el desarrollador para mostrar los datos del nodo. El comportamiento de tal funcin depender de la implementacin que el desarrollador haya dado al TabOutput o el ObjectType.

F.13
Caso de uso: Actores: Tipo: Descripcin:

Seleccionar nodo en el visor Seleccionar nodo en el visor Usuario. Evidente. Se llama a esta funcin cuando queremos seleccionar un nodo en el visor. Este nodo, generalmente un Geode, se puede seleccionar pulsando directamente sobre el elemento en la pantalla, o seleccionndolo en el rbol e indicando explcitamente que queremos seleccionarlo en el visor. Al seleccionar un objeto del visor tendremos que generar una informacin del objeto seleccionado, y crear una caja de seleccin que nos indique la posicin del objeto y el rea que ocupa. Este objeto que contiene informacin de seleccin se aadir a una lista, que consistir en una lista de las informaciones de todos los objetos seleccionados. Puesto que se trata de una seleccin nica, deberemos previamente vaciar la seleccin existente.

F.13.1
Caso de uso: Actores: Tipo: Descripcin:

Agregar nodo a la seleccin del visor Seleccionar nodo en el visor Usuario. Evidente. Esta funcin es equivalente a la anterior, solo que en este caso, en lugar de seleccionar solo el elemento que queremos, lo aadiremos a la seleccin actual.

131

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.13.2
Caso de uso: Actores: Tipo: Descripcin:

Crear Matriz de Transformacin como padre de un nodo. Seleccionar nodo en el visor Usuario. Oculta. Esta funcin se llama automticamente al seleccionar un objeto. La razn de ello es que al seleccionar un objeto, el usuario est indicando en cierto modo su intencin de aplicarle alguna transformacin. Esta transformacin solo se puede llevar a cabo sobre una Matriz de Transformacin que contenga al nodo como uno de sus descendientes. Por tanto, lo que har esta funcin ser comprobar si existe una matriz de transformacin como padre del nodo, y adems, que esa transformacin solo tenga a ese nodo como hijo. En caso contrario, creamos un nuevo nodo tipo Matriz de Transformacin y lo intercalamos entre el nodo que queremos transformar y su padre actual.

F.13.3
Caso de uso: Actores: Tipo: Descripcin:

Actualizar la seleccin. Seleccionar nodo en el visor Usuario. Oculta. Lo que esta funcin hace realmente es actualizar el cursor segn su posicin, o el eje manipulador, adems del estado del cursor. El estado del cursor define si el cursor est encima de algn objeto, o encima de algn otro elemento, como puede ser el eje manipulador. En primer lugar se comprueba si existe algn objeto seleccionado en la escena, en ese caso sabremos que el eje manipulador estar mostrado por tanto obtenemos si existe alguna colisin del cursor con tal eje. Si el cursor no esta encima de ningn elemento del eje manipulador entonces se comprueba si existe colisin con alguno de los objetos, actualizando el cursor y el estado del cursor en funcin de si el eje est o no seleccionado, y de la transformacin que estemos llevando a cabo.

F.13.4
Caso de uso: Actores: Tipo:

Actualizar el eje manipulador. Seleccionar nodo en el visor Usuario. Oculta.

132

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Descripcin:

Esta funcin realiza las mismas comprobaciones que la anterior, pero nicamente comprueba si existe alguna interseccin del cursor del ratn 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 ms 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.

F.14
Caso de uso: Actores: Tipo: Descripcin:

Copiar nodo. Copiar nodo Usuario. Evidente. Esta funcin se encarga de copiar un elemento del rbol a otro elemento destino. Este nodo se podr copiar como hijo del nodo destino o como hermano del nodo destino. Adems, el elemento podr copiarse desde un rbol hasta otro distinto, siempre que pertenezcan al mismo grafo. En esta aplicacin, cuando hablamos de copiar un elemento, lo que realmente estaremos haciendo ser instanciarlo, es decir, crearemos una nueva instancia en el rbol, y en el grafo lo que nicamente haremos ser aadir un nuevo padre al nodo que estamos copiando. Esta misma operacin deber repetirse (excepto la modificacin la vinculacin de los elementos del grafo) para todas las vistas que existan duplicadas del rbol del grafo de escena.

F.14.1
Caso de uso: Actores: Tipo: Descripcin:

Replicar seleccin. Copiar nodo Usuario. Evidente. Realiza una rplica del nodo haciendo uso de la funcin copiar nodo, creando su propia matriz de transformacin y desplazando el objeto una distancia respecto del objeto a copiar y tomando como nodo padre el mismo nodo padre del nodo origen.

F.15
Caso de uso: Actores: Tipo:

Mover nodo. Mover nodo Usuario. Evidente.

133

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Descripcin:

Esta funcin es exactamente igual que la anterior, con la nica diferencia que despus de copiar el nodo, el nodo origen se elimina, tanto del rbol, como el enlace de su padre.

F.16
Caso de uso: Actores: Tipo: Descripcin:

Duplicar Nodo. Duplicar nodo Usuario. Evidente. Al igual que la funcin Copiar Nodo, esta funcin se encarga de copiar un elemento del rbol a otro elemento destino. Este nodo se podr copiar como hijo del nodo destino o como hermano del nodo destino. En esta ocasin usamos el termino Duplicar, para decir que no vamos a instanciar el nodo, sino que vamos a duplicar por completo el nodo y todos sus descendientes, de manera que la rama que hayamos duplicado ser complemente independiente de la rama origen y cualquier modificacin sobre cualquier nodo de cualquier elemento duplicado no tendr ningn efecto sobre los originales. El procedimiento es el mismo, solo que al copiar los elementos del rbol, adems, copiaremos los elementos del grafo tambin (en el caso de copiar nodo, tan solo agregbamos un padre ms). Duplicar Seleccion. Duplicar nodo Usuario. Evidente. Realiza una rplica del nodo haciendo uso de la funcin duplicar nodo, creando su propia matriz de transformacin y desplazando el objeto una distancia respecto del objeto a duplicar y tomando como nodo padre el mismo nodo padre del nodo origen.

F.16.1
Caso de uso: Actores: Tipo: Descripcin:

F.17
Caso de uso: Actores: Tipo: Descripcin:

Eliminar nodo. Eliminar nodo Usuario. Evidente. Esta funcin elimina un elemento o instancia de un elemento del grafo. Para ello deber deseleccionarlo del visor en caso de que se encuentre seleccionado, y eliminarlo de todas las vistas de rbol que haya abiertas. Adems deber actualizar la informacin del grafo del editor puesto que contiene referencias a los tems del rbol, eliminando las referencias

134

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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
Caso de uso: Actores: Tipo: Descripcin:

Activar modo seleccin. Activar modo seleccin Usuario. Evidente. Se invoca esta funcin cuando el usuario quiere activar el modo de seleccin de objetos. En este modo simplemente podr seleccionar objetos en el visor, sin aplicarles ningn tipo de transformacin.

F.19
Caso de uso: Actores: Tipo: Descripcin:

Activar modo traslacin de objetos. Activar modo traslacin de objetos Usuario. Evidente. Se invoca esta funcin cuando el usuario quiere activar el modo de traslacin de objetos. Cuando este modo est activado el usuario podr aplicar transformaciones de traslacin sobre todos los objetos seleccionados en pantalla.

F.20
Caso de uso: Actores: Tipo: Descripcin:

Activar modo escalado de objetos. Activar modo escalado de objetos Usuario. Evidente. Se invoca esta funcin cuando el usuario quiere activar el modo de escalado de objetos. Cuando este modo est activado el usuario podr aplicar transformaciones de escalado sobre todos los objetos seleccionados en pantalla.

135

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.21
Caso de uso: Actores: Tipo: Descripcin:

Activar modo rotacin de objetos. Activar modo rotacin de objetos Usuario. Evidente. Se invoca esta funcin cuando el usuario quiere activar el modo de rotacin de objetos. Cuando este modo est activado el usuario podr aplicar transformaciones de rotacin sobre todos los objetos seleccionados en pantalla.

F.22
Caso de uso: Actores: Tipo: Descripcin:

Activar modo rotar vista. Activar modo rotar vista Usuario. Evidente. Se invoca esta funcin cuando el usuario quiere activar el modo de rotar la vista. Cuando este modo est activado el usuario podr girar la vista como desee para visualizar cualquier objeto en pantalla.

F.23
Caso de uso: Actores: Tipo: Descripcin:

Activar modo trasladar vista. Activar modo trasladar vista Usuario. Evidente. Se invoca esta funcin cuando el usuario quiere activar el modo de trasladar la vista. Cuando este modo est activado el usuario podr trasladar la vista como desee para visualizar cualquier objeto en pantalla.

F.24
Caso de uso: Actores: Tipo:

Escalar seleccin. Escalar seleccin Usuario. Evidente.

136

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Descripcin:

Cuando hablamos de seleccin, nos referimos a un conjunto de nodos. Por tanto no es ms que repetir la misma operacin para cada uno de los nodos. Esta funcin realiza una transformacin de escalado 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 transformacin pero de ello ya nos hemos asegurado al seleccionar el objeto. Esta funcin realmente se divide en tres sub-funciones, el comienzo, el transcurso y el final.

F.24.1
Caso de uso: Actores: Tipo: Descripcin:

Comenzar escalado de seleccin. Escalar seleccin Usuario. Oculta. Es como el Setup o la puesta a punto del escalado. Se llama a esta funcin para realizar los ajustes o actualizaciones necesarias o consultar los datos necesarios para prepararse para comenzar la transformacin. Por ejemplo, aqu recalcularemos la BoundingBox de la seleccin y deberemos guardar la posicin del centro geomtrico de la seleccin, lo cual nos servir mas adelante para almacenar correctamente la transformacin como una funcin invertible.

F.24.2
Caso de uso: Actores: Tipo: Descripcin:

Realizar escalado de seleccin. Escalar seleccin Usuario. Oculta. Esta es la funcin que realiza el escalado, aunque realmente la accin no se podr considerar como terminada hasta que soltemos el ratn. En este paso se aplica la misma transformacin a todos los objetos de la seleccin en funcin del desplazamiento del cursor sobre la pantalla, y siempre aplicndola sobre el centro geomtrico de cada objeto colocado en el origen de coordenadas. Una vez hecho esto, deberemos tambin actualizar las cajas de seleccin de los objetos seleccionados, puesto que las transformaciones deben afectarles por igual, as como actualizar su BoundingBox y la posicin del eje manipulador.

137

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.24.3
Caso de uso: Actores: Tipo: Descripcin:

Finalizar escalado de seleccin. Escalar seleccin Usuario. Oculta. Este es el paso que da por finalizado el escalado de la seleccin. Es aqu donde se actualiza la informacin de la seleccin, como por ejemplo los valores de las matrices auxiliares que se utilizan para almacenar informacin que luego servirn para almacenar la accin invertible de la transformacin. Tambin aqu actualizaremos la BoundingBox de la seleccin y actualizaremos la posicin del eje manipulador.

F.25
Caso de uso: Actores: Tipo: Descripcin:

Rotar seleccin. Rotar seleccin Usuario. Evidente. Cuando hablamos de seleccin, nos referimos a un conjunto de nodos. Por tanto no es ms que repetir la misma operacin para cada uno de los nodos. Esta funcin realiza una transformacin de rotacin 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 transformacin pero de ello ya nos hemos asegurado al seleccionar el objeto. Esta funcin realmente se divide en tres sub-funciones, el comienzo, el transcurso y el final.

F.25.1
Caso de uso: Actores: Tipo: Descripcin:

Comenzar rotacin de seleccin. Rotar seleccin Usuario. Oculta. Es como el Setup o la puesta a punto de la rotacin. Se llama a esta funcin para realizar los ajustes o actualizaciones necesarias o consultar los datos necesarios para prepararse para comenzar la transformacin. Por ejemplo, aqu recalcularemos la BoundingBox de la seleccin y deberemos guardar la posicin del centro geomtrico de la seleccin, lo cual nos servir mas adelante para almacenar correctamente la transformacin como una funcin invertible.

138

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.25.2
Caso de uso: Actores: Tipo: Descripcin:

Realizar rotacin de seleccin. Rotar seleccin Usuario. Oculta. Esta es la funcin que realiza la rotacin, aunque realmente la accin no se podr considerar como terminada hasta que soltemos el ratn. En este paso se aplica la misma transformacin a todos los objetos de la seleccin en funcin del desplazamiento del cursor sobre la pantalla, y siempre aplicndola sobre el centro geomtrico de cada objeto colocado en el origen de coordenadas. Una vez hecho esto, deberemos tambin actualizar las cajas de seleccin de los objetos seleccionados, puesto que las transformaciones deben afectarles por igual, as como actualizar su BoundingBox y la posicin del eje manipulador.

F.25.3
Caso de uso: Actores: Tipo: Descripcin:

Finalizar rotacin de seleccin. Rotar seleccin Usuario. Oculta. Este es el paso que da por finalizada la rotacin de la seleccin. Es aqu donde se actualiza la informacin de la seleccin, como por ejemplo los valores de las matrices auxiliares que se utilizan para almacenar informacin que luego servirn para almacenar la accin invertible de la transformacin. Tambin aqu actualizaremos la BoundingBox de la seleccin y actualizaremos la posicin del eje manipulador.

F.26
Caso de uso: Actores: Tipo: Descripcin:

Trasladar seleccin. Trasladar seleccin Usuario. Evidente. Cuando hablamos de seleccin, nos referimos a un conjunto de nodos. Por tanto no es ms que repetir la misma operacin para cada uno de los nodos. Esta funcin realiza una transformacin de traslacin 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 transformacin pero de ello ya nos hemos asegurado al seleccionar el objeto.

139

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Esta funcin realmente se divide en tres sub-funciones, el comienzo, el transcurso y el final.

F.26.1
Caso de uso: Actores: Tipo: Descripcin:

Comenzar traslacin de seleccin. Trasladar seleccin Usuario. Oculta. Es como el Setup o la puesta a punto de la traslacin. Se llama a esta funcin para realizar los ajustes o actualizaciones necesarias o consultar los datos necesarios para prepararse para comenzar la transformacin. Por ejemplo, aqu recalcularemos la BoundingBox de la seleccin y deberemos guardar la posicin del centro geomtrico de la seleccin, lo cual nos servir mas adelante para almacenar correctamente la transformacin como una funcin invertible.

F.26.2
Caso de uso: Actores: Tipo: Descripcin:

Realizar traslacin de seleccin. Trasladar seleccin Usuario. Oculta. Esta es la funcin que realiza la traslacin, aunque realmente la accin no se podr considerar como terminada hasta que soltemos el ratn. En este paso se aplica la misma transformacin a todos los objetos de la seleccin en funcin del desplazamiento del cursor sobre la pantalla. Esta transformacin tiene la particularidad de que requiere algunos clculos extraordinarios para calcular el incremento que vamos a aplicar a la traslacin, ya que calcularemos un plano imaginario que sea paralelo al plano seleccionado en el eje manipulador, y que pase por el centro de la seleccin, de esta manera, intersectando una lnea imaginaria desde el cursor hacia este plano obtendremos el punto donde queremos desplazar el objeto, y as calcularemos el incremento a aplicar como traslacin. Una vez hecho esto, deberemos tambin actualizar las cajas de seleccin de los objetos seleccionados, puesto que las transformaciones deben afectarles por igual, as como actualizar su BoundingBox y la posicin del eje manipulador.

F.26.3
Caso de uso:

Finalizar traslacin de seleccin. Trasladar seleccin

140

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Actores: Tipo: Descripcin:

Usuario. Oculta. Este es el paso que da por finalizada la traslacin de la seleccin. Es aqu donde se actualiza la informacin de la seleccin, como por ejemplo los valores de las matrices auxiliares que se utilizan para almacenar informacin que luego servirn para almacenar la accin invertible de la transformacin. Tambin aqu actualizaremos la BoundingBox de la seleccin y actualizaremos la posicin del eje manipulador.

F.27
Caso de uso: Actores: Tipo: Descripcin:

Centrar la vista en la seleccin. Centrar la vista en la seleccin Usuario. Evidente. Cuando el usuario quiera visualizar un objeto en el centro geomtrico de la pantalla, podr hacer uso de esta opcin. Esta funcin tan solo hace que la cmara enfoque al centro geomtrico de la seleccin actual.

F.28
Caso de uso: Actores: Tipo: Descripcin:

Modificar el zoom de la vista. Centrar la vista en la seleccin Usuario. Evidente. Esta funcin permite acercar o alejar la cmara o visor de su foco.

F.29
Caso de uso: Actores: Tipo: Descripcin:

Aadir un StateAttribute a un StateSet. Aadir un StateAttribute a un StateSet Usuario. Evidente. Esta funcin permite aadir un StateAttibute a un StateSet de un nodo del grafo de escena. El usuario deber seleccionar el StateAttribute de la lista de StateAttributes que la aplicacin soporte. Esta lista se obtiene del gestor de objetos, y es el mismo gestor de objetos el que devolver una nueva instancia del StateAttribute que elijamos.

141

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.30
Caso de uso: Actores: Tipo: Descripcin:

Eliminar un StateAttibute de un StateSet. Eliminar un StateAttribute de un StateSet Usuario. Evidente. Si el usuario as lo desea, podr eliminar los StateAttributes del StateSet de un nodo, seleccionando de la lista aquel que quiera. Del mismo modo, dispondremos del nombre del StateAttribute a eliminar, y el gestor de ObjectTypes nos devolver el tipo de StateAttribute, lo cual nos permitir directamente eliminarlo del StateSet.

F.31
Caso de uso: Actores: Tipo: Descripcin:

Aadir un Modo a un StateSet. Aadir un Modo a un StateSet Usuario. Evidente. Esta funcin permite aadir un Modo a un StateSet de un nodo del grafo de escena. El usuario deber seleccionar el Modo de la lista de Modos que la aplicacin soporte. Esta lista de modos est relacionada con los modos que OpenGL soporta.

F.32
Caso de uso: Actores: Tipo: Descripcin:

Eliminar un Modo de un StateSet. Aadir un Modo a un StateSet Usuario. Evidente. Esta funcin permite eliminar un Modo o un valor del Modo de un StateSet de un nodo del grafo de escena. El usuario deber seleccionar el Modo de la lista de Modos que el StateSet tenga actualmente.

F.33
Caso de uso: Actores: Tipo:

Modificar un Modo de un StateSet. Modificar un Modo a un StateSet Usuario. Evidente.

142

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Descripcin:

El modo de un StateSet es una mscara que puede contener varios flags, por tanto un usuario podr aadir o eliminar estos flags a un modo ya existente de un StateSet.

F.34
Caso de uso: Actores: Tipo: Descripcin:

Modificar el parmetro de un control del panel de comandos. Modificar el parmetro de un control del panel de comandos Usuario. Evidente. Cuando un usuario manipula alguno de los controles del panel de comandos donde aparecen los grupos de parmetros referentes a un nodo, a un objeto, 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 dcima su valor) y despus se realice una llamada a la notificacin de parmetro modificado. De esta manera el desarrollador de TabOutputs podr hacer las gestiones necesarias para modificar la estructura de datos asociada.

F.34.1
Caso de uso: Actores: Tipo: Descripcin:

Establecer el valor de un parmetro. Modificar el parmetro de un control del panel de comandos Usuario. Oculta. El desarrollador de TabOutputs podr establecer una interaccin con los controles asociados a los grupos de parmetros y forzar a establecer los valores que debern contener los controles. Para ello se dispondr de una funcin que permitir establecer ciertos tipos de datos conocidos por el desarrollador y soportados por la aplicacin en los controles de los paneles de comandos.

F.34.2
Caso de uso: Actores: Tipo: Descripcin:

Establecer el valor de un parmetro. Modificar el parmetro de un control del panel de comandos Usuario. Oculta. El desarrollador de TabOutputs podr establecer una interaccin con los controles asociados a los grupos de parmetros y obtener en cualquier momento el valor que el control est almacenando, guardndolo en una 143

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

estructura de datos conocida por el desarrollador. Para ello se dispondr de una funcin que permitir acceder a estos valores segn el identificador del parmetro que el desarrollador habr asignado previamente.

F.35
Caso de uso: Actores: Tipo: Descripcin:

Establecer el contenido del portapapeles. Establecer el contenido del portapapeles Usuario. Evidente. Al seleccionar elementos del rbol podremos copiarlos y pegarlos en el portapapeles del propio editor. Dependiendo de la operacin que llevemos a cabo, la operacin de pegar podr realizarse como una operacin de mover, copiar o de duplicar. Por tanto al realizar cualquier operacin de portapapeles almacenaremos el tipo de operacin de copia, y el nodo, o conjunto de nodos afectados.

F.36
Caso de uso: Actores: Tipo: Descripcin:

Pegar el contenido del portapapeles. Establecer el contenido del portapapeles Usuario. Evidente. Sabiendo la operacin previa almacenada en el portapapeles, sabremos que tipo de operacin tendremos que llevar a cabo al pegar. Puesto que tenemos un listado de items origen, y tenemos seleccionado el tem destino, podremos levar a cabo la operacin que proceda. Si la operacin del portapapeles era de copia, llevaremos a cabo la operacin de copia, si era una operacin de movimiento, llevaremos a cabo la operacin de movimiento de nodos, y si era una operacin de duplicado, duplicaremos la lista de nodos seleccionados sobre el item destino. Visualizar escena en modo de alambre. Visualizar escena en modo de alambre Usuario. Evidente. Visualiza la informacion geomtrica de la escena en modo de rejilla de alambre.

F.37
Caso de uso: Actores: Tipo: Descripcin:

144

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

F.38
Caso de uso: Actores: Tipo: Descripcin:

Visualizar escena en modo de relleno. Visualizar escena en modo de relleno Usuario. Evidente. Visualiza la informacion geomtrica de la escena en modo relleno.

F.39
Caso de uso: Actores: Tipo: Descripcin:

Visualizar sombreado en modo plano. Visualizar sombreado en modo plano Usuario. Evidente. Visualiza la escena en modo de sombreado plano.

F.40
Caso de uso: Actores: Tipo: Descripcin:

Visualizar sombreado en modo suavizado. Visualizar escena en modo suavizado Usuario. Evidente. Visualiza la escena en modo de sombreado suavizado.

F.41
Caso de uso: Actores: Tipo: Descripcin:

Mostrar vista superior de la escena. Mostrar vista superior de la escena Usuario. Evidente. Visualiza la escena desde un punto superior al centro de la seleccin actual.

F.42
Caso de uso: Actores:

Mostrar vista inferior de la escena. Mostrar vista inferior de la escena Usuario.

145

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Tipo: Descripcin:

Evidente. Visualiza la escena desde un punto inferior al centro de la seleccin actual

F.43
Caso de uso: Actores: Tipo: Descripcin:

Mostrar vista anterior de la escena. Mostrar vista anterior de la escena Usuario. Evidente. Visualiza la escena desde un punto anterior al centro de la seleccin actual

F.44
Caso de uso: Actores: Tipo: Descripcin:

Mostrar vista posterior de la escena. Mostrar vista posterior de la escena Usuario. Evidente. Visualiza la escena desde un punto posterior al centro de la seleccin actual Mostrar vista lateral izquierda de la escena. Mostrar vista lateral izquierda de la escena Usuario. Evidente. Visualiza la escena desde un punto lateral izquierdo al centro de la seleccin actual

F.45
Caso de uso: Actores: Tipo: Descripcin:

F.46
Caso de uso: Actores: Tipo: Descripcin:

Mostrar vista lateral derecha de la escena. Mostrar vista lateral derecha de la escena Usuario. Evidente. Visualiza la escena desde un punto lateral derecho al centro de la seleccin actual

146

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4.4.3 Casos de Uso siguiendo la notacin UML.


A continuacin 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 especfica sino que se consideran agrupadas en casos de uso ms generales. Una vez vistos los casos de uso en general (es decir, que pueden incluir varias funcionalidades agrupadas), se proceder a la especificacin de algunos de ellos de forma detallada. No se especifican todos los casos de uso, ya que se considera que con la especificacin de las funciones (de alto nivel), realizada en el apartado anterior, quedan explicadas las acciones que sern necesarias realizar para llevar a cabo una determinada tarea.

147

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

148

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

149

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

CASO DE USO: Iniciar Accin de los Actores 1. El usuario arranca la aplicacion. Respuesta del sistema 2. La aplicacin crea una vista y el objeto global ActiveViewHandler que su vez inicia los gestores de objetos, nodos, parametros, etc. y registra los tipos de datos que los gestores contendrn inicialmente. 3. Se crea el grafo inicial, conteniendo los datos auxiliares como la rejilla o el eje manipulador. 4. Se Inician las estructuras de datos necesarias para iniciar una escena en OpenSceneGraph. 5. Se crea la barra de herramientas de creacion de nodos, la barra de depuracin y la barra de paneles de comandos.

150

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

6. Se crea un nuevo rbol para representar el grafo inicial. 7. Se establece le pasa el nodo raiz del grafo al arbol para que se inicie la representacin en rbol del nodo. 8. Se inician los TabOutput y se muestra su contenido en el panel de comandos. 9. Se cargan los plugins del programa, que a su vez registran los objetos de los plugins en sus respectivos gestores.

CASO DE USO: Nueva Escena Accin de los Actores 1. El usuario decide iniciar una nueva escena en el editor pulsando el botn apropiado o seleccionando la opcion desde el men principal. Respuesta del sistema 2. La aplicacin crea una nueva vista. Al iniciar la vista se crea el grafo inicial de la aplicacin, conteniendo los datos auxiliares necesarios, como la rejilla o el eje manipulador, y un nodo de seleccin de objetos donde colgarn las cajas de seleccin de los mismos. 3. Se Inician las estructuras de datos necesarias para iniciar una escena en OpenSceneGraph. 5. Se crea una nueva escena vaca en la Barra de rbol (sin grafo asociado), agregando por tanto un nuevo rbol para representar el grafo inicial. Este arbol deber ser replicado tantas veces como vistas existan abiertas en la aplicacin. 6. Se establece esta escena como la escena activa. 8. Se inicia un nuevo objeto de seleccin con el eje manipulador. 9. Se establece la raz de la representacin en rbol de la escena como el nodo raz de nuestro grafo inicial.

CASO DE USO: Finalizar aplicacin Accin de los Actores Respuesta del sistema

151

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

1. El usuario cierra la aplicacin desde el botn de cerrar, o desde el menu principal.

2. La aplicacin realiza una llamada a cerrar todas las TreeBar. 3. Esto provoca que se libere la informacion de cada una de las escenas que cada TreeBar almacena, y que se vace la historia de la escena. 3. Se liberan los recursos OSG de cada escena. 4. Se libera la memoria almacenada por los controles de windows usados para representar el rbol.

CASO DE USO: Modificar un parmetro Accin de los Actores 1. El usuario interacta con algun control del panel de comandos, por ejemplo de los parmetros de un nodo del grafo de escena pulsando sobre la flecha superior de un Spinner. Respuesta del sistema 2. La aplicacin envia una notificacin al Gestor de parmetros para avisarle de que un control ha sido modificado o pulsado. 3. El gestor de parmetros comprueba si la notificacion pertenece a algn parmetro existente en sus tablas y en ese caso se le envia la notificacin al ObjectType asociado a tal control. 4. Del mismo modo, se comprueba si el ObjectType est siendo adjuntado por algun otro ObjectType y en caso afirmativo enva tal notificacin al adjuntador.

CASO DE USO: Seleccionar un objeto en el visor Accin de los Actores 1. El usuario coloca el cursor sobre un objeto del visor y pulsa el botn para seleccionar el objeto. Respuesta del sistema 2. La aplicacin recoje la notificacion de pulsacin del ratn y se la pasa al objeto seleccin. 3. El objeto seleccin obtiene la interseccin del ratn con la escena, para comprobar sobre qu est el cursor. 4. Puesto que el cursor est encima de un objeto y no est seleccionado vamos a crear una nueva accion de cambio de seleccin, por tanto guardaremos en dos tablas los datos de la seleccin para pasarlas como argumentos

152

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

de la nueva accion. De esta manera el sistema dispondr de la informacin necesaria para deshacer la accin que acabamos de llevar a cabo. 5. Ejecutamos la accin. El gestor de historia almacenar la accin internamente. 6. Actualizamos el eje manipulador, posicionandolo en el centro de la seleccin.

CASO DE USO: Insertar un fichero Accin de los Actores 1. El usuario decide insertar un fichero como hijo del nodo seleccionado en el rbol. 3. El usuario elige el fichero que quiere aadir a la escena. Respuesta del sistema 2. El sistema muestra un dilogo de seleccin de archivos. 4. Mediante funciones propias de OpenSceneGraph cargamos el fichero, obteniendo el nodo raiz del grafo de escena del fichero. 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 operacin y no hacemos nada. 5. Establecemos el grafo como hijo del nodo que tenemos seleccionado en el rbol. Para ello se deber recorrer el nuevo grafo, creando para cada nodo los tems necesarios en el rbol. 6. Por ltimo, deberemos crear una rplica de la nueva rama generada en todas las dems vistas del rbol que haya abiertas.

CASO DE USO: Nuevo rbol Accin de los Actores 1. El usuario pulsa el botn de visualizar nuevo rbol en la barra de herramientas, o selecciona la opcin del men principal. Respuesta del sistema 2. El objeto que gestiona todas las TreeBar, crea una nueva ventana que contendr los distintos rboles de las distintas escenas. 3. El gestor de las TreeBar aade esta nueva barra a sus ndices.

153

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

4. Se aade una nueva escena a la nueva TreeBar, por cada escena de las que ya existen. La escena representa el control de rbol en si. 5. Se realiza una rplica de cada una de las escenas (es decir, del rbol completo de cada una de las escenas) en la nueva TreeBar.

CASO DE USO: Crear Nodo Accin de los Actores 1. El usuario selecciona un elemento del rbol, preferiblemente un tem que est asociado a un nodo que admita tener hijos (derivado de Group). 2. El usuario selecciona el primer panel de comandos, y selecciona un elemento de la lista de nodos disponibles en la aplicacin. 3. El usuario pulsa sobre Crear Como Hijo 7. El gestor de nodos busca un NodeType entre sus ndices segn el nombre indicado, y obtiene una nueva instancia de la clase OpenSceneGraph que soporta el NodeType obtenido. 8. ActiveViewHandler crea un nuevo nodo del editor y le asocia el nodo OpenSceneGraph que acaba de crear. 9. ActiveViewHandler crea una nueva accion CrearNodo y la ejecuta. 10. Al ejecutar la nueva accin se crea el elemento del rbol y se aade la informacion necesaria en el nodo del editor. Respuesta del sistema 4. El TabOutput obtiene el nombre del nodo seleccionado de la lista de seleccin. 5. El TabOutput consulta el item seleccionado actualmente en el rbol. 6. Se invoca al ActiveViewHandler para crear un nodo a partir de su nombre, especificando el padre del cual deber colgar.

CASO DE USO: Deshacer Accin de los Actores 1. El usuario realiza una accin el en editor, por ejemplo desplazar un objeto en la pantalla. 2. El usuario decide deshacer esta accin pulsando en el botn Deshacer. Respuesta del sistema 3. La vista activa realiza una llamada a Undo del gestor de historia. 4. El gestor de historia realiza una llamada a la funcion Undo de la accin y retrocede la posicion del ndice de la ltima accion ejecutada.

154

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5. La vista activa obtiene el item actualmente seleccionado, y actualiza la salida del interfaz.

CASO DE USO: Rehacer Accin de los Actores 1. El usuario deshace una accin. 2. El usuario decide que no queria deshacer esa accion y pulsa en el boton Rehacer para recuperarla. Respuesta del sistema 3. La vista activa realiza una llamada a Redo del gestor de historia. 4. El gestor de historia realiza una llamada a la funcion Redo de la accin y avanza la posicion del ndice de la ltima accion ejecutada. 5. La vista activa obtiene el item actualmente seleccionado, y actualiza la salida del interfaz.

CASO DE USO: Seleccionar un item del arbol Accin de los Actores 1. El usuario pulsa sobre un tem del rbol. Respuesta del sistema 2. Se seleccionan en negrita todas las instancias del mismo item, es decir, aquellos 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 dems vistas de rbol que existan abiertas. 4. Se pide al ActiveViewHandler que muestre la informacin del nodo asociado al tem que hemos seleccionado.

5. Para ello, si es la primera vez que se va a mostrar ese tipo de nodo, se crean dinmicamente los dilogos que contendran los parmetros del nodo. 6. Seguidamente, se ocultar cualquier contenido de cualquier nodo anterior en caso de existir. 7. Se mostrarn los dilogos de este tipo de nodo y se mostrar el contenido de los datos del nodo en los controles que acabamos de mostrar.

155

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

8. Almacenaremos este nodo como el ltimo nodo mostrado y como nodo actualmente seleccionado.

CASO DE USO: Seleccionar un elemento del rbol en el visor Accin de los Actores 1. El usuario pulsa sobre un tem o varios items del rbol y lo selecciona. 2. El usuario pulsa el boton derecho sobre tal seleccin y elige la opcion de Seleccionar en visor. Respuesta del sistema 3. El rbol obtiene la lista de los items 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. 5. Se comprueba si los items cumplen la condicion de la Matriz de Transformacin padre, y en caso de que sea necesario, creamos tal matriz.

6. Se crea una nueva accion de cambio de seleccin con la seleccin anterior y la posterior. 7. Se le pasa la accion a ActiveViewHandler para ejecutarla.

CASO DE USO: Seleccionar un elemento del visor en el rbol Accin de los Actores 1. El usuario realiza un doble click sobre elemento del visor 3D. Respuesta del sistema 2. El sistema comprueba si existe algn elemento seleccionado. Para este caso se podra deducir que solo habr un elemento seleccionado, por tanto tan solo obtendremos el primero de la lista. 3. El rbol selecciona el elemento en todos los arboles, asi como sus instancias. 4. El ActiveView Handler muestra la informacin del nodo del mismo modo que en el caso de uso Seleccionar un tem del rbol.

CASO DE USO: Copiar un nodo

156

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Accin de los Actores 1. El usuario arrastra un item del rbol y lo suelta dentro de otro manteniendo pulsada la tecla CTRL.

Respuesta del sistema 2. El rbol sobre el que estamos realizando la operacin dispone de dos referencias a dos items, el item que estamos arrastrando y el 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 origen 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. 4. Para cada una de las rplicas del rbol existentes realizamos la copia de los items desde el origen hacia el destino, y solamente en la primera de las iteraciones, realizamos tambien la copia del nodo del grafo del editor.

CASO DE USO: Mover un nodo Accin de los Actores 1. El usuario arrastra un item del rbol y lo suelta dentro de otro manteniendo pulsada la tecla CTRL. Respuesta del sistema 2. El rbol sobre el que estamos realizando la operacin dispone de dos referencias a dos items, el item que estamos arrastrando y el 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 origen 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. 4. Para cada una de las rplicas del rbol existentes realizamos la copia de los items desde el origen hacia el destino, y solamente en 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 habiamos arrastrado).

CASO DE USO: Duplicar un nodo

157

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Accin de los Actores 1. Copia al portapapeles un item del rbol utilizando la combinacin de teclas CTRL+D. 2. El usuario posiciona la seleccin sobre otro item y utiliza la combinacion de teclas CTRL+V para pegar el nodo.

Respuesta del sistema 2. El rbol sobre el que estamos realizando la operacin dispone de dos referencias a dos items, el item que estamos arrastrando y el 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 origen 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. 4. Para cada una de las rplicas del rbol existentes realizamos la copia de los items desde el origen hacia el destino. Adems, en el primero de los rboles, en cada item del rbol que recorramos, crearemos una nueva instancia de copia del elemento haciendo uso del gestor de nodos, y enlazando estos nuevos nodos tanto en el grafo del editor como en el grafo de OpenSceneGraph.

CASO DE USO: Trasladar una seleccin Accin de los Actores 1. Con el modo trasladar activo, y con uno o ms objetos seleccionados, el usuario coloca el cursor sobre alguno de estos objetos seleccionados o sobre el eje manipulador y realiza una pulsacin del botn izquierdo del ratn, sin llegar a soltarlo. 6. Con el botn izquierdo pulsado, comenzamos a arrastrar la seleccin por el visor. 14. El usuario suelta el botn izquierdo del ratn. Respuesta del sistema 2. Se realiza una llamada a Comenzar Traslacin. En ella se calcula la normal al plano seleccionado en el eje manipulador y se almacena en una variable. 3. Se actualiza el centro de la seleccin actual y se obtiene en una variable. 4. Se calcula la interseccin de la linea imaginaria que formara una linea que atravesase perpendicularmente la pantalla pasando por la posicion del cursor y el plano imaginario que formara el plano del eje manipulador con centro en el centro de la seleccin. 5. Se guarda el punto de interseccion en una variable que nos servir de referencia para calcular el posterior incremento de la traslacin. 7. Se obtiene la normal del plano seleccionado en el eje manipulador.

158

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

8. Igual que antes, calculamos el punto de interseccion del cursor con el plano imaginario cuya normal hemos calculado en el paso anterior. 9. Se calcula el incremento restando la posicion calculada en el punto 5 a la posicion de la inserseccin actual. 10. Para cada uno de los elementos de la seleccin construimos una matriz de traslacin que se multiplicar a la actual matriz de transformacin. 11. Se actualiza el centro de la seleccin. 12. Se actualiza la posicin del eje manipulador en funcin del centro de la seleccin. 13. Se actualiza la BoundingBox de la seleccin. 15. Se almacena un vector de informacin de los elementos seleccionados. 16. Para cada uno de los objetos de informacin de seleccion, se actualiza el valor de la matriz de transformacin guardada. 17. Se crea una nueva accin de modificacin de transformacin, almacenando los valores anteriores y posteriores de las matrices.

CASO DE USO: Eliminar un nodo Accin de los Actores 1. El usuario pulsa sobre un tem o varios items del rbol y los selecciona. 2. El usuario pulsa el boton suprimir del teclado. Respuesta del sistema 3. El rbol obtiene la lista de los items 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 almacenamos en un vector. 5. Se crea una nueva accin de Borrar Items, donde se indican en una lista los items a eliminar y se ejecuta. 6. La ejecucin de esta accin consiste en

159

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

obtener el elemento del grafo de cada item que queremos eliminar para guardar su referencia en caso de un Redo, y eliminar los items de todos sus descendientes en el rbol.

CASO DE USO: Aadir un StateAttribute a un StateSet de un nodo Accin de los Actores 1. El usuario pulsa el botn Aadir StateAttribute del tercer panel de comandos del (panel de StateSet), habiendo ya un nodo seleccionado en el rbol. 3. El usuario pulsa aceptar en el dilogo de confirmacin. 5. El usuario elegir un nombre de un StateAttribute y pulsar Aceptar. Respuesta del sistema 2. En este caso, el nodo no contendr ningun StateSet por tanto se preguntar al usuario si desea crear uno mediante un dilogo de confirmacin. 4. Aparecer otro dilogo con el listado de los nombres StateAttributes que estn 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 accin de Agregar StateAttribute que agregar esta nueva instancia del StateAttribute al StateSet del nodo seleccionado actualmente.

CASO DE USO: Aadir un Modo a un StateSet de un nodo Accin de los Actores 1. El usuario pulsa el botn Aadir Modo del tercer panel de comandos del (panel de StateSet), habiendo ya un nodo seleccionado en el rbol. 3. El usuario elegir un nombre de un Modo y pulsar Aceptar. Respuesta del sistema 2. Aparecer un dilogo con el listado de los nombres de los Modos que estn registrados en el sistema. Este listado ser un listado esttico 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 accin de Agregar Modo que agregar este nuevo modo al StateSet del nodo seleccionado actualmente.

CASO DE USO: Modificar un Modo de un StateSet de un nodo

160

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Accin de los Actores 1. El usuario pulsa el botn Aadir Modo del tercer panel de comandos del (panel de StateSet), habiendo ya un nodo seleccionado en el rbol. 3. El usuario elegir un nombre de un Modo y pulsar Aceptar.

Respuesta del sistema 2. Aparecer un dilogo con el listado de los nombres de los Modos que estn registrados en el sistema. Este listado ser un listado esttico puesto que est relacionado con los modos que soporta OpenGL. 4. Puesto que el modo ya existe, y tiene un valor o ms de flag asignado, lo que haremos ser obtener el valor de esta mascara y aadir 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 accin de Modificar Modo que establecer un nuevo valor de la mscara de un modo de un StateSet.

CASO DE USO: Modificar un Modo de un StateSet de un nodo (Opcion 2) Accin de los Actores 1. El usuario selecciona uno de los comboboxes que acompaana a cada uno de los nombres de los modos que contiene el StateSet y modifica su valor. Respuesta del sistema 2. Puesto que el modo ya tiene un valor o ms de flag asignado, lo que haremos ser obtener el valor de esta mascara. 3. Crearemos un nuevo valor de mscara, , eliminando el flag anterior y aadiendo 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 accin de Modificar Modo que establecer un nuevo valor de la mscara de un modo de un StateSet.

CASO DE USO: Cambiar la escena activa Accin de los Actores 1. El usuario tiene abiertas varias escenas de manera simultnea en la aplicacin y realiza un cambio de escena mediante la combinacin de teclado CTRL+TABULADOR. Respuesta del sistema 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 seleccin, etc.

162

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE V

DISEO

163

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

164

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

INDICE
PARTE V........................................................................................................
5.1. Introduccin. .................................................................... Error! Marcador no definido. 5.2 Diagrama de componentes del sistema. ............................ Error! Marcador no definido. 5.3 Diseo de las funciones del sistema mediante diagramas de secuencia y colaboracin. ................................................................................................. Error! Marcador no definido. 5.3.1 Inicio. ......................................................................... Error! Marcador no definido. 5.3.2 Finalizar aplicacin .................................................... 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 Parmetro .................................................. 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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. 5.3.47 ActDeleteMultiItem (Action) ................................... Error! Marcador no definido. 5.3.48 DeleteNode (ActiveViewHandler) ........................... Error! Marcador no definido. 5.3.49 Cambiar escena activa.............................................. Error! Marcador no definido. 5.4. Diagrama de estados del sistema...................................... Error! Marcador no definido. 5.4.1 Estado del cursor ........................................................ Error! Marcador no definido.

166

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.1. Introduccin.
Para realizar cualquier software, una vez reconocidos los requisitos, y realizado un estudio de las necesidades del sistema, no es recomendable en ningn caso comenzar la implementacin sin realizar primero un diseo que cumpla con las caractersticas obtenidas en la fase de anlisis. En la fase de diseo, se especifica la arquitectura software del sistema y se ofrece una primera aproximacin algortmica al sistema global, la cual sea capaz de cumplir con todas las conclusiones alcanzadas en el anlisis 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 diseo. Siguiendo las conclusiones de la fase de anlisis, se realizar el diseo de las funciones ms importantes del sistema, y no todas ellas debido a que podramos extendernos excesivamente, explicando detalladamente los pasos a seguir para llevarlas a cabo en los casos que sean necesarios. Al finalizar la fase de diseo, ya estarn definidas todas las funciones, clases, y directrices necesarias para realizar la implementacin.

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 aplicacin y de su conexin con los dems componentes. El fichero ejecutable est generado mediante el uso de la librera MFC (Microsoft Foundation Classes), y hace uso de la librera grfica OpenSceneGraph, que a su vez est basada en la librera OpenGL. Adems, la aplicacin se complementa con la carga en memoria de fragmentos de cdigo aadidos en tiempo de ejecucin, que son las DLLs, que a su vez pueden acceder a la aplicacin.

167

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3 Diseo de las funciones del sistema mediante diagramas de secuencia y colaboracin.
5.3.1 Inicio.
Es la funcin que inicia todos los datos del programa. Al arrancar la aplicacin se iniciar el nico objeto global de la aplicacin (ActiveViewHandler), y se generar una vista vaca, la cual iniciar los datos del grafo por defecto. Cuando el ActiveViewHandler arranque iniciar todos los gestores de la aplicacin, se crearan las barras de herramientas (la principal y la de creacin de nodos) iniciar la barra principal de paneles de comandos y el rbol que contendr la representacin del grafo, y adems iniciar los tipos de datos que soporta la aplicacin aadindolos a sus respectivos gestores. Es en esta fase donde se realizar tambin la carga de los plugins. Al cargar los plugins la aplicacin buscar en el directorio de plugins ficheros dll, estos ficheros los intentar cargar uno por uno, extrayendo informacin 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 aplicacin sern los siguientes:
ObjTypeStateSet ObjTypeDrwStateSet ObjTypeCounter ObjTypeVariableRateCounter ObjTypeRandomRateCounter ObjTypeConstantRateCounter ObjTypeDrawable ObjTypeShapeDrawable ObjTypeGeometry ObjTypeParticle ObjTypeParticleSystem ObjTypeText

Los tipos de StateAttribute que iniciar la aplicacin:


AttTypeFog AttTypeMaterial AttTypeBlendFunc AttTypeLight AttTypeTexEnv AttTypeTexGen AttTypeTexture AttTypeTexture2D AttTypeVertexProgram AttTypeFragmentProgram

Y por ltimo, los tipos de nodo que iniciar sern:


TypeNode TypeGroup TypeLOD

168

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

TypePagedLOD TypeSwitch TypeGeode TypeSequence TypeBillboard TypeTransform TypeDOFTransform TypePositionAttitudeTransform TypeMatrixTransform TypeAutoTransform TypeLightSource TypeParticleSystemUpdater TypeParticleProcessor TypeEmitter TypeModularEmitter TypeFXEffect TypeFXCartoon TypeFXSpecularHighlights TypeFXBumpMapping

169

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.2 Finalizar aplicacin


Cuando el usuario salga de la aplicacin, 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 vaca el contenido de la Historia y se avisa al ActiveViewHandler que tal vista va a ser cerrada para que realice tambin sus operaciones. Aqu es donde se avisa al MultiTreeBar que libere toda su memoria, puesto que cada TreeBar contiene la informacin del grafo que hay cargado, incluso tablas hash que contena cada una de ellas.

170

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.3 Nueva Escena


Al iniciar una nueva escena, la aplicacin 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 informacin. El grafo no deber ser la escena en s, puesto que el editor necesita ms elementos para visualizar de manera auxiliar. Por tanto, el grafo inicial (raz) estar dividido en dos ramas principales, la primera ser la escena que vamos a crear, y en la segunda colgaremos aquellos nodos que nos sern tiles en el editor para manipular otros nodos, como puede ser el eje manipulador, las cajas de seleccin de objetos, e incluso la rejilla. Una vez hecho esto, deberemos aadir una nueva escena al editor. Esto implica crear nuestro propio grafo de escena (copia del de OpenSceneGraph), y aadir un nuevo control de rbol en cada una de las TreeBar abiertas en la aplicacin, clonando su contenido tantas veces como sea necesario. Tambin aqu ser donde inicialicemos los datos de la seleccin, y el StateSet global, que nos servir para cambiar el modo de visualizacin de la escena.

171

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 funcin. El usuario seleccionar del disco duro un fichero compatible con la aplicacin, 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.5 Modificar Parmetro


Cuando un usuario manipula alguno de los controles del panel de comandos donde aparecen los grupos de parmetros 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 dcima su valor) y despus se realice una llamada a la notificacin de parmetro 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 notificacin al elemento adjuntador de que uno de sus elementos adjuntos acaba de modificar un dato.

5.3.6 Nuevo rbol


Esta funcin crea una rplica de la barra del rbol. Lo que esta funcin hace es crear una nueva TreeBar, inicialmente vaca, y replicar todos y cada uno de las escenas que contiene esta TreeBar en la que acabamos de crear.

173

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.7 Seleccionar elemento en visor.


Para seleccionar un elemento en el visor tendremos que obtener la interseccin del ratn con la escena. Esto se har mediante un objeto de OpenSceneGraph llamado IntersectVisitor que nos devolver un listado de las colisiones encontradas entre una lnea y en el grafo que le indiquemos. Esta interseccin tan solo la comprobaremos desde la rama de la escena (recordemos que tenamos otra sub-rama principal con la informacin auxiliar del editor). Puesto que solo nos interesa la ms 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 funcin Seleccionar, que insertar una nueva accin de cambio de seleccin en la historia.

174

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.8 Crear Nodo


Esta funcin 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 botn de crear el nodo, se invocar la funcin de ParamModified de TabOutput. De este modo sabremos que se ha pulsado el botn 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 insercin del nuevo nodo pasar por medio de una accin que quedar registrada en el sistema para su posterior posible inversin.

175

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.9 Seleccionar Elemento en rbol


Est funcin se invoca cuando se selecciona un elemento en el rbol, o su seleccin 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 dems TreeBar abiertas, en color rojo. De esta manera el usuario podr identificar rpidamente el tem que acaba de seleccionar en cualquier otra vista abierta del rbol. Acto seguido, pasaremos a mostrar la informacin 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 dilogos, si exista algn otro mostrado se oculta y despus se muestran los dilogos 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.10 Undo.
La funcin Undo o Deshacer se invoca desde la vista activa. Esta realiza una llamada directa a la funcin Undo de gestor de Historia, que a su vez realiza una llamada a la funcin Undo de la accin actual apuntada por el gestor. Despus de ello, actualiza la posicin del cursor, retrocedindola un lugar, pero conservando las acciones posteriores. Puesto que la funcin 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 funcin es invocada desde el rbol desde el que se llama a esta funcin. Lo que hacemos es obtener una lista de los tems seleccionados en el rbol (sin sus descendientes). Despus obtenemos un puntero al primero de los rboles de la escena, para trabajar sobre l. Esto lo hacemos as porque en la informacin de seleccin de objetos siempre haremos referencia a

177

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

objetos del primer rbol, puesto que un mismo tem en rboles distintos tendr referencias distintas. Por ltimo, indicaremos al gestor de seleccin la lista de los objetos que queremos seleccionar. Este gestor comprobar previamente si los objetos que vamos a seleccionar contienen Matrices de Transformacin 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 funcin 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 transformacin, puesto que esa comprobacin ya se hizo al seleccionar el objeto), y queremos seleccionarlo en el rbol. En primer lugar obtenemos la lista de seleccin 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 seleccin de un objeto en el rbol, que ya hemos explicado anteriormente: se seleccionan todas las instancias del objeto, as como sus equivalentes en los dems rboles y se muestra la informacin del nodo en el panel de comandos. Por ltimo, hacemos que se muestre automticamente la segunda pestaa del panel de comandos, que es la que muestra la informacin de los parmetros del nodo seleccionado en el rbol.

178

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.13 Copiar elemento de rbol


Esta funcin 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. Despus obtiene el ndice de la TreeBar sobre la que estamos realizando la operacin, 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 operacin de copiar para cada una de ellas.

5.3.14 Copiar tem de un nico rbol.


La funcin anterior haca uso de esta funcin 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 instanciacin, esta copia solo consistir en aadir un nuevo padre al nodo que queremos copiar. Por ltimo deberemos aadir 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 funcin para cada uno de ellos, estableciendo como padre en la llamada el nodo origen de la funcin actual.

179

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.15 SelectAllInstances
Esta funcin 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 funcin la invoca el propio rbol, pero accede a todas las dems rplicas del rbol en el editor. A partir del nodo del editor sobre el que queremos aplicar la funcin, debemos obtener el ndice de la instancia. Con este ndice identificaremos automticamente en cada uno de los rboles el tem equivalente, que colorearemos de rojo.

180

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.17 CreateParentMatrixTransform
Esta funcin se llama automticamente al seleccionar un objeto. La razn de ello es que al seleccionar un objeto, el usuario est indicando en cierto modo su intencin de aplicarle alguna transformacin. Esta transformacin solo se puede llevar a cabo sobre una Matriz de Transformacin que contenga al nodo como uno de sus descendientes. Por tanto, lo que har esta funcin ser comprobar si existe una matriz de transformacin como padre del nodo, y adems, que esa transformacin solo tenga a ese nodo como hijo. En caso contrario, creamos un nuevo nodo tipo Matriz de Transformacin y lo intercalamos entre el nodo que queremos transformar y su padre actual.

5.3.18 StartTranslation
Esta funcin y las dos siguientes solo las explicaremos para la Traslacin, pues que para el escalado y la rotacin siguen comportamientos similares. Esta funcin es como el Setup o la puesta a punto de la traslacin. Se llama a esta funcin para realizar los ajustes o actualizaciones necesarias o consultar los datos necesarios para prepararse para comenzar la transformacin. Por ejemplo, aqu recalcularemos la BoundingBox de la seleccin y deberemos guardar la posicin del centro geomtrico de la seleccin, lo cual nos servir mas adelante para almacenar correctamente la transformacin como una funcin invertible en la Historia.

181

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.19 DoTranslate
Es el proceso de trasladar en s. Esta es la funcin que realiza la traslacin a medida que vamos desplazando el ratn, aunque realmente la accin no se podr considerar como terminada hasta que soltemos el ratn. Esta es la funcin que realiza la traslacin, aunque realmente la accin no se podr considerar como terminada hasta que soltemos el ratn. En este paso se aplica la misma transformacin a todos los objetos de la seleccin en funcin del desplazamiento del cursor sobre la pantalla. Esta transformacin tiene la particularidad de que requiere algunos clculos extraordinarios para calcular el incremento que vamos a aplicar a la traslacin, ya que calcularemos un plano imaginario que sea paralelo al plano seleccionado en el eje manipulador, y que pase por el centro de la seleccin, de esta manera, intersectando una lnea imaginaria desde el cursor hacia este plano obtendremos el punto donde queremos desplazar el objeto, y as calcularemos el incremento a aplicar como traslacin. Una vez hecho esto, deberemos tambin actualizar las cajas de seleccin de los objetos seleccionados, puesto que las transformaciones deben afectarles por igual, as como actualizar su BoundingBox y la posicin del eje manipulador.

5.3.20 EndTranslate
Este es el paso que da por finalizada la traslacin de la seleccin. Es aqu donde se actualiza la informacin de la seleccin, como por ejemplo los valores de las matrices auxiliares que se utilizan para almacenar informacin que luego servirn para almacenar la accin invertible de la transformacin. Tambin aqu actualizaremos la BoundingBox de la seleccin y actualizaremos la posicin del eje manipulador.

182

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 funcin la proporciona el ActiveViewHandler, y se utiliza para ejecutar cualquier accin en el sistema. Lo que esta funcin hace es ejecutar la accin pasada por referencia, y pasrsela al gestor de historia para aadirla. El gestor de historia comprobar si la posicin actual de la historia est colocada al final, y en caso afirmativo, insertar la accin, incrementando esta posicin. En caso de no ser as, todas las acciones posteriores a las de la posicin actual, debern ser eliminadas, y despus de ello, se insertar la accin, incrementando la posicin actual en uno.

183

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.23 RecursiveCreateDialogs
Esta funcin se invoca la primera vez que queremos mostrar un ObjectType por el interfaz, y es invocada por el gestor de parmetros. Esta accin simplemente crea en memoria los dilogos que formarn esta estructura. La primera accin a realizar es crear los dilogos del ObjectType a partir de su grupo de parmetros, ya definido, realizando una llamada recursiva en caso de que existe un ObjectType padre definido y este no haya creado tampoco sus dilogos. Despus de esto, se comprueba si existen ObjectTypes adjuntos, y se realiza la misma llamada a esta misma funcin para cada uno de ellos.

5.3.24 CreateDialogs.
Es la funcin que invoca la funcin recursiva anterior. Aqu se obtiene el vector de grupos de parmetros del objeto, y para cada uno d ellos, se crea un dilogo independiente, indicando el Rollup en el que lo mostraremos. Cada pestaa del panel de comandos tiene un Rollup asociado, por lo que el Rollup equivale a la pestaa del panel de comandos donde queremos que se creen los dilogos.

184

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.25 CreateDialogFromGroup.
Esta funcin es invocada por la funcin anterior y es la que crea realmente el dilogo. En un principio se crea un dilogo dinmicamente, inicialmente vaco, y vamos recorriendo cada uno de los descriptores de grupo del grupo de parmetros. Cada uno de estos descriptores tendr unas caractersticas por lo que podremos crear distintos controles en funcin del tipo de descriptor. As pues, donde en el diagrama de colaboracin podemos apreciar CrearControl, deber estar sustituido por una llamada a la funcin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.26 RegisterTabOutput (TabOutputManager)


Esta funcin 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 parmetros que habr implementados en la clase TabOutput.

5.3.27 RegisterType (ObjectTypeManager)


Esta funcin la invoca el gestor de ObjectTypes. La funcin 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 aadimos el objeto a los ndices del gestor, para poder realizar bsquedas rpidas por su nombre.

186

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.28 NewInstance
Esta funcin es propia del gestor de ObjectTypes (aunque tambin 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 indicndole el nombre del tipo de objeto.

5.3.29 CreateTreeNode
Esta funcin 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 informacin como un puntero al nodo OpenSceneGraph que acabamos de crear, y un puntero al NodeType que identifica al nodo.

187

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.30 CargarPlugins
Esta funcin es invocada al iniciar el TabOutput de plugins, que es iniciado a su vez al iniciar la aplicacin. En primer lugar cargamos el fichero DLL, obteniendo el manejador del mismo. Creamos una nueva estructura de datos (PluginInfo) que contendr la informacin del plugin que carguemos, para que el gestor de plugins la almacene. Consultaremos el nmero de clases del plugin, as como la descripcin del plugin y obtendremos una instancia de cada una de las clases implementadas en el plugin. Toda esta informacin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Lo que esta funcin hace realmente es actualizar el cursor segn su posicin, o el eje manipulador, adems del estado del cursor. El estado del cursor define si el cursor est encima de algn objeto, o encima de algn otro elemento, como puede ser el eje manipulador. En primer lugar se comprueba si existe algn objeto seleccionado en la escena, en ese caso sabremos que el eje manipulador estar mostrado, por tanto obtenemos si existe alguna colisin del cursor con tal eje. Si el cursor no esta encima de ningn elemento del eje manipulador entonces se comprueba si existe colisin con alguno de los objetos, actualizando el cursor y el estado del cursor en funcin de si el eje est o no seleccionado, y de la transformacin que estemos llevando a cabo.

5.3.32 UpdateAxis
Esta funcin es invocada por la seleccin. Esta funcin realiza las mismas comprobaciones que la anterior, pero nicamente comprueba si existe alguna interseccin del cursor del ratn 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 ms 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.33 MapIOControls
Esta funcin (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 cuestin. Esta funcin es una funcin 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 parmetros asociando como clave en descriptor en s. De esta manera tenemos una tabla hash que asocia Ids de parmetros con sus respectivos descriptores.

5.3.34 RecursiveOnEndSelection
Esta funcin se invoca como notificacin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Para cada uno de los objetos, tambin se realizar una notificacin 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 funcin se llama cuando se necesita mostrar el contenido del dilogo de un ObjectType en el panel de comandos. Lo nico que hace esta funcin es llamarse recursivamente para sus parientes, y generar el contenido del Rollup (un dilogo desplazable).

5.3.36 RecursiveClearRollupContent (ObjectType)


Realiza el proceso inverso a la funcin anterior, es decir, elimina los Rollups del panel de comandos del interfaz, pero adems tambin realiza la misma llamada para cada uno de los adjuntos y se desvincula del adjuntador actual.

191

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.37 GenerateRollupContent (TabOutput)


Esta funcin es invocada directamente por la funcin 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 pgina desplegable o Rollup a partir de un dilogo ya generado. Una vez hecho esto, el dilogo estar contenido en un desplegable que el usuario podr plegar siempre que quiera tan solo pulsando un botn, para ahorrar espacio en el interfaz, y desplegar cuando quiera mostrar su contenido de nuevo. De entre la informacin necesaria para generar un grupo desplegable est el dilogo, el nombre que identificar al grupo, y adems si el grupo podr ser o no desplegable, puesto que es opcional, y si se mostrar inicialmente expandido o contrado.

5.3.38 ClearRollupContent (TabOutput)


Es la funcin inversa a la anterior. Suele invocarse cuando queremos limpiar la salida del panel de comandos, bien para dejarlo vaco, bien para dar paso a generar el contenido de otro TabOutput. Esta llamada desvincula el dilogo que identifica en grupo de parmetros del Rollup en el que est contenido, pero no destruye en dilogo que hemos creado de la memoria. El primer paso es marcar el TabOutput como oculto, y adems marcar que sus datos no estn mostrados. Para cada uno de los grupos de parmetros que contiene el TabOutput obtendremos el tab que ocupa en el panel de comandos, y obtendremos el puntero al dilogo dinmico del grupo. Con el tab, obtendremos el Rollup asociado al tab, y as sabremos si el dilogo est o no expandido, para almacenar este estado. Despus eliminaremos la pgina del Rollup para que deje de mostrarse su dilogo.

192

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.39 GetParamValue (TabOutput)


Esta es la funcin que proporciona TabOutput para que los desarrolladores puedan establecer un contacto con los controles generados en el panel de comandos. A esta funcin se le pasan dos parmetros, uno con el ID del parmetro a consultar, y un segundo parmetro que es una variable donde almacenaremos el valor de tal parmetro. En este caso vamos a mostrar el comportamiento de la funcin para obtener el valor de un parmetro almacenndolo en una variable entera. En primer lugar obtendremos el descriptor del parmetro asociado al ID del parmetro que queremos, sabiendo esto, obtendremos el grupo de parmetros al que pertenece el descriptor, y a su vez podremos obtener un puntero al dilogo que lo representa. Puesto que el descriptor del parmetro tambin guarda el ID del control asociado en el dilogo, podremos obtener el valor que almacena el control mediante la llamada a GetDlgItemInt(id).

5.3.40 SetParamValue (TabOutput)


Esta es la funcin que proporciona TabOutput para que los desarrolladores puedan establecer un contacto con los controles generados en el panel de comandos.

193

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

A esta funcin se le pasan dos parmetros, uno con el ID del parmetro a modificar, y un segundo parmetro que es una variable con el valor del parmetro. En este caso vamos a mostrar el comportamiento de la funcin para establecer el valor de un parmetro mediante una variable entera. En primer lugar obtendremos el descriptor del parmetro asociado al ID del parmetro que queremos, sabiendo esto, obtendremos el grupo de parmetros al que pertenece el descriptor, y a su vez podremos obtener un puntero al dilogo que lo representa. Puesto que el descriptor del parmetro tambin guarda el ID del control asociado en el dilogo, podremos establecer el valor que almacena el control mediante la llamada a SetDlgItemInt(id, value).

5.3.41 LookAtSelection
Esta funcin 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 cmara del visor. LookAtSelection centra la vista en el centro geomtrico de la seleccin actual del visor. Para ello obtenemos el punto central de la seleccin, 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 seleccin. Por ltimo establecemos esta matriz como la matriz del TrackBall.

5.3.42 SetRootNode (ActiveViewHandler)


Permite establecer el nodo raz es una escena en todas las vistas de rbol abiertas. La nica tarea de ActiveViewHandler es realizar la conversin del ID de la escena a su ndice. Esta conversin 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 aplicacin.

194

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Por ltimo, se realiza la llamada SetRootNode al objeto MultiTree, indicando que vamos a establecer el nodo como nodo raz (parmetro NULL).

5.3.43 SetRootNode (MultiTreeBar)


Esta llamada puede provenir tanto de ActiveViewHandler, como de la insercin de un subgrafo desde un fichero. Es por ello que aqu se establece como parmetro de entrada el tem sobre el que debemos establecer el grafo (no necesariamente el raz). Permite establecer un grafo colgando de un elemento de un rbol. Este elemento puede ser la raz del rbol, por lo que el rbol no debe necesariamente contener algn elemento. Esta funcin internamente establece el grafo de escena sobre una de las vistas del rbol (suponiendo que haya varias simultneas) y realiza rplicas del mismo sobre las dems. 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 subrbol sobre el rbol que queremos y completando nuestro grafo interno. Esta funcin solo permitir insertar nodos dentro del elemento que queramos, si este elemento pertenece a un nodo derivado de la clase Group de OpenSceneGraph.

195

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 aadir la informacin 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 funcin clona un rbol a partir de otro. Este rbol puede ser clonado slo 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 clonacin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.46 DeleteNode (OSGTreeCtrl)


Para eliminar uno o varios tems del rbol lo haremos mediante una accin. Esta accin 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 accin, ActDeleteMultiItem, facilitndole esta nueva lista de tems a eliminar.

5.3.47 ActDeleteMultiItem (Action)


Es la accin que ejecuta la funcin anterior. La accin almacena internamente una lista de los TreeNodeInfo (nodo del grafo del editor) que vamos a eliminar, para mantenerlos en memoria mientras la accin pueda deshacerse.

197

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Despus, invocamos a la funcin eliminar sobre cada uno de los elementos del rbol, propia la de clase OSGTreeCtrl.

5.3.48 DeleteNode (ActiveViewHandler)


Esta funcin 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. Despus 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

5.3.49 Cambiar escena activa


Se produce esta llamada a esta funcin cuando el usuario realiza un cambio de la escena activa, ya sea mediante alguna combinacin del teclado o usando el men de seleccin 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 seleccin, puesto que son independientes en cada escena, y cada escena tiene las suyas. La funcin 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, facilitndole los punteros necesarios.

5.4. Diagrama de estados del sistema


5.4.1 Estado del cursor
El cursor puede tomar cuatro distintos estados en funcin del objeto sobre el que se encuentre, puede ser un objeto seleccionado, un objeto no seleccionado, el eje manipulador, y el vaco. En

199

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE VI

IMPLEMENTACION

201

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

202

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

INDICE
PARTE VI ...................................................................................................... 6.1 Introduccin ..............................................Error! Marcador no definido.
6.2 Parametrizacin de datos................................................... Error! Marcador no definido. 6.2.1 El descriptor de parmetros (OSGParamGroupDesc). .............. Error! Marcador no definido. 6.2.2 Los grupos de parmetros (OSGParamGroup) .......... Error! Marcador no definido. 6.2.3 El gestor de parmetros (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 Implementacin 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 Interaccin 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 implementacin ............................. Error! Marcador no definido. 6.8.1 La actualizacin 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 funcin clone......................................................... Error! Marcador no definido. 6.8.4 La funcin DoFrame()................................................ Error! Marcador no definido. 6.8.5 Eliminar un nodo, deshacer y rehacer. ....................... Error! Marcador no definido.

203

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

204

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

6.1 Introduccin
Hasta ahora se han definido los requisitos que deben cumplir cada uno de los subsistemas de los cuales est compuesta la aplicacin. Conociendo estos requisitos que marcan lo que se debe hacer, se realiz un anlisis para alcanzar una primera aproximacin lgica de cada sistema. Posteriormente se realizo la fase de diseo en la que se establece una primera solucin, la cul 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 solucin siguiendo la estructura creada en los apartados anteriores. La implementacin es la parte de ms bajo nivel del proyecto, donde se crean soluciones a problemas concretos planteados en el diseo. Esta parte la dividiremos en 6 apartados, explicando las partes relevantes de la implementacin de cada uno: Parametrizacin de datos. Aqu se presentarn todas las estructuras de datos relacionadas con los grupos de parmetros y los descriptores de parmetros, los TabOutput, ObjectType, NodeType y AttributeType y sus respectivos Gestores, el gestor de parmetros y las funciones ms importantes de cada uno. Implementacin del rbol del grafo de escena. Aqu se explicar el rbol y sus funciones, as como el mtodo a seguir en su duplicado y la gestin de eventos de teclado. Interaccin con el visor 3D. Veremos las acciones a llevar a cabo sobre la seleccin 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 cdigo del sistema gestor de plugins, asi como el cdigo 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 cdigo referente a las clases MFCs.

Y por ltimo aadiremos un apartado extra, que llamaremos Problemas de implementacin , donde explicaremos algunos de los problemas encontrados durante la implementacin, y las soluciones adoptadas. Toda la implementacin se realizar utilizando el lenguaje de programacin C++, ya que es el lenguaje utilizado por la librera 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 cdigo fuente mostrados a continuacin han sido truncados, mostrando solo la informacin considerada como relevante para la explicacin.

205

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

6.2 Parametrizacin de datos


6.2.1 El descriptor de parmetros (OSGParamGroupDesc).
Como ya hemos visto, el descriptor de parmetros sirve para describir nombres y tipos de datos que mas tarde sern representados como controles de un dilogo. 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 bool void void SetEditable(bool Editable); IsEditable(); AddFlag(int _flag); 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 parmetro type define el tipo de parmetro 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 parmetros (OSGParamGroup)


Los grupos de parmetros, como su nombre indican tan solo agrupan parmetros y se identifican por un nombre. Representan un grupo en la barra deslizable del la barra de pestaas (Tabs) del editor, se asignaran a un Tab concreto de la barra de Tabs que no es ms que un dilogo, que puede agrupar varios parmetros distintos de una misma categora referentes a un mismo objeto. Contendr opcionalmente un botn que permitir plegar y desplegar el contenido de los controles que pertenecen a ese grupo de parmetros (rollable).
class OSGParamGroup : public std::vector<OSGParamGroupDesc*> { 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
inline inline inline inline inline inline inline bool IsRollable(){return rollable;} void SetExpanded(bool bexp){expanded=bexp;} bool IsExpanded(){ return expanded;} void SetGroupPage(RC_PAGEINFO *pg){page=pg;} RC_PAGEINFO * GetGroupPage(){return page;} CDynDialogEx *GetDialog(){return dialog;} 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 parmetros (OSGParamManager)


Esta clase proporciona mecanismos para crear todos y cada uno de los controles asociados a cada tipos de descriptor de parmetro de forma dinmica, y en tiempo de ejecucin. Tambin se encarga de registrar los controles internamente manteniendo unas tablas hash para identificar los descriptores de parmetros con su grupo de parmetros 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 void void void void void void void void void void *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); CreateButton(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateStatic(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateTextbox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateEditbox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateSpinner(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateRadio(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateRange(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateVector3(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateVector4(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateListbox(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc *desc); CreateColorSwatch(CDynDialogEx *dlg, OSGTabOutput *nt, OSGParamGroupDesc

protected: int last_id; std::map<int, OSGTabOutput*> hash_idoutput; std::map<int, OSGParamGroupDesc*> hash_idparamgroupdesc;

208

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
CRect curr_rect; };

La funcin NotifyObjectType se invoca por el sistema cuando el un parmetro se ha modificado, y el gestor de parmetros se encarga de notificar al OSGTabOutput que lo contiene del evento.
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 case case case TYPE_RADIO: TYPE_BUTTON: TYPE_CHECKBOX: 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
case case case case case EDITTYPE_INT: EDITTYPE_VEC3_FLOAT: EDITTYPE_VEC4_FLOAT: EDITTYPE_RANGE_FLOAT: 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 (parmetro) lo hemos podido representar en un dilogo utilizando los controles comunes que proporciona la API de Win32. No obstante, para representar un color hemos querido hacer una excepcin; un color no es ms 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 numricamente 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 pequeo rectngulo 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 BYTE BYTE BYTE protected: BYTE BYTE BYTE BYTE CWnd public: afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); }; GetRed(); GetGreen(); GetBlue(); GetAlpha();

m_bRed; m_bGreen; m_bBlue; m_bAlpha; *pNotifyWnd;

Este control mostrar un dilogo de seleccin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

6.2.5 Las clases OSGTabOutput y OSGTabOutputManager


Aunque la clase OSGTabOutput derivar en otras tres ms, mantendremos una variable para saber de antemano que tipo de OSGTabOutput estamos usando:
#define #define #define #define OUTPUT_TYPE_DEFAULT 0 OUTPUT_TYPE_OBJECT 1 OUTPUT_TYPE_NODE 2 OUTPUT_TYPE_ATTRIBUTE 3

Esta clase proporciona los mecanismos necesarios para construir un objeto que se muestre en la barra de pestaas principal, ms concretamente un dilogo, 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 void void void void void void void void void void GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int GetParamValue(int param_id, param_id, param_id, param_id, param_id, param_id, param_id, param_id, param_id, param_id, param_id, std::string &value); int &value); osg::Vec3f &value); osg::Vec4 &value); float &value); osg::Vec4d &value); osg::Quat &value); osg::Matrixd &value); CPoint &value); std::string &value, int row, int col); float &min, float &max);

void AddParamFlag(int param_id, int addflag); void RemoveParamFlag(int param_id, int addflag); bool IsParamEditable(int param_id); void void void void void void void void void void SetParamValue(int param_id, std::string &value); SetParamValue(int param_id, int &value); SetParamValue(int param_id, float &value); SetParamValue(int param_id, float &min, float &max); SetParamValue(int param_id, osg::Vec3f &value); SetParamValue(int param_id, osg::Vec4 &value); SetParamValue(int param_id, osg::Vec4d &value); SetParamValue(int param_id, osg::Quat &value); SetParamValue(int param_id, osg::Matrixd &value); SetParamValue(int param_id, std::vector<std::string> &values, bool sorted=true); void SetParamValue(int param_id, OSGW_PAIRLIST &values);

212

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 parmetro y establecer este valor son GetParamValue y SetParamValue. Estas funciones estarn sobrecargadas para todos y cada uno de los tipos de datos que soporta el descriptor de parmetros. Tambin podremos asignar flags a los parmetros. De momento solo estn implementados dos flags:
#define DESC_EDITABLE 0 #define DESC_READONLY 1

La funcin MapIOControls() la realiza el TabOutputMananger automticamente, 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 parmetros que tendr el TabOutput. Al mismo tiempo se actualiza la tabla hash que relaciona cada uno de los parmetros con su descriptor de parmetros 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 parmetros 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 pestaa del interfaz permite la creacin de nodos en el grafo. Esta clase deriva de OSGTabOutput y se implementa como 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 (funcin Attach y Detach) La notificacin de fin de seleccin (RecursiveOnEndSelection) Notificacin de que se ha modificado algun parmetro 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 void void void ShowRecursiveData(osg::Object *obj = NULL); RecursiveOnEndSelection(osg::Object *obj = NULL); RecursiveClearRollupContent(); 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 tambin un puntero al ObjectType que est actualmente enlazando a este ObjectType, y el objeto OpenSceneGraph que est actualmente representando. Tambin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 prcticamente idnticas.

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, desc[1].Set(1, desc[2].Set(2, desc[3].Set(3, desc[4].Set(4, desc[5].Set(5, desc[6].Set(6, desc[7].Set(7, desc[8].Set(8, desc[8].Set(9, TYPE_CHECKBOX, "Soporta DisplayList"); TYPE_CHECKBOX, "Usa DisplayList"); TYPE_CHECKBOX, "Usa Objetos Vertex Buffer"); TYPE_CHECKBOX, "Requiere update traversal", DESC_READONLY); TYPE_CHECKBOX, "Requiere event traversal", DESC_READONLY); TYPE_STATIC, "Bound inicial"); EDITTYPE_VEC3_FLOAT, "BBMin"); EDITTYPE_VEC3_FLOAT, "BBMax"); TYPE_CHECKBUTTON, "Mostrar Shape"); 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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\nCrearlo?", MB_YESNO|MB_ICONQUESTION) == IDYES) { osg::StateSet *sts = new osg::StateSet(); node->setStateSet(sts); ShowAttachData(ATT_STATESET, sts);

218

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 Implementacin 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 void void void void AddParent(TreeNodeInfo *newtni, bool node_too=true); RemoveParent(TreeNodeInfo *tni, bool node_too=true); RemoveChild(TreeNodeInfo *child, bool node_too=true); SetChild(int i, TreeNodeInfo *newtni, bool node_too=true); 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 HTREEITEM GetTreeItem(int index, int mirror_index=0);

219

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 aadir padres o hijos, asi como desvincularlos. Adems, 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 mltiplemente instanciado 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:
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 virtual virtual virtual virtual virtual virtual virtual

bool bool void void void void void void

HandleKeyDown(WPARAM wParam, LPARAM lParam); NewItem(TVINSERTSTRUCT & ins); OnNewItem(HTREEITEM hItem); CreateCursorMap(); SortCurrentLevel(HTREEITEM hItem = 0); SortCurrentLevelAndBelow(HTREEITEM hItem = 0); DisplayContextMenu(CPoint & point); ExtendContextMenu(CMenu & menu);

protected: virtual virtual virtual virtual virtual

void void void void void

DragStart(); DragMove(); DragEnd(); DragStop(); SetDragCursor(HTREEITEM hDropTarget, EDropHint hint);

220

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
virtual CDragData * bool bRightDrag); virtual virtual virtual virtual virtual virtual virtual virtual public: virtual bool virtual bool virtual bool bool DoCopyClipboard(int copyOp); DoPasteClipboard(); DoDeleteItem(HTREEITEM); IsAncestor(HTREEITEM hItem, HTREEITEM hCheck) const; bool bool bool bool bool bool bool bool DoEditLabel(HTREEITEM); DoInsertSibling(HTREEITEM); DoInsertChild(HTREEITEM); DoInsertRoot(HTREEITEM); DoSortCurrentLevel(HTREEITEM); DoSortCurrentLevelAndBelow(HTREEITEM); DoSelectFromScene(HTREEITEM hItem); DoAddSelectFromScene(HTREEITEM hItem); CreateDragData(HTREEITEM hDragItem,

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 tambin. Tambin proporciona funciones para Seleccionar todas las instancias de un mismo nodo, o modificar el color de un subrbol (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 ratn. Tambin permite ordenar un nivel y sus descendientes. Esta clase tambin tendr la funcionalidad de aadir un men contextual (para cuando se pulse el botn derecho del ratn), que permite distintas opciones sobre el elemento seleccionado. Los eventos de copiar y pegar nodos usando el teclado (Copiar y Pegar) estn incluidos en la siguiente funcin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
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 extensin de la anterior y permite mltiple seleccin de objetos. Esta clase tan solo tiene que sobrecargar las funciones virtuales que necesite modificar para adaptar su comportamiento para la seleccin mltiple. La principal diferencia de la clase anterior es su funcin 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)) {

222

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 extensin del rbol aade funcionalidades ms 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 inicializacin 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 funcin muy importante, SetRootNode(), que permite establecer como nodo raz (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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
return mireader.GetRootItem(); }

La clase readNodeVisitor utilizada dentro de la funcin 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 funcin, pero OpenSceneGraph seguir invocndola para todos y cada uno de los nodos del grafo. Dentro de esta funcin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 ms 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 ms 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 aadir una nueva Bar, conteniendo los rboles de las distintas escenas. La funcin 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 Interaccin con el visor 3D


6.4.1 La clase OSGSelection
La principal clase relacionada con la interaccin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
int cursor_over; // sobre qu esta el cursor 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 seleccin. 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. Tambin 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 transformacin se guardar en una variable el valor del centro de la seleccin (mouse_saved_pos) , y el valor actual del centro de la seleccin se almacena 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:
enum { CURSOR_OVER_NOTHING=0, CURSOR_OVER_UNSELECTED_OBJECT, CURSOR_OVER_SELECTED_OBJECT, CURSOR_OVER_AXIS};

Y definen si el cursor no est encima de nada, esta encima 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 ratn, y se engarga de actualizar la forma del cursor en funcion de la variable cursor_over haciendo uso de la funcion GetIntersection(), la seleccin y la posicion de la boundingbox que la define asi como el eje manipulador.
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_over = CURSOR_OVER_UNSELECTED_OBJECT; } } } else // ningun objeto seleccionado en pantalla {

228

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 ratn 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 funcin OnLButtonDown() se invoca al pulsar el botn izquierdo del ratn, en funcin 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 adems tenemos pulsada la tecla Shift, lo que conseguiremos ser clonar la seleccin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 simultneamente 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> osg::ref_ptr<osg::Switch> osg::ref_ptr<osg::Switch> osg::ref_ptr<osg::Switch> int selected_axis; int last_selected; }; p_xy; p_zx; p_zy; switch_ejes;

Esta clase consta de una serie de nodos, Switches e informacin geomtrica que se irn 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 6.1. Estructura del grafo que forma el Eje Manipulador

La funcin SetAxis() es la encargada de activar y desactivar los distintos hijos de los Switches de OpenSceneGraph que darn al eje manipulador el comportamiento que queremos. Los hijos los identificaremos por un nmero:
#define #define #define #define #define #define #define CHILD_NORMAL_AXIS CHILD_X_AXIS CHILD_Y_AXIS CHILD_Z_AXIS CHILD_XY_AXIS CHILD_ZX_AXIS CHILD_ZY_AXIS 0 1 2 3 4 5 6

Y la funcin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 ratn. Tambien es la que almacena los distintos cursores que toma la aplicacin en funcin del modo activo. Es en esta clase donde se decide si el movimiento del ratn deber hacer una llamada a rotar, escalar, o trasladar, dentro de la funcin mouseMotion(). Adems es la clase que contiene el objeto OSGSelection, y tambin el objeto TrackBall. La clase Producer::Trackball proporciona a la vista movilidad y un comportamiento de rotacin o desplazamiento de cmara, y permite establecer la vista directamente con su matriz en caso necesario.
class MFCKeyboardMouseCallback : public Producer::KeyboardMouseCallback { public: MFCKeyboardMouseCallback(osgUtil::SceneView* sceneView); void home(); virtual void virtual void virtual void virtual void virtual void virtual void virtual void virtual void virtual void

keyPress( Producer::KeyCharacter key); specialKeyRelease( Producer::KeyCharacter key); specialKeyPress( Producer::KeyCharacter key); mouseScroll(Producer::KeyboardMouseCallback::ScrollingMotion sm); mouseMotion( float mx, float my ) ; passiveMouseMotion( float mx, float my ) ; buttonPress( float mx, float my, unsigned int mbutton ); buttonRelease( float mx, float my, unsigned int mbutton ) ; doubleButtonPress(float mx, float my, unsigned int mbutton ) ;

233

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 float float unsigned int osg::ref_ptr<Producer::Trackball> osg::ref_ptr<osgUtil::SceneView> bool bool bool bool _mx, _my; _mx_buttonPress, _my_buttonPress; _mxdrag, _mydrag; _mbutton; _trackBall; _sceneView;

key_ctrl; key_shift; clone_actived; 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Veamos un ejemplo de accin, 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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, derivndola de OSGNodeType, de manera similar a como hemos hecho con la clase Drawable derivndola de OSGObjectType:
class PluginCartoon : public OSGNodeType { public: PluginCartoon(void);

236

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
~PluginCartoon(void); virtual virtual virtual virtual virtual virtual virtual }; void ShowCustomData(osg::Object *obj); void CreateIOControls(); void ParamModified(osg::Object *obj, int param_id); void AttachParamModified(int attach_id, int param_id){} void OnEndSelection(osg::Object *obj){}; osg::ref_ptr<osg::Object> NewInstance(); 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 extern extern extern "C" "C" "C" "C" PLUG_API PLUG_API PLUG_API PLUG_API OSGTabOutput* LibClassInstance(int i); int LibNumClasses(); std::string LibDescription(); 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 da un aspecto 2D a la geometria 3D"; return str; } PLUG_API int LibVersion() { return OSGWORLD_VERSION; }

tipo Cartoon que

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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
std::string path; int version; std::string desc; HMODULE handle; TabOutputList objlist; };

Contiene informacin acerca del fichero que se corresponde con el plugin, la ruta, la version con la que fue compilado, la descripcin del mismo, el manejador que nos ha devuelto, y la lista de objetos OSGTabOutput que contiene.
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 typedef typedef typedef OSGTabOutput* int std::string int (*PL_LIBCLASSINSTANCE)(int); (*PL_LIBNUMCLASSES)(void); (*PL_LIBDESC)(); (*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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 informacin 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, "Descripcin:", 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 aplicacin (sin tener en cuenta el cdigo generado por las MFCs).
OSGActiveViewHandler *OSGAVH;

Y ser la encargada de contener las instancias de todos los distintos gestores del sistema, asi como distintas funcionalidades globales.
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 void void void void void void void SelectObject(HTREEITEM hItem, bool select=true); SelectObjectOnly(std::vector<HTREEITEM> &vec); SelectObjectOnly(HTREEITEM hItem); SelectObjectFromTree(HTREEITEM hItem, bool select=true); SelectObject(int x, int y); SelectObject(osg::Node * node, osg::Group *parent,bool select); SelectObject(TreeNodeInfo *node, TreeNodeInfo *parent, bool select); SelectAll(bool select);

void ShowTreeNodeInfo(TreeNodeInfo *tni, bool reset=true); void ShowTabOutput(OSGTabOutput *outp); void Exec(OSGAction *action, bool addtohistory=true);

241

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.
void void void BOOL CloseAllMirrors(); OnCloseScene(int scene_id); OnCloseTreeBar(CTreeBar *treebar); 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 IsSceneActive(int scene_id); 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 parmetros, el gestor de TabOutputs, el gestor de plugins, el gestor de TreeBars, el gestor de historia actual, y la seleccin de objetos, y una instancia de la barra principal que es un conjunto de pestaas, cada una con una funcionalidad diferente. Tambin contiene una referencia al visor actual y su superficie de render, as como el nodo raz de la escena del grafo de escena. Esta clase es la encargada de mostar la informacin de un nodo de un grafo de escena en el interfaz de usuario, lo que hace realmente esta funcin es mostrar los datos del nodo a travs de su NodeType:
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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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; }

Tambin implementa una funcin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 pestaas. Los Rollups son dilogos que permiten extenderse ms de lo que la pantalla ocupa, generando una especie de barra de Scroll en caso de extenderse ms de los lmites visuales de la aplicacin:
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, m_wndSheetBar.AddRollup(p2, m_wndSheetBar.AddRollup(p3, m_wndSheetBar.AddRollup(p4, m_wndSheetBar.AddRollup(p5, IDD_TAB_CONTAINER, IDD_TAB_CONTAINER, IDD_TAB_CONTAINER, IDD_TAB_CONTAINER, IDD_TAB_CONTAINER, IDI_ICON5); IDI_ICON6); IDI_ICON7); IDI_ICON8); 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 objecttypem.RegisterType(new objecttypem.RegisterType(new objecttypem.RegisterType(new objecttypem.RegisterType(new objecttypem.RegisterType(new objecttypem.RegisterType(new objecttypem.RegisterType(new objecttypem.RegisterType(new objecttypem.RegisterType(new

AttTypeFog()); AttTypeMaterial()); AttTypeBlendFunc()); AttTypeLight()); AttTypeTexEnv()); AttTypeTexGen()); AttTypeTexture()); AttTypeTexture2D()); AttTypeVertexProgram()); 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 de inicializar los datos de le escena, e informar al Manejador de la Vista Activa de que se ha seleccionado esta vista como activa. Al cargar un fichero, las MFCs crean una nueva clase Documento y otra de Vista (COSGWorldView) que se muestra a continuacin.

class COSGWorldView : public CView { public: static COSGWorldView * COSGWorldView::GetActiveView(); // Reemplazos public: virtual void OnDraw(CDC* pDC); void void void void

// Reemplazado para dibujar esta vista

SetPolygonMode(osg::PolygonMode::Mode m); SetShading(osg::ShadeModel::Mode m); SetProjectionType(ProjectionType pt); 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 ratn La visualizacin del grafo de escena la escena La funcion de dibujado

Adems, contendr una referencia al nodo raz 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 funcin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 implementacin.


6.8.1 La actualizacin de OpenSceneGraph 0.9 a 1.0.
Este problema requiri indagar el cdigo fuente propio de OpenSceneGraph. Para establecer el nodo raz 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 raz, podemos volver a consultarlo mediante la funcin. Puesto que nosotros sabemos cual es el nodo raz, sabemos que no contiene ningn padre. En cierto punto del programa realizamos la comprobacin de que el nodo no contenga ningn padre para identificarlo como nodo raz. Hasta aqu todo funcionaba bien. En la versin 1.0 de la librera, 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 raz deja de cumplir la condicin que antes buscabamos, y el programa comienza a cascar. La solucin para acceder al nodo realmente raz del grafo fue la llamada a GetCamera() de la clase SceneView.

6.8.2 La clase RefParticle.


La clase ObjectType de nuestra aplicacin est pensanda para representar un tipo de dato de OpenSceneGraph. Tras haber estudiado a fondo la librera, 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 aplicacin. 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

No existi ningun problema hasta que nos encontramos con el objeto osgParticle::Particle. Este objeto no deriva de ningun otro, y adems, es un objeto importante a la hora de trabajar con sistemas de partculas. La solucin 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 funcin GetParticle() para acceder a los datos en s.

6.8.3 La funcin clone.


Esta funcin la implementan los objetos OpenSceneGraph para generar nuevas instancias de objetos a partir de otros. Esta funcin se utiliza para crear el duplicado de ramas (la funcion copiar simplemente aade 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 aade 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 suceda es que se creaba un duplicado y una copia, puesto que al realizar la llamada a clone, se obtena una instancia del objeto con la misma informacin, pero tamben con la informacin de los padres y los hijos. La solucin fue eliminar tanto los padres como los hijos del objeto recin clonado antes de seguir trabajando con l.

6.8.4 La funcin DoFrame().


La clase OSGWorldView realiza una llamada a la funcin OnStartRendering cuando se produce el evento de posicionar el ratn sobre el rea de dibujado de la vista. Esta funcin entra en un bucle que realiza la llamada a DoFrame() que es la encargada de realizar el proceso de render de OpenSceneGraph. Cuando el ratn abandona el proceso de dibujado, el bucle termina y la escena deja de actualizarse.

250

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Pero como a nosotros nos interesa que la escena contine mostrndose indefinidamente, para poder apreciar los cambios que se produzcan en la escena al modificar los parmetros de cualquier nodo o cualquier tipo de dato, eliminamos la condicin del bucle y lo dejamos de manera indefinida. Consecuencia : La aplicacin se ralentiza y es imposible manipular los controles. Una posible solucin era indicar a la View que repintase la escena al modificar cualquier parmetro 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 ejecucin o enviar algn 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 impresin de que la escena est en continuo movimiento, sin afectar en absoluto al resto de la aplicacin.

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 accin, 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 accin estaremos creando un nuevo tem. Por tanto, el TreeNodeInfo deber actualizar sus referencias al rbol.

251

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Pero eso no es todo, si al deshacer la accin, continuamos deshaciendo acciones, podremos encontrarnos alguna accin que haga referencia al tem del rbol que ya no existe. Una solucin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE VII

APLICACIONES DE PRUEBA

253

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

254

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

INDICE
PARTE VII......................................................................................................
7.1 Introduccin ...................................................................... Error! Marcador no definido. 7.2 El editor OSGWorld.......................................................... Error! Marcador no definido. 7.2.1 Especificacin de los elementos del Interfaz grfico. 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 Utilizacin de Sistemas de partculas para crear fuego y humo. Error! Marcador no definido. 7.3.2 Utilizacin 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 Instanciacin 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

256

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

7.1 Introduccin
Hasta ahora se han desarrollado todos los elementos necesarios para el correcto funcionamiento de la aplicacin. En este captulo, se pretende demostrar la funcionalidad del trabajo realizado, asi como introducir tanto los elementos del interfaz, como los conceptos bsicos para el manejo de la aplicacin, y mostrar algunos ejemplos que se han podido realizar como prueba.

7.2 El editor OSGWorld.


7.2.1 Especificacin de los elementos del Interfaz grfico.
La aplicacin constar de un interfaz de ventanas que permitirn al usuario realizar todas las acciones posibles de interaccin. Para ello se han intentado seguir ciertos criterios: Que sean elementos intuitivos, de forma que los usuarios con una rpida visualizacin 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 aplicacin le parezca lo ms dinmica posible al usuario. Para ello se intentar disminuir en lo posible el nmero de dilogos 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 aplicacin.

Figura 7.1. Aspecto del interfaz grfico

El interfaz estar compuesto principalmente de los siguientes elementos:

257

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 ms comunes en la utilizacin del editor. Una barra de nodos para la creacin 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 informacin de depuracin 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

La barra de mens se encuentra directamente debajo de la barra de ttulo de la ventana principal. El ttulo de cada men indica la finalidad de los comandos que contiene. Todos los mens siguen las convenciones estndar de Microsoft Windows. Al seleccionar un men, se abre un men desplegable que muestra varios comandos. Como alternativa al uso del ratn (u otro dispositivo sealador), cada nombre de men incluye un carcter subrayado. Al presionar la tecla correspondiente junto con la tecla ALT, el men se abre. Los comandos de los mens abiertos normalmente tienen tambin un carcter subrayado. Mientras el men est abierto, puede presionar la tecla correspondiente al carcter para que el comando se ejecute. Los puntos suspensivos () al final de un comando indican que abre un cuadro de dilogo. Una flecha hacia la derecha despus de un comando indica la aparicin de un submen. Si un comando tiene un mtodo 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 verificacin. 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.

258

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Menu Edicin

Deshacer: El comando Deshacer invierte la ltima operacin realizada con el objeto u objetos seleccionados. Rehacer: Invierte la ltima operacin 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 operacin de copiado. Replicar seleccin: Crear una rplica exacta de la seleccin (instanciada), y desplazada de la original.

Menu Ver Barra de herramientas: Muestra u oculta la barra de herramientas principal de la aplicacin. Barra de estado: Muestra u oculta la barra de estado de la aplicacin. Barra de Nodos: Muestra u oculta la barra de nodos de la aplicacin. Barra de paneles: Muestra u oculta la barra paneles de la aplicacin. Ventana de depuracin: Muestra u oculta la ventana de depuracin de la aplicacin.

259

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 7-2. Modo de visualizacin de rejilla.

Menu Escena Nuevo rbol: Crea una nueva barra conteniendo el rbol del grafo de escena. Seleccionar por nombre: Muestra un dilogo de seleccin de nodos por nombre. Centrar seleccin: Centra la seleccin 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. Dilogo de seleccionar por nombre.

260

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Menu Representacin 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 funcionarn si no existe ningn elemento seleccionado en el rbol.

261

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 rpido a herramientas y cuadros de dilogo 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 operacin de copiado.

Deshacer: El comando Deshacer invierte la ltima operacin realizada con el objeto u objetos seleccionados. Rehacer: Invierte la ltima operacin realizada por el comando Deshacer.

262

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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 dilogo de seleccin 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 seleccin: Centra la seleccin de objetos actual del visor en pantalla.

Figura 7-4. Ejemplo de la manipulacin 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 OpenSceneGraph en el grafo de escena.

Nodo Projection: Inserta un nodo Projection como hijo del nodo actual. Nodo LOD: Inserta un nodo LOD como hijo del nodo actual.

263

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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. Nodo PositionAttitudeTransform: Inserta un nodo PositionAttitudeTransform como hijo del nodo actual. Nodo Sequence: Inserta un nodo Sequence como hijo del nodo actual. Nodo Billboard: Inserta un nodo Billboard como hijo del nodo actual. Nodo ParticleSystemUpdater: Inserta un nodo ParticleSystemUpdater como hijo del nodo actual. Nodo ModularEmitter: Inserta un nodo ModularEmitter como hijo del nodo actual. Nodo FluidProgram: Inserta un nodo FluidProgram como hijo del nodo actual. Nodo SpecularHighlights: Inserta un nodo SpecularHighlights como hijo del nodo actual. 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. Slo 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

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.

Figura 7-5. Panel de creacion de nodos.

Panel Nodos: Permite manipular los parmetros de los nodos del grafo. Cada escaln en el rbol de jerarquia del nodo se representa por un grupo distinto, pudiendo modificar los parmetros de manera independiente a medida que el nodo va aumentando su complejidad.

Figura 7-6. Panel de parmetros de nodos.

265

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Panel StateSet: Permite crear o eliminar StateAttributes al StateSet de un nodo o un Drawable y modificar sus parmetros. 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Panel Plugins: Muestra un listado de los plugins cargados por el editor asi como informacion adicional sobre cada uno de ellos.

Figura 7-8. El panel de plugins.

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 simultneas de una misma escena.

Figura 7-9. La barra del rbol del grafo de escena.

267

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Figura 7-10. Visualizacin de varias vistas simultneas del rbol del grafo de escena.

El rbol adems permite la pulsacion del botn derecho del ratn sobre los elementos mostrando un men contextual de Opciones: Seleccionar: Selecciona en el visor los elementos del rbol seleccionados. Agregar a seleccin: Agrega a la seleccin en el visor los elementos del rbol seleccionados. Eliminar: Elimina los elementos del arbol seleccionados. Ordenar: o Nivel Actual: Ordena alfabticamente el nivel actual de los nodos seleccionados en el rbol. o Nivel actual y debajo: Ordena alfabticamente el nivel actual de los nodos seleccionados en el rbol y sus descendientes. Seleccionar todos: Selecciona todos los elementos del rbol. Seleccionar ninguno: Deselecciona todos los elementos del rbol. Expandir subrbol: Expande el subrbol que contiene el elemento actual del rbol en caso de estar contraido. Contraer subrbol: Contrae el subrbol que contiene el elemento actual del rbol en caso de estar expandido.

268

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

7.2.1.6 El Visor 3D
El visor es el rea de la aplicacin donde se muestra en tiempo real la representacin final de la geometria del grafo es escena. Acciones sobre el editor El visor permite cierta interaccin directa con el usuario haciendo uso del teclado y el ratn de manera conjunta y con ayuda del eje manipulador.

Figura 7-11. Composicin de una escena completa utilizando el editor.

Al seleccionar uno o ms objetos en el visor, automticamente nos aparecer un eje auxiliar como el de la figura. Este eje nos permitir aplicar transformaciones a la seleccin actual sobre el eje o los ejes iluminados de manera simultnea (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 seleccin actual: Se pueden agregar objetos a la seleccin 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

269

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

podemos rotar objetos alrededor de si mismos sobre cualquiera de los 3 ejes, o sobre dos ejes simultneos. 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 simultneos. o Escalado uniforme: Si mantenemos pulsada la tecla maysculas 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 seleccin manteniendo pulsada la tecla maysculas a la vez que hacemos una traslacin. El resultado se puede apreciar en la Figura 7.8. Mostrar los parmetros de un objeto: Se puede forzar la seleccin del objeto actual del rbol del grafo para mostrar sus parmetros en el panel de Nodos haciendo doble click sobre el objeto que queramos en el visor.

Figura 7-12. Clonado rpido de objetos usando teclado y ratn.

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 utilizacin de la aplicacin.

270

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

7.3.1 Utilizacin de Sistemas de partculas para crear fuego y humo

7.3.2 Utilizacin de las Luces.

271

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

7.3.3 Efecto Cartoon

7.3.4 Efecto BumpMapping

272

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

7.3.5 Efecto de Specular Highlights

7.3.6 Instanciacin multiple

273

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

7.3.7 Efecto de niebla.

7.3.8. Ejemplo de utilizacion de Shaders

274

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE VIII

CONCLUSIONES

275

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

276

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica 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

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

8.1 Conclusiones
Con todo esto, podemos concluir haber cumplido con los objetivos planteados al inicio del proyecto: Hemos construido un interfaz amigable, dinmico y sencillo de manejar. Adems, 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 estarn muy familiarizados con algunos aspectos de la aplicacin. 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 ratn (arrastrando elementos) o de teclado. Adems, podemos estableces tantas vistas simultneas del rbol como queramos, lo cual facilitar en gran medida la manipulacin 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 parmetros de manera sencilla. Podemos manipular la escena directamente, aplicando transformaciones a los objetos, copindolos o duplicndolos e incluso eliminndolos directamente de la pantalla. Adems, 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 ratn se desplaza, de este modo, hemos conseguido que el usuario tenga la impresin de estar realmente moviendo objetos por la pantalla. Hemos conseguido que la mayora de acciones puedan ser invertibles, incluso en aquellos casos en los que la accin requiera eliminar objetos. De este modo, estamos ahorrando al usuario el tiempo que podra dedicar a corregir muchos errores que se cometen en el manejo de aplicaciones, y que podra costarnos mucho mas tiempo del que pensamos. Hemos dotado a la aplicacin de un sistema de plugins, proporcionando un conjunto de libreras o Kit de Desarrollo, que permitirn al desarrollador implementar nuevas funcionalidades en el programa de una manera sencilla, y con un mnimo esfuerzo.

Como conclusiones personales del alumno, podemos destacar que se ha conseguido familiarizar con el entorno de programacin Visual .NET, se ha aprendido a fondo el funcionamiento de la librera OpenSceneGraph, y se ha profundizado en la utilizacin de estructuras de datos en C++. Del mismo modo, se han adquirido nuevos conocimientos sobre la programacin en Windows, y ms concretamente sobre las MFC, la generacin de controles, y las peculiaridades propias de esta librera. 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.

278

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

8.2 Trabajos futuros


La lista de nuevas funcionalidades que se podra aadir a la aplicacin podra 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 continuacin pasaremos a enumerar aquellos de los trabajos futuros que hemos considerado como ms 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 podra abarcar desde el desarrollo de un sistema de motion capture para la aplicacin, hasta la implementacin de nuevos tipos de nodo que todava no estn implementados en la aplicacin, o nuevos efectos que vayan apareciendo, ya que OpenSceneGraph es una librera relativamente joven y en continuo desarrollo. Permitir el desarrollo de plugins de exportacin e importacin de ficheros. Hasta ahora la aplicacin permite plugins de tipos de datos, y plugins genricos (que se muestran en el panel de comandos, y permiten manipular cualquier informacin de la escena), pero no existe manera de importar o exportar tipos de datos desconocidos, para ello se debera de implementar un tipo de plugin especfico para esta tarea. Aadir nuevos manipuladores. Estos objetos auxiliares se conocen en 3D Studio Max como Guizmos, y existe uno distinto para cada tipo de transformacin. En nuestro caso hemos utilizado el eje manipulador (Guizmo de traslacin en 3d max) para cualquier transformacin. Agregar la posibilidad de trasladar luces como su fueran objetos. Esta opcin 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 animacin. Existen estructuras de datos en OpenSceneGraph que gestionan la animacin, y sera interesante que fueran manipulables desde el editor. Permitir crear agrupaciones de elementos. Una caractersticas de cualquier software 3D, permite agrupar elementos (independientemente de su disposicin en el grafo), de manera que al estar agrupados las transformaciones afectan por igual a cada uno de los miembros. Aadir un sistema de representacin de 4 visores simultneos. Debido al sistema de representacin que utiliza OpenSceneGraph, nos resultaba algo complicado aadir esta funcionalidad, por lo que el tiempo de implementacin estimado hubiera sido sobrepasado. Adicin de interfaces multimodal avanzados para agilizar y facilitar al usuario el montaje de las escenas. Esta caracterstica podra consistir en aadir un sistema de captura al programa para aplicar transformaciones a los objetos, sustituyendo al ratn, de esta manera se podran por ejemplo desplazar objetos en es espacio 3D de una manera ms intuitiva que con un ratn.

8.3 Comparativa con OSGEdit.


Para terminar el apartado de conclusiones, vamos a pasar a realizar una comparativa con el software ms parecido que existe actualmente para la edicin de escenas en OpenSceneGraph. En esta comparativa enumeraremos las distintas funcionalidades de cada aplicacin en una tabla, indicando su disponibilidad en color verde, y su ausencia en color rojo.

279

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Funcionalidad Representacin 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 aplicacin. Visualizacin mltiple del rbol Mapeado de parmetros de tipos de datos Adicin de StateAttributes Transformacin inteligente de Geodes Transformacin 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 simultneas

OSGEdit

OSGWorld

280

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

PARTE IX

BIBLIOGRAFIA

281

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

282

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

Bibliografa.
Libros: [1] Marcos Fernndez, apuntes de las asignaturas Informtica Grfica y Ampliacin de Informtica Grfica. Ao 2004. [2] Deitel & Deitel. Cmo programar C++. Prentice Hall. [3] Jeffrey Richter. Programacin Avanzada en Windows. Microsoft Press. [4] Richard C. Leinecket y Tom archer. La Biblia de Microsoft Visual C++ 6.0. Anaya multimedia. Ao 1999. [5] Herbert Schildt. Programacin con MFC 6.0. Osborne McGraw-Hill. Ao 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, Introduccin a la graficacin por computador. Addison-Wesley Ibero-Americana. [10] Bernie Reahl. El creador de mundos virtuales. Anaya multimedia. Ao 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. Programacin en OpenGL. Anaya multimedia. Ao 1996. [15] Christopher Lampton. Vuelos de fantasa. Anaya Multimedia. Ao 1993. [16] T. Akenine-Mller 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. Versin Junio 2006.

283

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

[20] Autodesk. 3D Studio MAX Software Development Kit Help (SDK). Versin 5.1.
U U

[21] Miguel Lozano, Carlos caldern. Entornos virtuales 3D clsicos e inteligentes: hacia un nuevo marco de simulacin para aplicaciones grficas 3D interactivas. Departmento de Informtica, Universidad de Valencia.
U U U

[22] George Eckel, Ken Jones, Tammy Domeier. OpenGLPerformer Getting Started Guide. Version 3.2. Silicon Graphics, Inc. Ao 2004.
U U

[23] George Eckel,Ken Jones. OpenGLPerformer Programmers Guide. Version 3.2. Silicon Graphics, Inc. Ao 2004.
U U

Pginas y referencias web: [24] http://www.openscenegraph.org/ Pgina oficial de OpenSceneGraph.


H H

[25] http://osgedit.sourceforge.net/ Pgina oficial del OSGEdit.


H H

[26] http://www.opengl.com/ Pgina oficial de la librera OpenGL.


H H

[27] http://es.wikipedia.org/ Wikipedia, la enciclopedia libre.


H H

[28] http://www.ogre3d.org/ Pgina oficial del motor Ogre 3D.


H H

[29] http://www.sgi.com/software/performer/ Pgina de SGI OpenGL Performer.


H H

[30] http://www.multigen-paradigm.com/ Pgina oficial de multigen.


H H

[31] http://www.codepixel.com/ Pagina web orientada a la programacin grfica.


H H

[32] http://openrm.sf.net/ Pgina oficial de la libreria grfica OpenRM.


H H

[33] http://www.opensg.org/ Pgina oficial de la libreria grfica OpenSG.


H H

[34] http://plib.sf.nef/ Pgina web de la libreria Plib.


H H

[35] http://www.r3vis.com/RMSSceneGraph/ Pgina oficial de la libreria RMSceneGraph.


H H

[36] http://www.sgi.com/software/optimizer/ Pgina de la herramienta SGI OpenGL Optimizer.


H H

[37] http://sgl.sf.net/ Pgina oficial de la librera SGL.


H H

[38] http://java.sun.com/products/java-media/3D/ Pgina de la API de Java 3D.


H H

[39] http://www.gamasutra.com/ Pagina web sobre programacin grfica y videojuegos.


H H

[40] http://www.codeproject.com/ Gran cantidad de tutoriales y recursos MFC.


H H

[41] http://www.codeguru.com/ Pgina con cantidad de tutoriales y recursos de programacin.


H H

[42] http://www.nps.navy.mil/cs/sullivan/osgtutorials/ Tutoriales de OpenSceneGraph.


H H

284

E.T.S.E. Universidad de Valencia


Desarrollo de un sistema de edidin de escenas basado en una librera grfica de alto nivel.

[43] http://www.gamedev.net/ Pgina orientada al desarrollo y programacin de videojuegos.


H H

[44] http://developer.kde.org/documentation/tutorials/developing-a-pluginstructure/index_es.html Artculo sobre la arquitectura de plugins.


H H

[45] http://es.wikipedia.org/wiki/Gr%C3%A1ficos_3D_por_computadora/ Artculo sobre la historia de las 3D.


H H

[46] http://www.realityprime.com/scenegraph.php/ Artculo sobre los grafos de escena. Avi Bar-Zeev. Scenegraphs: Past, present and future.
H H

[47] http://www.3dscenegraph.com/ Portal sobre los distintos grafos de escena disponibles actualmente, y gran cantidad de artculos relacionados.
H H

[48] http://www.codeproject.com/dll/RegDLL.asp Ejemplo de creacion de una DLL en Visual Studio.


H H

[49] http://www.codeproject.com/dll/TargetApp.asp Desarrollo de una DLL a modo de plugin.


H H

[50] http://www.clockworkcoders.com/oglsl/index.html Artculo sobre shaders.


H H

[51] http://www.lighthouse3d.com/opengl/glsl/ Tutorial bsico sobre GLSL.


H H

[52] http://www.geocities.com/eric6930/Win32_tips.html Tips sobre programacion de controles Win32.


H H

[53] http://www.gamedev.net/community/forums/ Foros de la comunidad gamedev.


H H

285

You might also like