Sunteți pe pagina 1din 80

Ttulo: Simulacin de efectos fsicos

Alumno: scar Llorens Maldonado Director: Guillem Godoy Balil Departamento: Lenguajes i Sistemas Informticos Data: 3 de Julio de 2008

Simulacin de efectos Fsicos

scar Llorens Maldonado

- Pgina 2 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

DADES DEL PROJECTE Ttol del Projecte:

Nom de l'estudiant: Titulaci: Crdits: Director/Ponent: Departament:

MEMBRES DEL TRIBUNAL (nom i signatura)

President:

Vocal:

Secretari:

QUALIFICACI Qualificaci numrica: Qualificaci descriptiva:

Data:

- Pgina 3 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

- Pgina 4 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

NDICE
1.- MOTIVACIN 2.- INTRODUCCIN 3.- ELECCIN DEL MOTOR 4.- PHYSX DE AGEIA 5.- UTILIZACIN DEL MOTOR 5.1.- INICIALIZACIN Y CONFIGURACIN DEL MOTOR Y LA ESCENA 5.1.1.- INICIALIZACIN DEL MOTOR 5.1.2.- CONFIGURACIN DEL MOTOR 5.1.3.- CREACIN DE LA ESCENA 5.1.4.- MATERIAL POR DEFECTO DE LA ESCENA 5.2.- ALGUNAS FUNCIONES TILES ASOCIADAS A LA ESCENA 5.3.- BUCLE DE EJECUCIN 5.4.- CREACIN DE ACTORES 5.4.1.- DESCRIBIR LA FORMA DEL ACTOR 5.4.2.- POSICIN LOCAL/GLOBAL 5.4.3.- PESO 5.4.4.- CENTRO DE MASAS 5.4.5.- CREACIN DEL ACTOR 5.4.6.- FUNCIONES ASOCIADAS A UN ACTOR 5.4.7.- PINTAR EL ACTOR EN LA ESCENA 5.5.- CREACIN DE CUERPOS RGIDOS CONVEXOS 5.6.- USER REPORTS 5.7.- UNIONES ENTRE ACTORES 7 7 9 12 14 14 14 14 15 16 17 19 22 22 24 24 25 25 26 27 30 32 34

6.- SIMULACIN DE EFECTOS FSICOS 6.1.- GENERACIN DE HUMO 6.1.1.- OBJETIVO 6.1.2.- IDEA 6.1.3.- HERRAMIENTAS USADAS 6.1.4.- IMPLEMENTACIN 6.1.5.- RESULTADO FINAL

37 37 37 37 37 37 39

- Pgina 5 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.2.- SIMULACIN DE UN TORNADO 6.2.1.- OBJETIVO 6.2.2.- IDEA 6.2.3.- HERRAMIENTAS USADAS 6.2.4.- IMPLEMENTACIN 6.2.5.- RESULTADO FINAL 6.3.- OBJETOS ELSTICOS 6.3.1.- OBJETIVO 6.3.2.- IDEA 6.3.3.- HERRAMIENTAS USADAS 6.3.4.- IMPLEMENTACIN 6.3.5.- RESULTADO FINAL 6.4.- ANIMACIN DE ROPA 6.4.1.- OBJETIVO 6.4.2.- MTODO 1 6.4.2.1.- Idea 6.4.2.2.- Herramientas usadas 6.4.2.3.- Implementacin 6.4.2.4.- Resultado final 6.4.3.- MTODO 2 6.4.3.1.- Idea 6.4.3.2.- Herramientas usadas 6.4.3.3.- Implementacin 6.4.3.4.- Resultado final 6.5.- ROTURA DE OBJETOS 3D 6.5.1.- OBJETIVO 6.5.2.- IDEA 6.5.3.- HERRAMIENTAS USADAS 6.5.4.- IMPLEMENTACIN 6.5.5.- RESULTADO FINAL 6.6.- ROTURA DE OBJETOS 2D 6.6.1.- OBJETIVO 6.6.2.- IDEA 6.6.3.- HERRAMIENTAS USADAS 6.6.4.- IMPLEMENTACIN 6.6.5.- RESULTADO FINAL 7.- CONCLUSIN 8.- BIBLIOGRAFIA

40 40 40 41 41 43 44 44 44 45 45 47 49 49 49 49 49 50 54 55 55 55 56 59 61 61 61 62 63 64 66 66 66 67 68 73 75 79

- Pgina 6 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

1.- MOTIVACIN
Aprender el uso de un motor fsico para integrarlo en una aplicacin. Usando las herramientas que proporciona, crear algunos efectos fsicos complejos que el motor no incorpora.

2.- INTRODUCCIN
A menudo en las animaciones de los efectos especiales de pelculas, en simulacin, videojuegos, etc. deben crearse movimientos que simulen varios efectos fsicos. Por supuesto que el animador puede recrear estos efectos de colisiones o deformaciones con el propio editor 3D, pero sera de gran ayuda una herramienta que simulase todo este tipo de animaciones de forma realista. Es muy difcil crear desde cero la animacin de, por ejemplo, un edificio derrumbndose. Sin embargo, esta tarea puede verse reducida a una simple configuracin de los objetos de la escena y de sus propiedades, si se cuenta con otra aplicacin para recrear el efecto fsico del derrumbe del edificio. Muchos simuladores incorporan su propio motor fsico para recrear de forma ms fcil esos efectos. Ejemplos como en la simulacin de avalanchas, en Formula 1 o en empresas automovilsticas, para la construccin de edificios, etc. usan su propio motor fsico. Algunos motores, debido a su precisin tambin se usan en el mbito docente. Tambin en los videojuegos, ahora se est haciendo uso de este tipo de motores (y tal vez por eso ahora este mercado est creciendo). El motor fsico se incorpora en la propia tarjeta grfica para que la simulacin de objetos que se rompen o chocan sea ms eficiente. Hay que tener en cuenta que el clculo de fsicas y en concreto el de colisiones puede llegar a ser muy costoso, dependiendo del nmero de objetos que haya en la escena y de la complejidad de stos. La simulacin de agua a partir de partculas de un cierto tamao, y la posterior creacin de una malla de tringulos que englobe y agrupe las partculas, es un clculo muy complejo que en pocos casos puede realizarse en tiempo real. Muchos editores como 3d Studio, Softimage XSI, Blender, etc. incorporan ya el clculo de fsicas con su propio motor. Blender en concreto utiliza un motor llamado Bullet. Estos editores proporcionan herramientas para simular lquidos, ropa, movimientos humanos, creacin y animacin de cabello, etc. y tambin permiten exportar todas estas animaciones de la misma forma que el resto. Este proyecto consta de dos partes: un tutorial sobre el uso del motor fsico PhysX, y la simulacin de algunos efectos fsicos interesantes. Antes, explico qu motores fsicos hay en el mercado, cuales son

- Pgina 7 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

gratuitos, algunas diferencias entre ellos y el porqu he elegido PhysX de Ageia para realizar el proyecto. Tambin incluyo una introduccin a ste motor en concreto. La primera parte intenta ser una aproximacin rpida (aunque bastante completa) para poder conocer el uso del motor. Hago una breve explicacin de todos los componentes que he usado para simular los efectos fsicos del proyecto, aunque tambin puede estar pensado como un tutorial que explica el funcionamiento de las herramientas ms comunes que usara alguien que quiere empezar a usar este motor para sus proyectos. La segunda parte consta de algunas simulaciones de efectos fsicos usando PhysX, bastante diferentes entre ellas. Mi intencin inicial era hacer ms de las que al final he implementado, pero cada una de ellas result ser ms trabajosa de lo previsto. Tampoco he dedicado mucho tiempo a recrear correctamente la visualizacin de estos objetos, ya que prefera dedicarme ms al mbito fsico que al visual. En concreto, he simulado la generacin de humo como sistemas de partculas, el movimiento y atraccin de un tornado (en concreto, de la trayectoria que describen los objetos atrados por ste), simulacin de objetos elsticos (o al menos, todo lo elsticos que he podido recrear con el motor), simulacin de ropa, de objetos que se rompen en trozos precalculados y la rotura en tiempo de ejecucin de baldosas (objetos semiplanos, 2D pero con grosor). Estas simulaciones no las har desde un punto de vista fsico ni exacto. Son aproximaciones visuales del movimiento o del comportamiento que resultaran de esos efectos fsicos; deben dar la impresin de que est reproduciendo el movimiento real. Finalmente, en la conclusin del proyecto tambin hablar de los avances que se estn haciendo con motores fsicos, que nuevas funcionalidades incorporan y cmo se pretende reducir el tiempo de clculo.

- Pgina 8 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

3.- ELECCIN DEL MOTOR


Existe una interfaz unificada de varios motores fsicos llamada PAL, Physics Abstraction Layer. Permite el uso de mltiples motores en una misma aplicacin, as como cambiar fcilmente de usar un motor a usar otro, o actualizar una versin existente. Adems extiende algunas funcionalidades de los componentes de simulacin ms comunes. Es mucho ms fcil de usar que los dems motores fsicos y no obliga al implementador a usar un motor en concreto. La desventaja es que al estar tan simplificada la interfaz, no podra crear algunos de los efectos fsicos que quera hacer en este proyecto. Sin embargo, ya que incluye motores fsicos gratuitos ms utilizados, puedo aprovecharla para comparar los resultados entre ellos. Contiene unos cuantos tests de colisiones, error de clculo, eficiencia/ests, etc. Utiliza el motor grfico Irrlicht para mostrar los resultados. Los motores a los que somete a los tests son: Bullet: Un muy buen motor fsico, integrado en el editor grfico Blender. Es de cdigo abierto, multiproceso, para uso comercial de forma gratuita y soporta formato fsico de COLLADA. Se ha usado en algunos juegos para PC, PS3 y Xbox360. Jiggle: No es muy conocido, aunque se us para algunos juegos de hace aos, ahora se encuentra poca documentacin sobre este motor. Newton Game Dynamics: Otro motor, de fcil uso pero con pocas funcionalidades. No se ha usado en ningn proyecto mnimamente importante. Novodex: Ahora es conocido como PhysX de la marca AGEIA aunque en PAL siguen poniendo el nombre de Novodex. NVIDIA adquiri la empresa este mismo ao y pretende incorporar el soporte a PhysX en sus tarjetas grficas. Es de comercializacin gratuita (enviando una copia a la empresa), pero de cdigo cerrado. Ofrece muchas funcionalidades. Se ha usado en ms de 140 juegos y la misma marca comercializa una tarjeta para potenciar el clculo y poder simular agua u otros sistemas de partculas. ODE (Open Dynamics Engine): Otro motor gratuito y de licencia abierta para la simulacin de cuerpos rgidos, no es de los ms eficientes pero ofrece mucha precisin. Es muy til para simular vehculos y fricciones. Se usa tambin en el mbito docente. Tokamak: Otro motor de cdigo abierto sin licencia. Es bastante sencillo y tiene pocas funcionalidades. Permite especificar en cierta medida la eficacia o la precisin que se requiere. Es especialmente eficiente cuando simula pilas de cajas y el coste computacional de aplicar friccin en los objetos es mnimo.

- Pgina 9 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

TrueAxis: Un motor slido para la implementacin de videojuegos y de entornos interactivos. Es un motor muy eficiente y puede soportar clculos de colisiones entre objetos con velocidades muy extremas. La licencia para uso no comercial es gratuita, sin embargo para comercializar algn producto que use su motor deben abonarse desde 100 a 10000 dependiendo de la envergadura del proyecto. Las versiones de estos motores en PAL son bastante actuales y no ha habido muchos cambios (tal vez en las funcionalidades si), as que es un buen punto de partida para escoger un motor. A continuacin comentar los resultados de algunos de los tests que incorpora PAL para comparar los distintos motores fsicos. La primera de las pruebas consiste en un conjunto de tests de apilamiento de cajas y de esferas, y en lanzar una esfera contra una pila de cajas. Cuantas ms cajas haya en la pila, ms lento va a ser el clculo de fsicas, pero para comparar un motor con otro se debe mirar el incremento de esfuerzo computacional al incrementar el nmero de cajas. Hay que decir que el clculo de colisiones de una caja o una esfera, que se consideran objetos simples, son muy sencillos y eficientes
Tests de apilamiento.

Aun as vemos que para Newton Dynamics, este incremento en tiempo de proceso es mucho ms notorio. Los que tienen una tasa mnima de incremento de tiempo son los motores Tokamak(en especial), TrueAxis y PhysX (Novodex).

Tiempo de clculo para una pila de cajas segn el nmero que haya.

- Pgina 10 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Otra forma de comparar la calidad de clculos de un motor respecto a otro es ver la precisin, o el error (respecto al movimiento real) que tienen al calcular las fsicas. De todas formas, la precisin no es un factor que me importe mucho a la hora de escoger un motor. La figura siguiente muestra el error posicional de los clculos de cada motor respecto el caso ideal, normalizando el error con el mtodo de Euler semi-implcito (Symplectic Euler). Se construye una esfera en el centro y se deja caer con la fuerza de la gravedad (-3,8 m/s) de la escena y el tiempo se para a 0,01.

Test de error relativo de la simulacin.

El ltimo test quiere comparar los errores de penetracin entre objetos de la escena. Deja caer varias esferas (objetos simples) en una caja con forma de pirmide invertida. Se ejecuta en distintas frecuencias para cada motor. A menores frecuencias muchas bolas no llegan a tocar la caja, la atraviesan antes de llegarse a producir la colisin, mientras que a mayores frecuencias hay ms frames en que la bola puede estar tocando la pared de la caja y con ello producir una colisin. En la ejecucin a frecuencias bajas, en la mayora de los motores muchas de las bolas atraviesan la caja sin llegar a colisionar con ella. En concreto, en la ejecucin de Tokamak (el que pareca ms eficiente de entre los motores) a una frecuencia alta una bola consigue atravesar la caja. Finalmente, por la eficiencia de clculo, por tener una licencia gratuita y por la gran cantidad de funcionalidades que incorpora, me decid por usar el motor PhysX de Ageia. - Pgina 11 Test de errores penetracin.

Simulacin de efectos Fsicos

scar Llorens Maldonado

4.- PHYSX DE AGEIA


El SDK de PhysX de AGEIA une simulacin dinmica de cuerpos rgidos y deteccin de colisiones en un paquete de fcil uso. El componente dinmico de cuerpos rgidos le permite simular objetos con alto grado de realismo. Hace uso de conceptos fsicos como puntos de referencia, posicin, velocidad, aceleracin, momentos, fuerzas, movimientos rotacionales, energas, fricciones, impulsos, colisiones, uniones, etc. para proveerle de un kit de desarrollo con el que podr crear muchos tipos de dispositivos mecnicos. PhysX de AGEIA Technologies, antes conocido como NovodeX y ahora adquirido por NVIDIA, permite crear efectos fsicos en tiempo real para la simulacin en aplicaciones (bsicamente est pensada para juegos). La simulacin de movimiento de objetos en una escena con gravedad y friccin, el clculo de colisiones y la creacin de formas complejas articuladas son algunas de las funcionalidades ms importantes. Tiene una interfaz ANSI C++ implementada como una jerarqua de clases que contienen funcionalidades accesibles y clculos especficos al hardware usado (PC, PS3, Xbox360, etc.). El cdigo es cerrado, con lo que no podemos conocer la implementacin de las funciones que componen el motor. Las unidades para la masa, el tamao y el tiempo son por defecto los kilogramos, los metros y los segundos; aunque pueden ser modificados. El motor realiza clculos de valores en coma flotante de 24 bits, con lo que la precisin del motor tambin depender de que unidades hayamos escogido para trabajar. El siguiente diagrama muestra la arquitectura del motor:

- Pgina 12 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Bsicamente, tenemos una clase NxPhysicsSDK que representa el motor. Puede tener una o ms escenas que contienen actores. Estos actores pueden estar formados por varias formas que pueden ser simples como cajas, esferas, etc. o ms complejas como mallas de tringulos. Adems cada forma tendr asociado un material. Tambin podemos tener uniones de distintos tipos entre dos actores (por ejemplo la articulacin de un brazo robot). El SDK tambin incluye clases math para la creacin de vectores, matrices, operaciones entre estas y algunas funciones y macros. Tambin incluye un SDK para la gestin de personajes y otro para el cocinado de mallas (creacin de la estructura interna de una malla). Tiene algoritmos muy eficientes para algunas formas simples como cajas, esferas, cpsulas, planos, segmentos y rayos (y para comprobar las colisiones entre ellos), aunque tambin pueden crearse formas ms complejas con un pre-proceso para crear la representacin interna. Existe una tarjeta que se puede comprar a parte, comercializada por NVIDIA. La AGEIA PhysX accelerator es uno de los primeros procesadores dedicados nicamente a las fsicas, un hardware optimizado para clculos a gran escala para acelerar la interaccin y el movimiento, que libran al procesador del trabajo de realizar todos estos clculos. Las tarjetas grficas de NVIDIA empiezan a incorporar este procesador de clculo, aunque solo sirve para el motor PhysX. En siguiente apartado se trata el funcionamiento y las funcionalidades de PhysX, en especial las que he utilizado y son comunes en todas las simulaciones del proyecto.

- Pgina 13 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.- UTILIZACIN DEL MOTOR 5.1.- INICIALIZACIN Y CONFIGURACIN DEL MOTOR Y LA ESCENA
Aqu se explica cmo se ha inicializado y configurado el motor, y la creacin de una escena con ciertos parmetros. La implementacin de este apartado, puede encontrarse en la constructora de la clase
MotorFisic, en motorFisic.cpp .

5.1.1.- INICIALIZACIN DEL MOTOR


Para inicializar el motor utilizo la funcin:
NxPhysicsSDK* NxCreatePhysicsSDK (versin, gestorMemoria, canalSalida,

descriptorHardware, canalSalidaError)

De esta funcin, el primer parmetro es el ms importante: la versin del SDK de PhysX, que ser la constante NX_PHYSICS_SDK_VERSION. Los dems por defecto son nulos.

5.1.2.- CONFIGURACIN DEL MOTOR


Para configurar el motor, uso la siguiente funcin aplicada al motor creado:
setParameter(parmetro, valor)

Hay varios parmetros que se pueden configurar, entre ellos los siguientes: Grosor de la piel (NX_SKIN_WIDTH): Define cunto pueden penetrarse los objetos en el motor. El clculo de colisiones se hace mediante operaciones de interseccin entre dos objetos, por lo que un valor de 0 no est permitido como grosor de la piel ya que no podran calcularse las colisiones y eso producira una inestabilidad en la simulacin. Un valor alto provocara que objetos penetrasen parcialmente dentro de otros. Dependiendo de la escala que se usa, se deber configurar correctamente este parmetro. En mi caso he usado el valor 0,01 . Velocidad para poner los objetos a dormir (NX_DEFAULT_SLEEP_LIN_VEL_SQUARED y

NX_DEFAULT_SLEEP_ANG_VEL_SQUARED):

Podemos optimizar el clculo de las fsicas si eliminamos algn

objeto de este proceso. Podemos descartar (es decir, hacer dormir) los objetos que estn parados, o casi parados. ste parmetro define a qu velocidad se considera un objeto como apto para ponerlo a dormir y para que ya no influya en el clculo de las dems fsicas, a menos que otro objeto colisione con - Pgina 14 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

l. Es muy til cuando queremos que un objeto no rebote infinitamente, o su velocidad disminuya progresivamente hasta ser imperceptible su movimiento. Habilitar el CCD Deteccin de colisiones continua (NX_CONTINUOUS_CD): Sabemos que el clculo de colisiones se hace comprobando si un objeto est dentro de otro. Cuando tenemos objetos a mucha velocidad es posible que entre clculo y clculo, el objeto rpido atraviese un objeto por entero y no se interprete la colisin. Podemos activar el CCD para corregir este problema. Se comprueba la colisin con un volumen alargado del movimiento del objeto entre el clculo anterior y el actual.

Deteccin de colisiones contina

Visin de debug (NX_VISUALIZE_****): Habilitar la visualizacin de ejes (escena, actores, uniones), colisiones, fuerzas, velocidades, uniones, emisores, campos de fuerza, normales, etc. para debugar de forma sencilla la aplicacin.

5.1.3.- CREACIN DE LA ESCENA


Podemos tener varias escenas, con objetos que colisionen en grupos diferentes, con gravedades, fuerzas o fricciones diferentes para hacer comparaciones o para simular el paso de un entorno a otro. En mi caso solo tengo una escena inicializada mediante la funcin del motor:
NxScene* createScene(descriptorEscena)

Tenemos que pasar como parmetro un descriptor (NxSceneDesc), que podemos configurar con los siguientes parmetros:

- Pgina 15 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Gravedad (gravity): Se debe definir una gravedad para la escena como un vector. Obviamente mi inicializacin es NxVec3(0,(NxReal)-9.8,0) . Informe de contactos (userContactReport): Cuando se produzca un contacto entre dos objetos especiales, se llamar a la funcin asignada. De esta parte hablar ms en el apartado 5.6 . Lmites de la escena y planos (limits, groundPlane, boundsPlanes): la escena puede ser encerrada en un cubo, o definir un suelo directamente. Prioridades de los clculos (simThreadPriority, workerThreadPriority) Una vez creada la escena ya podremos aadir Actores, pero antes debemos redefinir (si queremos) el material por defecto que tendrn todos estos actores.

5.1.4.- MATERIAL POR DEFECTO DE LA ESCENA


Como no uso materiales distintos para los objetos, solo he configurado el material que viene por defecto. Se puede obtener mediante la funcin getMaterialFromIndex, pasandole como nmero de material el 0. Los tres campos que se deben configurarse son los siguientes: Friccin esttica (staticFriction): Valor mayor o igual a 0. Es el coeficiente de friccin que experimenta el objeto cuando est parado para empezar a moverse. Friccin dinmica (dynamicFriction): Valor mayor o igual a 0. Es el coeficiente de friccin que experimenta el objeto cuando est en movimiento. Balanceo (restitution): Valor entre 0 y 1. Cuanto mayor sea este valor, ms rebotar el objeto al colisionar con otro. Un valor muy cercano a 1 produce problemas de estabilidad y parece que el objeto gane energa cada vez que colisiona. Cuanta ms friccin esttica y dinmica tengan los objetos de la escena, ms fcil ser que stos entren en estado de dormir (si se ha activado esta opcin), con lo que ganaremos rendimiento en el clculo de fsicas. En mi caso, he asignado un valor de 0,5 a los tres parmetros, es decir un material que rebota poco y tiene poca friccin esttica y dinmica.

- Pgina 16 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.2.- ALGUNAS FUNCIONES TILES ASOCIADAS A LA ESCENA


Aparte de las funciones asociadas al bucle de ejecucin del programa, que llamarn a la escena para que calcule y actualice las nuevas posiciones de los objetos (de esto hablar en el apartado siguiente), hay varias funciones que se deben mencionar por su importancia y el uso que he hecho en la implementacin: Crear un actor (createActor): Funcin que declara un nuevo objeto (actor) en la escena, pasando como parmetro un descriptor. Los actores van desde formas simples como cubos, esferas o pldoras a objetos ms complejos como actores formadas por varias formas, objetos convexos o mapas de altura (Heightfields). En el apartado 5.4 hablar en profundidad de cmo crear estos actores. Eliminar un actor (releaseActor): Funcin que elimina un actor de la escena. Es necesario eliminar el actor usando esta funcin y no solo liberando la memoria, ya que sino el actor seguira estando en la escena. Crear una unin (createJoint): Al igual que para crear un actor, a esta funcin se le pasa un descriptor. Se define una unin entre dos actores, muy til para definir desde las bisagras de una puerta hasta la suspensin de un coche, brazos mecnicos, el esqueleto de un modelo, etc. Hay muchos tipos de uniones: de X grados de libertad, cilndricas, prismticas, esfricas, de punto a plano, etc. Adems se les pueden asignar efectos elsticos, motrices, de rotura de uniones o que suavicen el movimiento de los actores asociados. De todo esto hablar en el apartado 5.7 . Eliminar una unin (releaseJoint): Anlogo a eliminar un actor. Crear/eliminar un campo de fuerza (createForceField, releaseForceField): Es posible crear campos de atraccin o repulsin hacia ciertos objetos. En la implementacin del proyecto no he usado ningn campo de fuerza. Crear/eliminar un nuevo material (createMaterial, releaseMaterial): Ya he dicho que se pueden aplicar distintos materiales a los objetos de la escena, incluso a partes de estos objetos; aunque en mi caso slo he usado un material para todos los actores. Crear un efecto en una pareja de actores (setActorPairFlags): A esta funcin se le pasan tres parmetros: dos actores y un efecto. Cuando se produzca este efecto entre los dos actores, se llamar a una funcin que deberemos haber definido en el campo userContactReport de la clase Scene. Por ejemplo: podemos definir que cuando dos actores entren en contacto, se lleven a cabo una serie de acciones sobre stos. A esta parte le dedicar el apartado 5.7 .

- Pgina 17 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Establecer si habr colisin entre dos grupos de objetos (setGroupCollisionFlag): Se pueden crear dos grupos distintos de objetos y definir que no habr colisin entre ellos (pero s entre los integrantes de cada grupo). Adems, el motor lleva ya predefinidas algunas funciones para crear efectos fsicos de gran escala como los siguientes: Crear un fluido (createFluid): Implementacin para la creacin de un fluido como un conjunto de partculas. Tambin proporciona un ejemplo de generacin de una malla para la visualizacin de este fluido a partir de las partculas. La simulacin y representacin de fluidos conlleva hacer clculos muy costosos y solo est pensado para ejecutarse en la tarjeta que vende PhysX. Crear ropa (createCloth): Tambin es posible crear ropa directamente, aunque yo tambin he implementado la simulacin de ropa, tal vez de forma distinta. Crear un objeto de tela (softBody): No le veo mucha utilidad fuera del mbito promocional, pero tambin se pueden crear objetos que estn hechos de ropa. Se les aplica una presin interna (como si se estuvieran continuamente inflando desde dentro), con lo que se pueden deformar por una colisin y volver a su forma original. Estas funciones, al no ser cdigo abierto, no puede verse su implementacin, y si queremos generar una variacin de ellas, no hay forma de saber cmo han sido implementadas.

- Pgina 18 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.3.- BUCLE DE EJECUCIN


La implementacin del bucle de ejecucin del programa depender de en qu momento queremos calcular las fsicas, y de qu queremos estar haciendo mientras stas se calculan. En este sentido la opcin ms recomendable es la de dibujar la escena por pantalla mientras se actualizan los actores de la escena fsica. Antes, comentar qu funciones ofrece el motor fsico para ejecutar el clculo de colisiones: Especificar el incremento de tiempo (simulate): Aunque por el nombre de la funcin, parece que empezamos a ejecutar el clculo de fsicas pasndole el incremento de tiempo desde el inicio de la anterior ejecucin, esta funcin es solo para especificar el incremento de tiempo. Empezar el clculo (flushStream): Ejecuta la simulacin en un proceso a parte (o varios). Esperar los resultados (fetchResults): Esta funcin devuelve cierto si la simulacin ha acabado y falso en caso contrario. Tiene dos parmetros: al primero se asigna la constante NX_RIGID_BODY_FINISHED (para preguntar si han acabado los clculos de los objetos rgidos) y el segundo es otro booleano que indica si esta llamada va a ser bloqueante o no: si queremos que la funcin retorne cuando haya acabado el clculo de fsicas o solo queremos preguntar si ha acabado. Se necesita tambin un reloj que calcule cunto tiempo ha pasado entre clculo y clculo. Cada vez que llamemos a la funcin que inicia el clculo de fsicas, debemos decirle cunto tiempo ha pasado desde que la llamamos por ltima vez. As nos aseguramos de que el reloj del motor fsico est sincronizado con el real. Si se quiere obtener la animacin de los objetos para almacenarla, se puede capturar su posicin y orientacin en intervalos de tiempo constante. Entonces se ha de pasar como parmetro a la funcin
simulate el valor de este intervalo.

Tambin debemos tener en cuenta que mientras se estn procesando las fsicas, no se puede modificar ningn parmetro del motor ni de la escena. Esto incluye aadir/modificar fuerzas a un actor, crear/eliminar actores, cambiar el estado de un actor, etc. Estas modificaciones deberemos hacerlas despus de acabar el proceso de fsicas y antes de iniciar el siguiente. En resumen, tambin tenemos las siguientes funciones que querremos ejecutar en el bucle del programa: Pintar la escena: Se puede pintar la escena en cualquier momento, aunque se estn procesando las fsicas, ya que el motor permite acceder a los actores, velocidades, posiciones, mallas, etc. del ltimo clculo.

- Pgina 19 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Procesar la entrada del teclado: Si conlleva modificar la escena fsica, deberemos hacerlo despus de acabar el clculo de fsicas y antes de volver a empezarlo; si no, podemos procesar la entrada de teclado en cualquier momento, aunque es preferible hacerlo siempre antes de volver a pintar la escena. Actualizar la escena: Ya he comentado que debe hacerse despus de acabar el clculo de fsicas y antes de empezar el siguiente. Teniendo en cuenta todos estos factores, un posible bucle de ejecucin podra ser el siguiente: OPCIN 1:
mientras no salir hacer fetch_results(NX_RIGID_BODY_FINISHED,true); procesar_entrada(); actualizar_escena(); simulate(incremento_tiempo); flushStream(); pintar_escena(); fmientras

En este caso, es posible que no importe si procesamos la entrada antes de actualizar la escena. Pintamos la escena tras empezar la ejecucin del clculo de fsicas y despus esperamos a que acabe para volver a procesar la entrada. Si tenemos otro proceso que queremos ejecutar mientras el motor fsico acaba los clculos, un bucle de ejecucin podra ser el siguiente: OPCIN 2:
mientras no salir hacer mientras fetch_results(NX_RIGID_BODY_FINISHED,false) hacer clculos_alternativos(); fmientras procesar_entrada(); actualizar_escena(); simulate(incremento_tiempo); flushStream(); pintar_escena(); fmientras

En la primera opcin del bucle, al llamar a la funcin fetch_results en modo bloqueante, el clculo de fsicas se ejecuta el mismo nmero de veces que se pinta la escena, por lo que una ralentizacin en el procesado del motor se muestra en los frames por segundo de la visualizacin de la simulacin. Quizs esto no es deseable y queremos que se vaya pintando la escena mientras se van calculando las fsicas. Para ello solo debemos ejecutar la funcin fetch_results en modo no bloqueante y mientras devuelva falso pintar la escena:

- Pgina 20 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

OPCIN 3:
mientras no salir hacer mientras fetch_results(NX_RIGID_BODY_FINISHED,false) hacer pintar_escena(); fmientras procesar_entrada(); actualizar_escena(); simulate(incremento_tiempo); flushStream(); fmientras

Si la funcin procesar_entrada no modifica ningn atributo de la escena del motor fsico, tambin puede ejecutarse dentro del bucle de fetch_results. Con este bucle de ejecucin, la ralentizacin del motor por el numero de clculos que debe hacer no influye (o casi) en el nmero de imgenes por segundo que se visualiza la escena por pantalla. Si se produce este efecto de forma exagerada, podemos movernos por la escena con un alto nmero de fps pero vemos que los objetos de la escena se mueven a saltos. Si los clculos de la funcin pintar_escena son complejos no es deseable usar este bucle de ejecucin, ya que tambin influira negativamente en el tiempo de clculo de fsicas, por lo que yo he optado por usar el primer bucle que he presentado. Cabe recalcar que realizo clculos costosos al pintar la escena, como generar mallas y calcular normales.

- Pgina 21 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.4.- CREACIN DE ACTORES


Un actor es un objeto de simulacin que existe solamente en una escena del motor fsico. Hay varios tipos de actores predefinidos por el motor, y cada uno tiene propiedades y algoritmos de clculos de colisiones diferentes. No es lo mismo calcular la colisin entre dos esferas que entre dos cubos, y mucho menos calcularla entre dos objetos convexos cualesquiera. Podramos crear nuevos tipos de actores pero los que proporciona el motor son suficientes, al menos para las simulaciones que he hecho. Cada actor interacta con el entorno de forma distinta, dependiendo de qu tipo de actor es (esttico, dinmico), de las fuerzas que se le aplican, de las colisiones a las que se ve sometido, de las uniones a otros objetos a las que est asignado, etc. En cada ejecucin de clculo de fsicas, el motor deber calcular la nueva posicin y orientacin del actor teniendo en cuenta todos estos factores, y adems actualizar todos los valores vectoriales y escalares que le definen (como la velocidad lineal y angular, la aceleracin, la fuerza aplicada a una unin, etc.) para la siguiente actualizacin. Para definir un actor, primero hemos de definir un descriptor de actor, llamado NxActorDesc que tendr una forma espacial.

5.4.1.- DESCRIBIR LA FORMA DEL ACTOR


La forma de un actor puede contener varias partes (ya que hay objetos formados por varias piezas de formas simples o complejas unidas), por lo que deberemos definir cada una de estas partes con otro descriptor. El motor proporciona varios descriptores de formas simples cuyos parmetros variarn en funcin del objeto que se est creando. Algunos de estos descriptores son los siguientes:

Algunas formas bsicas

Descriptor de planos (NxPlaneShapeDesc): Para crear planos que limiten la escena, para definir de forma fcil el suelo o las paredes. Para definirlo debemos asignarle la normal(nx,ny,nz) del plano y la distancia d al origen de coordenadas, segn la funcin del plano xnx+yny+znz=d.

- Pgina 22 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Descriptor de esferas (NxSphereShapeDesc): Se puede definir un objeto con forma de esfera mediante la
posicin(x,y,z) del centro de la esfera y un radio r.

Descriptor de cajas (NxBoxShapeDesc): Debemos definir las tres longitudes (ancho,


largo, alto) y la posicin(x,y,z) que corresponder a la del centro de la caja.

Descriptor de cpsulas (NxCapsuleShapeDesc): Las cpsulas pueden definirse con la


posicin(x,y,z)

del centro, la altura de la zona cilndrica y el radio de las semiesferas


Cpsula

de los extremos. Todas las unidades longitudinales del motor son expresadas en metros.

Estos descriptores contienen funciones especficas para cada forma, de manera que el clculo de posicin y colisiones es mucho ms eficiente. Tambin tenemos descriptores para formas ms complejas como: Descriptor de malla de tringulos (NxTriangleMeshShapeDesc): Se pueden definir mallas de tringulos que actuarn como objetos estticos en la escena, es decir que solo influirn en el clculo de colisiones. Descriptor de objetos convexos (NxConvexShapeDesc): A este tipo de objetos le dedicar el apartado 5.5 . Para crear una forma convexa como actor, deberemos definir cada cara de la forma mediante tringulos y vrtices. Aun se deber hacer un paso ms antes de poder crear la forma y es la de generar la malla de tringulos interna al motor, con la operacin que denominan cook. Hay que decir que el clculo de colisiones para una forma convexa, aunque sea el ms ptimo posible, es ms costoso que el de otras formas simples como la caja o la esfera. Para que no se produzcan errores es necesario que la malla sea cerrada, convexa y regular. Descriptor de mapas de alturas (NxHeightFieldShapeDesc): No lo he usado, pero se pueden definir de la misma forma que una malla de triangulos. Cada uno de estos descriptores se debe apilar en la pila de formas del actor, mediante la funcin pushBack del campo shapes del descriptor del actor NxActorDesc. Al crear el actor, el motor crear una estructura jerrquica de las formas que componen ese actor. He podido comprobar que no parece haber ningn problema si algunas de estas formas se solapan entre s.

- Pgina 23 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.4.2.- POSICIN LOCAL/GLOBAL


El actor tendr definida la posicin que se encuentra de la escena (posicin global). Adems, para los objetos con varias partes, se debe definir una posicin local para cada una de ellas. Por ejemplo, para crear la forma de la siguiente mesa, deberemos definir cinco cajas con parmetros distintos, con la misma posicin global pero distinta posicin local.

Creacin de una mesa definiendo posiciones locales distintas para cada pata.

5.4.3.- PESO
Se pueden definir objetos estticos y dinmicos en la escena. Los actores dinmicos colisionaran con otros actores y se les aplicarn fuerzas, mientras que los estticos son objetos con peso infinito a los que no les afecta ninguna colisin ni fuerza aplicada. Para un actor, adems de definir la forma, se puede definir el cuerpo con la clase NxBodyDesc. Si un actor no tiene cuerpo, se considerar un objeto esttico. Para crear un objeto dinmico, se debe crear un cuerpo, asignrselo al actor y modificar el campo density con el peso de todo el objeto. El cuerpo del actor se puede configurar inicialmente con una velocidad (lineal o angular) o con varios parmetros para precisar cundo ese objeto se puede poner en estado dormido. Tambin se puede definir un actor esttico que tenga cuerpo pero el peso sea igual a cero.

- Pgina 24 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.4.4.- CENTRO DE MASAS


Por defecto, el centro de masas de un objeto se encuentra en la posicin global de la escena que se ha definido para ese objeto. Es decir, para la esfera situada en el punto P con radio R, el centro de masas se encontrara en el mismo punto P ya que el descriptor de la esfera se crea en la posicin global del objeto ms la posicin local L de la forma, y la esfera tiene como centro L. Si por ejemplo, se quiere definir una esfera con el centro de masas en el extremo inferior, se deber definir en la posicin global P, con radio R y L=(0,R,0).

Modificacin de la posicin local para cambiar el centro de masas

En el caso de la mesa del apartado 5.4.2, el centro de masas est situado en el suelo, es decir la posicin global del objeto. Si queremos situar su centro de masas en otro punto, deberemos modificar la posicin local de todos los objetos. Si no queremos que la posicin global sea el centro de masas, tambin se puede modificar el atributo
massLocalPose del descriptor del cuerpo NxBodyDesc.

5.4.5.- CREACIN DEL ACTOR


Tras ver todo lo que hay que definir para crear un actor, los pasos que hay que seguir son los siguientes:
crear descriptor del actor NxActorDesc; para cada forma que se quiera crear hacer Crear el descriptor de la forma NxSphereShapeDesc, NxBoxShapeDesc, NxConvexShapeDesc, etc. ; descriptorActor.shapes.pushBack(&descriptorForma);

fpara si es dinmico hacer Crear descriptor del cuerpo NxBodyDesc y configuarlo; descriptorActor.body=descriptorActor; fsi
asignar la posicin global del actor a descriptorActor.globalPose; escena->createActor(descriptorActor);

- Pgina 25 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

A la funcin createActor de la escena NxScene se le pasa el descriptor del actor y devuelve 0 si no lo ha podido crear por alguna incoherencia en el descriptor, o un puntero al actor si ha podido hacerlo. Hay que tener en cuenta que esta funcin solo es posible ejecutarla si el motor no est realizando ningn clculo de fsicas, y tras ejecutarla, en el siguiente inicio de la simulacin, el actor ya estar en la escena. En el archivo del proyecto motorFisic.cpp hay definidas varias funciones de creacin de actores de distintas formas.

5.4.6.- FUNCIONES ASOCIADAS A UN ACTOR


Algunas funciones interesantes que ofrece la clase NxActor para modificar varios parmetros del actor cuando el motor no est realizando ningn clculo de fsicas, son las siguientes: Asignarle un grupo (setGroup, getGropu): Se pueden crear grupos de actores y, por ejemplo, hacer que solo colisionen entre ellos los actores de un mismo grupo, o ejecutar una funcin cuando un grupo atraviesa un plano, etc. Modificar un flag del actor (raiseActorFlag, clearActorFlag): Hay flags para desactivar la colisin con otros objetos de ese actor (NX_AF_DISABLE_COLLISION) o cambiar la rutina que se llama al colisionar (NX_AF_CONTACT_MODIFICATION), entre otros. Modificar un flag del cuerpo (raiseBodyFlag, clearBodyFlag): Flags para desactivar la influencia de la gravedad en el actor(NX_BF_DISABLE_GRAVITY), para impedir que se mueva o rote hacia algn eje en concreto (NX_BF_FROZEN_POS_# , NX_BF_FROZEN_ROT_#, con #=X,Y o Z) o en todos los ejes (NX_BF_FROZEN_POS , NX_BF_FROZEN_ROT), entre otros. Cambiar/Obtener la posicin global (setGlobalPosition, getGlobalPosition): El parmetro o

resultado de estas funciones es un vector(x,y,z) de tipo NxVec3 correspondiente a la nueva o actual posicin del actor. Cambiar/Obtener la orientacin del actor (setGlobalOrientation, getGlobalOrientation): El parmetro o resultado de estas funciones es una matriz 3x3 de tipo NxMat33 correspondiente al producto de las tres matrices de rotacin en los ejes X, Y y Z. Mover el actor de forma kinemtica (moveGlobalPosition, moveGlobalOrientation): Cuando un actor se mueve de forma kinemtica, colisiona con los dems objetos pero estos no influyen en su trayectoria, como un objeto esttico con peso infinito. Se debern llamar a estas funciones antes de empezar el clculo de fsicas en cada actualizacin de la escena para que la animacin resulte fluida. - Pgina 26 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Crear/eliminar nuevas partes para el actor (createShape, releaseShape): Entre clculo y clculo an es posible crear o eliminar partes del actor. Operaciones con la masa del objeto (setCMassGlobalPose, updateMassFromShapes, etc...): Existen varias operaciones para modificar la masa, la inercia, la posicin local del centro de masas, etc., y para consultarlas. Modificar la velocidad (setLinearVelocity, setAngularVelocity, setMaxAngularVelocity): Para modificar la velocidad lineal o angular para el siguiente clculo de fsicas. Tambin es posible especificar una velocidad mxima para el actor. Modificar el momento del objeto (setLinearMomentum, setAngularMomentum): El momento lineal es el producto de la masa por la velocidad, y el momento angular es el producto vectorial momento lineal por el vector de posicin. Cuando dos actores colisionan, si el primero tiene un momento mucho mayor, ste arrollar al segundo. Aplicar una fuerza (addForce, addLocalForce, addTorque, addLocalTorque, etc): Hay dos tipos de fuerzas dependiendo de si queremos aplicar una fuerza en un instante (algo parecido a dar un golpe al objeto) o queremos que el objeto se vea sometido a una fuerza constante (como ir empujando el objeto). La funcin addForce aplica una fuerza instantnea a calcular en el siguiente proceso de fsicas mientras que addTorque aplica una fuerza continua que deber ser aplicada antes de cada clculo de fsicas. Si por error usaremos addForce en cada ejecucin del bucle del programa veramos que el objeto va ganando velocidad de forma cuadrtica. Estas funciones aplican la fuerza sobre el centro de masas, pero tambin es posible hacerlo sobre un punto en concreto del actor con funciones como
addForceAtPos.

Operaciones para dormir el actor (putToSleep, wakeUp, setSleepLinearVelocity, etc): Es necesario que los actores puedan dormirse (dejar de moverse y de colisionar entre ellos) si no hay friccin en la escena o hay muchos actores, ya que sino el objeto estara movindose infinitamente aunque fuera cada vez a menor velocidad.

5.4.7.- PINTAR EL ACTOR EN LA ESCENA


Es posible que queramos pintar la misma malla que tenemos definida en el actor, pero en la mayora de casos tendremos una malla ms compleja que corresponder al objeto que se debe representar en la escena y otra ms simplificada para el clculo de fsicas.

- Pgina 27 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

En la clase NxActor tenemos un campo llamado UserData que es un puntero para poner la informacin que queramos, como por ejemplo la malla a representar. Sin embargo yo no he usado este campo para guardar esta informacin porque lo necesitaba para otros datos. Pero antes de dibujar el objeto se debe posicionar en la escena. Para ello el motor nos da tres funciones:
getGlobalPosition, getGlobalPosition NxMat34 respectivamente.

y getGlobalPose que devuelven un NxVec3, una NxMat33 y una

Matriz de Transformacin 3D

El motor, tras cada clculo de fsicas, modificar los valores de la matriz de transformacin asociada al objeto. La funcin getGlobalPosition nos devuelve la posicin (x,y,z) global del actor mientras que la funcin getGlobalOrientation nos devuelve la matriz 3x3 de las tres rotaciones del actor. Finalmente, la funcin getGlobalPose nos devuelve la matriz de transformacin sin la ltima lnea. En cuanto a las funciones de OpenGL, tenemos la funcin void glMultMatrixf(const GLfloat *m) que debemos pasarle un puntero a la matriz de transformacin 4x4. Esta funcin sustituye la actual matriz de transformacin (ModelView) por el producto de sta con la que pasamos como parmetro. Entonces posicionar el actor en la escena, es tan simple como crear una matriz 4x4 con la matriz 3x3 obtenida de la llamada a getGlobalPose, aadirle una ltima fila con [0,0,0,1] y pasar esta matriz como parmetro a glMultMatrix. Finalmente, la funcin para representar un actor es la siguiente:
glPushMatrix(); matrix3x4 = getGlobalPose(); matriz4x4 = crearMatriz(matrix3x3 + [0,0,0,1]); glMultMatrix(matriz4x4); dibujarActor(); glPopMatrix();

- Pgina 28 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Si un objeto est formado por varias formas de diferentes tipos, debemos obtener el nmero de formas y dibujar cada una con las instrucciones anteriores. Cada forma NxShape contiene informacin sobre su posicin y orientacin global, adems del tipo de forma (funcin getType). Otra forma para posicionar el objeto sera la de multiplicar la matriz ModelView con la matriz de transformacin global del Actor y, para cada parte, volver a multiplicarla por la matriz de transformacin local de esa parte.

Cada caja es pintada con el algoritmo anterior.

- Pgina 29 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.5.- CREACIN DE CUERPOS RGIDOS CONVEXOS


En muchos casos se quiere crear un objeto que ni sea una forma simple ni est formado por formas simples, es decir una malla de tringulos aleatorios. Para ello el motor nos da una serie de funciones para crear actores slidos rgidos convexos. Hay que tener en cuenta que la malla del objeto que se quiere crear ha de ser convexa, cerrada y regular, sin embargo he comprobado que eso no es una condicin para que se cree el actor en la escena. S que es una condicin para que no haya ningn tipo de error ni comportamiento irregular. Estos actores se crearn de la misma manera que el resto: crearemos el descriptor de un actor y para este uno o ms descriptores de partes (shapes). Si una de estas partes tiene que ser un objeto convexo, crearemos un descriptor del tipo NxConvexMeshDesc. Para poder crear el objeto se tiene que rellenar el campo meshData de tipo NxConvexMesh. La informacin que he usado para crear la malla es: una tabla de vrtices(x,y,z) y una tabla de caras (tringulos) que sern grupos de tres ndices a la tabla de vrtices. Por tanto primero se tiene que crear un NxConvexMesh y para ello vamos a usar otro descriptor NxConvexMeshDesc en el que hay que rellenar los siguientes campos: numVertices: Nmero de vertices de la malla numTriangles: Nmero de tringulos de la malla pointStrideBytes: Tamao en memoria entre cada uno de los vrtices de la tabla de vrtices, en mi caso sizeof(NxVec3) . triangleStrideBytes: Tamao en memoria entre la informacin de cada una de las caras en la tabla de caras. Como usar caras triangulares y la topologa s la de un ndice entero (NxU32) a la tabla de vrtices para cada vrtice del tringulo, este tamao ser 3*sizeof(NxU32) . points: Puntero a la tabla de vrtices. triangles: Puntero a la tabla de caras. flags: Le asigno la constante NX_CF_COMPUTE_CONVEX. Con el descriptor configurado, ya se pueden usar una serie de funciones para crear la malla: primero deberemos cocinar(cook) la malla con la funcin NxCookConvexMesh. Esta funcin que devuelve un booleano tiene como parmetro, aparte del descriptor de la malla, un puntero a un buffer de escritura de datos MemoryWriteBuffer que luego se usa para crear finalmente la malla. La funcin de cocinar crea una estructura de datos que permite al SDK ejecutar clculos de fsicas ms eficientes. - Pgina 30 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Finalmente para crear el objeto NxConvexMesh, slo hay que llamar a la funcin createConvexMesh del motor pasando como parmetro un buffer de lectura MemoryReadBuffer de los datos resultado del cocinado. El resto instrucciones para acabar la creacin del actor es anlogo a los dems tipos de formas. El algoritmo de todo el proceso es el siguiente:
*vrtices = obtener_vertices_objeto(); *caras =obtener_caras_objeto(); crear descriptor de malla NxConvexMeshDesc; descriptorMalla.numVertices = numeroVertices; descriptorMalla.numTriangles = numeroTriangulos; descriptorMalla.pointStrideBytes = tamao(NxVec3); descriptorMalla.triangleStrideBytes = 3*tamao(NxU32); descriptorMalla.points = vrtices; descriptorMalla.triangles = caras; descriptorMalla.flags = NX_CF_COMPUTE_CONVEX; NxInitCooking(); // necesario para iniciar el cocinador de mallas crear buffer de escritura MemoryWriteBuffer; NxCookConvexMesh(descriptorMalla, fufferEscritura); Crear el descriptor de la forma NxConvexShapeDesc; descriptorForma.meshData = motorFisico-> createConvexMesh(MemoryReadBuffer(bufferEscritura.data)); crear descriptor del actor NxActorDesc; descriptorActor.shapes.push_back(descriptorForma); ... // acabar de crear el actor como los dems

Este cocinado solo admite objetos convexos, cerrados y regulares. De todas formas, si pasamos un objeto no cerrado o no regular el algoritmo se ejecuta y se crea el actor, que obviamente no opondr resistencia en cuanto a colisiones en la zona abierta del objeto. En cuanto a formas cncavas, si se quiere que no haya ningn tipo de error en la simulacin, se debe dividir el objeto cncavo en objetos convexos y cocinarlos por separado para crear finalmente un actor con varias formas. Este ltimo paso para objetos cncavos no lo he implementado ya que he visto que los objetos resultantes no provocan errores muy graves en la simulacin. Es posible que el cocinado cree la envolvente convexa al encontrar un vrtice cncavo, o tal vez lo elimine; observando la simulacin es difcil de saberlo.

- Pgina 31 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.6.- USER REPORTS


En algunos casos querremos que se ejecute un proceso al colisionar dos objetos. Para ello necesitamos un herramienta que nos informe de qu colisiones ha habido en el clculo de fsicas para poder procesar dichas colisiones antes de la siguiente ejecucin. PhysX tiene un conjunto de funciones llamadas User Reports. En este apartado explicar el uso que le he dado a estas funciones para a procesar colisiones de actores diferentes en algunas de las simulaciones que he hecho para el proyecto. Primero se debe activar el informe de colisiones al crear una escena en el motor. Se asigna en el campo
userContactReport

de NxSceneDesc la direccin de la funcin a la que se llamar al procesar un contacto

entre dos actores en el clculo de fsicas. Esta funcin debe heredar de NxUserContactReport y ha de contener la siguiente funcin pblica:
void onContactNotify (parejaActores, evento)

El parmetro evento hace referencia a uno de los tres tipos de eventos que puede existir en la colisin de dos actores:
NX_NOTIFY_ON_START_TOUCH: Se ha disparado el evento al entrar en contacto los dos actores NX_NOTIFY_ON_END_TOUCH: Los dos actores han dejado de estar en contacto. NX_NOTIFY_ON_TOUCH: Los dos actores siguen estando en contacto en ese clculo de fsicas.

El primer parmetro parejaActores contiene los dos actores asociados a ese evento. El informe de colisin entre dos actores solo se disparar si se ha definido un evento para esa pareja de actores en la escena, que se hace mediante la funcin de NxScene:
void setActorPairFlags (actor1, actor2, evento)

Una desventaja de definir de esta forma la colisin entre parejas de actores es que si queremos procesar la colisin de X actores con ellos mismos, tendremos que definir (X-1)+(X-2)+...+2+1 parejas. Tambin existe la misma funcin pero para actores de diferentes grupos, pasando como parmetros los dos grupos que deben llamar a la funcin de userContactReport si colisionan entre s. El procesado de una pareja de actores que han colisionado, no es tan fcil como esperaba aunque s se puede obtener la informacin necesaria, como por ejemplo el punto de colisin, y poder acceder a los dos actores para acceder a la velocidad que llevaba cada uno.

- Pgina 32 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

En mi caso, y simplificando, tendr una clase que tendr asociada un actor NxActor. A la funcin de contacto llegarn precisamente los actores del motor, por lo que yo debo saber a qu clase pertenecen. La mejor opcin es usar el campo UserData de NxActor para guardar un puntero a la clase a la que pertenece. Adems, como voy a procesar algunos actores de forma distinta a otros, deber aadir un campo en
UserData que contendr el tipo de actor.

Cuando se elimina un actor del motor, la informacin asociada a qu debe hacerse si entra en contacto con las parejas a las que est asociada, tambin queda eliminada. Hay otros tipos de User Reports, el de contactos es solo uno de ellos. Tambin tenemos varios elementos de visin de debug del motor fsico (como direcciones y magnitudes de velocidad, fuerza, etc.), disparadores que ejecutan una rutina cuando un actor entra en una zona definida en la escena, punto de interseccin con algn objeto de un rayo trazado a travs de la escena (RayCast), otros tests de interseccin y un debugador visual para monitorizar en una aplicacin aparte la ejecucin del SDK.

- Pgina 33 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

5.7.- UNIONES ENTRE ACTORES


Para crear un brazo robtico, un personaje o cualquier otro mecanismo articulado es necesario definir uniones entre los diferentes componentes. El proceso para crear una unin es el mismo que el de los actores: crear un descriptor con los parmetros de configuracin (incluyendo los dos actores sometidos a la unin) y declararlo en la escena usando la funcin
createJoint.

Las uniones que nos proporciona el motor son las siguientes:


NxRevoluteJoint:

Define una unin de dos actores por un

punto y con un grado de libertad. Se debe definir el eje de rotacin (globalAxis, vector perpendicular al plano en que rotaran los actores) y el punto de unin (globalAnchor). Es til para crear articulaciones, brazos robot, bisagras, etc.
NxSphericalJoint:

Unin por un punto con un grado de libertad. El eje es perpendicular al papel.

Unin esfrica entre dos actores por un punto. Tiene tres grados de libertad: puede

rotar sobre los tres ejes, por lo que tambin puede girar sobre s mismo. Es necesario definir la posicin y un eje global. Se pueden crear articulaciones como la del brazo con el hombro.
NxPrismaticJoint:

Es una unin traslacional: un actor puede

moverse a travs de otro por una recta definida por un punto y un vector director.
NxCylindricalJoint: Igual que la prismtica pero tambin permite

Unin prismtica a travs de una recta.

rotacin en el eje del vector director de la recta.


NxPointOnLineJoint:

Unin que permite que un

punto de un actor pueda desplazarse por una lnea definida en otro actor, para simular algo parecido a una cortina con rieles. Es necesario definir el punto por el que estarn unidos y el vector de la recta (situando el actor en la posicin correcta).
Unin punto-lnea.
NxPointInPlaneJoint: Igual que la anterior pero esta vez el punto definido de un actor, se puede mover

por todo un plano del otro actor. Se define un punto del plano y su normal, y se coloca correctamente el actor. - Pgina 34 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

NxPulleyJoint:

Sirve para simular una polea, o una rueda que

tiene una

cuerda con un actor colgando de cada lado. Se

definen los dos puntos en que estarn colgando los actores y la longitud de la cuerda.

NxDistanceJoint:

Establece que entre dos actores haya


Unin polea. La cuerda se debe representar de alguna forma a parte.

siempre una distancia. Se definen los dos puntos, un vector que une los dos puntos y la distancia que debe haber.
NxSpringAndDamperEffector:

Unin de tipo muelle. Es como la anterior, que define una distancia entre

dos actores pero si se modifica esta distancia, se aplicarn fuerzas para volver a la original, por lo que se deben definir estas fuerzas en lo que llaman Spring y Damper, que hablar a continuacin.
Nx6DFJoint: Unin con 6 grados de libertad, es decir, los tres de rotacin y los tres de traslacin. Si no se

ponen lmites, es como si no hubiera ninguna unin entre los dos actores, por lo que es necesario establecer lmites de valor y/o plano en la rotacin y/o translacin. La mayora de estas uniones pueden ser configuradas a partir de unos parmetros, que tienen nombres distintos segn el tipo de unin. En general, se pueden especificar: Valores lmite : Un valor lmite para un eje de rotacin (en radianes) o translacin (en unidades del motor). Por ejemplo, se deber definir un lmite inferior de rotacin y otro de superior para la articulacin de un codo (que ser de tipo NxRevoluteJoint), para permitir que solo rote los aproximadamente 180 grados que puede.
El eje del actor de debajo (lila) solo puede rotar entre los dos ngulos lmites (en rojo) del eje de rotacin de la unin.

Planos lmite : En este caso es un plano que limita la rotacin o la traslacin. El punto global definido al crear la unin (globalAnchor) no podr atravesar este plano lmite. Springs : A veces se quiere que las uniones hagan fuerza a partir de un cierto umbral. Por ejemplo, que a partir de un cierto radio de rotacin, se deba aplicar ms fuerza para seguir rotando sobre ese eje. En la unin NxSpringAndDamperEffector es necesario definir las fuerzas de estiramiento y contraccin para poder crear la unin en la escena, en las dems es opcional pero se pueden asignar estos efectos a cualquier grado de libertad que tenga la unin. - Pgina 35 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Dampers : A veces, aunque sea necesario aplicar una fuerza al objeto (por un efecto de Spring o por una colisin) la velocidad de los actores asociados a la unin es muy grande. Se puede limitar esta velocidad aadiendo fuerzas contrarias para frenar o suavizar el movimiento del actor. Motores : Hace fuerza continuamente de translacin o de rotacin en un eje. Rotura : A veces queremos romper una unin para simular, por ejemplo, que un impacto produce una fuerza capaz de sacar una puerta de sus bisagras. Aunque esto tambin puede hacerse consultando la fuerza de impacto y eliminando la unin de la escena con releaseJoint en caso necesario, se puede hacer automticamente si se define una fuerza lmite que puede soportar la unin. Cuando se alcance la fuerza lmite, se eliminar la unin entre los dos actores. Tal vez se quiera que los dos actores no colisionen entre s y solo limitar los movimientos mediante la configuracin de valores i planos lmite de las uniones. Para ello hay que asignar el siguiente flag:
descriptorUnion.jointFlags |= NX_JF_COLLISION_DISABLED;

Para la creacin de personajes, el motor tiene una serie de clases para hacer ms fcil la definicin de las articulaciones, aunque tambin puede hacerse usando las mencionadas.

Ragdoll

- Pgina 36 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.- SIMULACIN DE EFECTOS FSICOS 6.1.- GENERACIN DE HUMO 6.1.1.- OBJETIVO


El objetivo es implementar un generador que cree una columna de humo. Si algn objeto pasa por encima, el humo se ha de apartar y pasar por los lados.

6.1.2.- IDEA
La idea es generar partculas esfricas que representen Actores en la escena. A estas partculas se les asociar una aceleracin vertical hacia arriba y una velocidad hacia una direccin aleatoria. Gracias a la aleatoriedad de esta velocidad, cada partcula tomar direcciones un poco distintas y har el efecto de una columna de humo. Adems, como las partculas actuaran como actores esfricos, si chocan contra un objeto que est por encima de ellos, se apartarn hacia los lados para seguir subiendo.

6.1.3.- HERRAMIENTAS USADAS


Cada partcula de humo ser un actor esfrico, por lo que usar la forma simple NxSphereShape. El actor tiene funciones para asignar una velocidad inicial (setLinearVelocity) y modificar la aceleracin en cada clculo de fsicas (usar la funcin addForce, con Fuerza=masaaceleracin). Tambin, como quiero que las partculas de humo no choquen entre ellas, hay que desactivar la colisin. La forma ms fcil para hacerlo es asignar todas las partculas al mismo grupo al crear el descriptor (descriptorParticula.group=grupo) y desactivar la colisin entre los miembros de ese grupo con la funcin setGroupCollisionFlag(grupo1, grupo2, false) pasando como parmetros el mismo grupo.

6.1.4.- IMPLEMENTACIN
Los valores que se podrn configurar en la simulacin sern los siguientes:
ESCALAR_VELOCIDAD_INICIO:

Valor escalar de la velocidad inicial con el que multiplicaremos el

vector aleatorio de la direccin que tomar la partcula.


FUERZA_ACELERACIN: Fuerza con que subirn las partculas. RADIO_MXIMO: Radio mximo que puede tener una partcula y si se sobrepasa, se eliminar. TIEMPO_ENTRE_PARTCULAS: Tiempo que debe pasar entre la creacin de dos partculas.

- Pgina 37 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Para crear las partculas de humo he creado una clase ParticulaFum en emisorFum.cpp que contiene un
NxActor que se inicializa de la siguiente forma: funcin particulaHumo(posicionInicio, velocidadInicio) devuelve ParticulaHumo Crear el descriptor del actor, del cuerpo y de una forma simple de esfera; descriptorEsfera.radius = 1; descriptorEsfera.group = grupo; //todas las particulas tendran el mismo grupo descriptorActor.shapes.pushBack(descriptorEsfera); descriptorActor.body = descriptorCuerpo; descriptorActor.density = 0.1f; //las partculas tienen un peso muy pequeo descriptorActor.globalPose.t = posicionInicio; NxActor* actorParticula = motorFisico->getEscena()->createActor(descriptorActor); actorParticula->setLinearVelocity(velocidadInicio); Crear partcula; partcula->actorMotor=actorPartcula; devolver partcula; ffuncin

La velocidad de inicio es un escalar multiplicado por un vector aleatorio. Para generar valores aleatorios he utilizado la funcin rand() de C++. En la inicializacin del generador de partculas, uso la funcin
setGroupCollisionFlag

pasando como primer y segundo parmetro el grupo que he asignado a cada

partcula para que no colisionen entre ellas. La actualizacin de cada partcula antes de cada clculo de fsicas consiste en: 1) Eliminar la partcula si ha llegado a un tamao especfico (radio); o 2) Aplicar una fuerza en sentido contrario a la gravedad e incrementar el radio de la partcula:
accin actualizarPartcula (partcula,incrementoTiempo) si particula.radio>RADIO_MXIMO entonces eliminar_partcula; sino incrementar_radio_partcula; particula->actorMotor->addForce(FUERZA_ACELERACIN); fsi faccin

En cuanto a la creacin del emisor de humo, este contendr una lista de partculas de humo. Antes de cada clculo de fsicas, llamaremos a la funcin actualizar del generador de humo. ste, crear varias partculas dependiendo del lapso de tiempo que haya pasado y actualizar todas las partculas de la lista:
accin actualizarEmisor (incrementoTiempo) tiempoPartculas += incrementoTiempo; mientras tiempoPartculas > TIEMPO_ENTRE_PARTCULAS entonces crear partcula con velocidad aleatoria y aadirla a la lista; tiempoPartculas-= TIEMPO_ENTRE_PARTCULAS; fmientras para cada elemento P de la lista de partculas hacer actualizar_partcula(P,incrementoTiempo); fpara faccin

- Pgina 38 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Guardando el tiempo restante tiempoPartculas entre dos clculos de fsicas, nos aseguramos que siempre se crean las partculas a la misma velocidad.

6.1.5.- RESULTADO FINAL


El resultado final, a falta de una representacin mejor para la visualizacin, es una correcta simulacin de una columna de humo. No chocan entre ellas pero s con los actores que las atraviesan. Para la representacin he hecho que las partculas se hicieran ms grandes a medida que crecan y que desaparecieran al llegar a un cierto tamao. Sera deseable poder crear un nmero mucho mayor de partculas y, en el caso ideal, que el tamao de las partculas fuese igual a un pixel.

Resultado final de la generacin de humo.

Para mejorar la representacin, se podra crear un Shader y aplicar un efecto de Cell-Shading, o si se quiere algo ms realista, trazar para cada pxel de la salida, un rayo hacia la escena y oscurecer este punto dependiendo de cuntas partculas atraviesa y a qu distancia de cada una.

- Pgina 39 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.2.- SIMULACIN DE UN TORNADO 6.2.1.- OBJETIVO


El objetivo es crear un tornado que recoja los objetos que tenga cerca y estos empiecen a girar a su alrededor. Los objetos recogidos irn subiendo hasta llegar a una altura en que saldrn despedidos lejos del tornado.

6.2.2.- IDEA
La idea es descomponer el tornado en varios crculos de atraccin y rotacin. Cada crculo tendr un radio y una posicin relativa respecto al eje del tornado para as poder crear su forma caracterstica. Por lo que ahora el problema queda reducido a cmo implementar uno de estos crculos. Ya que solo los objetos que estn a una cierta distancia sern recogidos, es intuitivo definir un radio de accin para ese crculo. Los objetos que estn fuera de este radio, no se vern afectados por el tornado. No quiero crear una animacin de un objeto que gira o se ve atrado, modificando su posicin en cada iteracin del bucle de ejecucin, ya que no estara contemplando la posibilidad de que chocara con otros objetos que estn en el mismo proceso. Es por eso que se deben aplicar fuerzas sobre los objetos y no ir modificando su posicin. As, estos podrn colisionar entre ellos y aadir otras fuerzas resultado de las colisiones. El problema radica en cmo hacer que el objeto describa la trayectoria deseada slo aplicando fuerzas. Cada crculo va a efectuar una fuerza diferente sobre los objetos que giran en torno el tornado (ya que donde se tiene ms fuerza es en la base de ste). Cuando un objeto est a una cierta distancia del centro, el crculo lo atrae hacia s y es cuando ya est en los alrededores del crculo cuando empieza a girar. Por tanto se debe definir una zona de Atraccin (en la que se aplicar una fuerza hacia el centro dependiendo de la posicin en que se encuentra) y
Efecto sobre los elementos de la escena segn de la distancia al centro del crculo. Divisin del tornado entre crculos de atraccin y rotacin.

otra de Rotacin.

- Pgina 40 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Adems, debido a las funciones que ofrece el motor y el error en el clculo de la rotacin, las cajas entraran en el crculo del tornado (y si llegan a quedar justo en el centro, solo girarn sobre su eje). Si pasa esto, se debe aadir una fuerza de Repulsin para que el objeto salga del crculo. Es muy difcil mantener el objeto girando en la zona de Rotacin, por lo que constantemente se estar corrigiendo la trayectoria del objeto atrado. Los elementos atrados por el tornado irn subiendo, por lo que se les debe aplicar una fuerza hacia arriba. Para calcular la fuerza que se debe aplicar entre dos crculos de atraccin/repulsin, se utilizar una interpolacin lineal con la distancia. Cuando lleguen a una cierta altura quiero que los objetos salgan disparados hacia afuera y caigan. Esto es aplicar solamente una fuerza hacia afuera independientemente de la zona en que se encuentre.

6.2.3.- HERRAMIENTAS USADAS


No son muchas, solo las necesarias para modificar la direccin de un Actor. Intuitivamente, si solo queremos ir aadiendo fuerzas, usaramos la funcin addForce. Pero si vamos usando esta funcin en cada iteracin del bucle de la aplicacin, lo que haremos ser ir incrementando progresivamente la fuerza a la que est sometido el actor. Solo usando esta funcin es imposible mantener el actor en la zona de Rotacin, hay que unir una fuerza que calcularemos dependiendo de la zona en que se encuentre, con la fuerza que lleva el actor. Como no hay ninguna funcin getForce, pero sabemos que F = m*a = m*v/t y se puede obtener la masa con getMass y la velocidad con getLinearVelocity. El tiempo supondremos que es constante, aunque no sea cierto, porque queremos que aunque haya ralentizaciones en los clculos, la fuerza aplicada siempre sea la misma. Aparte tambin es necesario obtener la posicin global del actor con getGlobalPosition.

6.2.4.- IMPLEMENTACIN
Para definir un tornado, se deben definir varios crculos. Cada uno de estos tendr un radio, una posicin relativa (x,y,z), y una fuerza. Tendremos una lista de actores a los cuales puede afectar el tornado. Los actores de la escena que no estn en esta lista no recibirn ninguna influencia. Si aadimos algn actor que sea de tipo esttico, tampoco modificar su posicin al aplicarle las fuerzas.

- Pgina 41 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Cada vez que acabemos un clculo de fsicas y antes de empezar el siguiente, llamaremos a la funcin
aplicarFuerzas

del tornado. Este proceso buscar, para cada actor que recibe influencia, entre qu dos

crculos se encuentra.
accin aplicarFuerzas() para cada actor A de la lista de actores hacer buscar entre qu dos crculos se encuentra el actor; si est en el ltimo crculo hacer ... sino ... fsi fpara faccin

Si es el ltimo crculo, se aplica una fuerza de Repulsin. Para ello calculamos el vector V que va desde el punto central PC del ltimo crculo hasta el punto en que se encuentra el objeto PA , normalizamos el vector y lo multiplicamos por la fuerza definida en este crculo FC.
Clculo de la fuerza Repulsiva.

He dicho que usara la funcin addForce para asignar esta fuerza, pero teniendo en cuenta que se debe mantener la fuerza que tena el actor, por lo que a esta funcin le paso como parmetro el vector de la fuerza calculada menos la fuerza que llevaba, es decir:
actor.addForce(fuerzaRepulsin actor.getLinearVelocity()*actor.getMass()/TIEMPO_CONSTANTE)

Si no nos encontramos en el ltimo crculo, el actor puede estar en las cuatro zonas que he comentado antes. Si se encuentra a una distancia mayor que la de efecto del tornado, no se le aplicar ninguna fuerza y si se encuentra dentro del crculo del tornado, se aplicar la misma fuerza de repulsin. Si est en la zona de Atraccin, se le aplicar la misma fuerza que hemos calculado antes de Repulsin, pero en sentido contrario. En este caso hago una interpolacin lineal de la fuerza con la distancia del actor al centro para que al entrar dentro de la zona no se le aplique una fuerza mxima. En el ltimo caso, si nos encontramos en la zona de rotacin, deberemos aplicar una fuerza suficiente para hacer rotar el objeto. Se debe calcular una fuerza de atraccin y una fuerza que es tangente a la trayectoria circular que debe describir. Ambas fuerzas sumadas con unos coeficientes dan como resultado una fuerza que hace rotar el objeto alrededor del punto PC. Estos coeficientes deben definirse para que el actor tienda a acercarse al crculo, y no a alejarse. Debido al error que produce el motor al hacer los clculos (o por simplificarlos) y
Clculo de la fuerza de Rotacin.

- Pgina 42 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

que hay varios actores colisionando entre si y produciendo nuevas fuerzas, no se puede calcular con las leyes de Newton la fuerza exacta que debe hacerse, teniendo as que recurrir a coeficientes.

6.2.5.- RESULTADO FINAL


El resultado final sin aplicar ningn efecto de visualizacin es bastante correcto en cuanto al movimiento de las cajas que recoge el tornado. Recoge las que estn a una cierta distancia y las hace girar en torno suyo. He conseguido el efecto que quera ya que como hay muchas ms cajas girando alrededor estas colisionan entre s y no son objetos estticos con una animacin definida. Finalmente, al llegar al ltimo circulo de rotacin, los objetos pierden la fuerza que las impulsa hacia arriba, ya que no hay ningn otro crculo, y entonces caen al vacio. El coste computacional de este efecto es proporcional al nmero de cajas, incrementndose (significativamente) cuando hay muchas colisiones. Posteriormente se podra aplicar una (o varias) texturas al tornado para que quedara una visualizacin ms realista, pero he preferido dedicar este tiempo a otras simulaciones con el motor.

Resultado final del tornado con visualizacin de debug.

- Pgina 43 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.3.- OBJETOS ELSTICOS 6.3.1.- OBJETIVO


Quiero crear un objeto elstico o deformable que pueda modificar su malla cuando un objeto hace presin sobre l, pero que vuelva a su forma original en cuando la presin ha acabado. Ya anticipo que el resultado final no es todo lo bueno que esperaba.

6.3.2.- IDEA
Si se quiere que el objeto se pueda deformar, el uso de conectores o uniones es obligatorio ya que son las que permiten un movimiento entre dos actores. Un objeto elstico ser la composicin de varios actores y varios conectores que los unen. Cogeremos un modelo 3D formado por una malla de tringulos y lo dividiremos en varios actores. Seguramente hay varias formas de hacer esto pero yo he optado por la siguiente: para cada vrtice crear un actor con una forma esfrica. El radio de la esfera depender del tamao de los tringulos a los cuales pertenece. Tambin, para cada arista crear un actor con forma de cpsula alargada. El motivo de escoger esta forma es que como van a rozarse las formas resultantes de las aristas con las formas resultantes de los vrtices, el rozamiento y las colisiones entre dos esferas es menor (y una forma de cpsula tiene una semiesfera en cada extremo). El radio de la cpsula depender del tamao del tringulo y la longitud ser igual a la de la arista. Los radios escogidos han de dejar espacio suficiente para que en estado de reposo los actores asociados a un tringulo (tres cpsula y tres esferas) no ejerzan fuerza entre s. Una vez declarados los actores en la escena, se crearn uniones entre cada actor-arista y sus dos actoresvrtice asociados. Las uniones sern de tipo esfrico, para permitir la rotacin en los tres grados de libertad. Si las uniones no aplicasen ninguna fuerza, el conjunto de actores se caera ya que no tiene ningn volumen fsico dentro, por lo que todos los conectores han de ejercer una fuerza para que el actor-arista y el actor-vrtice asociados vuelvan a su posicin relativa (en grados) original.
Creacin de actores-vrtice y actores-arista

- Pgina 44 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

De esta forma, todos los tringulos que forman el modelo podrn modificar su orientacin respecto a los tringulos vecinos, y al ejercer una fuerza sobre un actor, el movimiento que producir repercutir en las uniones ms cercanas dando como resultado una deformacin del objeto. La dificultad reside en orientar bien los actores-arista y en configurar adecuadamente la fuerza que efectuar cada conector.

6.3.3.- HERRAMIENTAS USADAS


Para los actores-arista utilizare la forma de cpsula NxCapsuleShape, la cual se configura con un radio y una longitud. Para los actores-vrtice utilizo la forma de esfera NxSphere que ya he explicado como declararla en la escena. La orientacin de las cpsulas ser aleatoria y los algoritmos para la creacin de actores que he presentado solo permiten crear actores con la orientacin original (en el caso de la cpsula es vertical con las semiesferas arriba y abajo). Al crear el actor se deber modificar la orientacin multiplicando la matriz de transformacin (campo
globalPose) con las matrices de rotacin 3x3.

Orientacin de las cpsulas y creacin de uniones, punto de unin (rojo) y eje (azul).

Las uniones esfricas se crean con la clase NxSphericalJoint. Para configurar sern necesarios, aparte de los dos actores, el punto de unin y el eje (para determinar los lmites de rotacin y el efecto de Spring). Hay que inhibir la rotacin de las esferas para no provocar fuerzas indeseadas. Esto se hace con la instruccin:
actorMotor->raiseBodyFlag(NX_BF_FROZEN_ROT);

6.3.4.- IMPLEMENTACIN
Es necesario especificar una topologa para el modelo que debemos crear. Originalmente tendremos una lista de vrtices y una lista de tringulos que sern grupos de tres ndices a la lista de vrtices. Adems se necesita asociar a cada vrtice un actor-vrtice, y a cada tringulo tres actores-aristas. Si un tringulo est formado por los ndices a vrtice <i,j,k> y los actores-aristas <m,n,l>, el actor-arista m conecta con los actores-vrtices de i y j, el n con los de j y k, y el l con los de k e i. Primero crearemos todos los actores-vrtice recorriendo la lista de vrtices y despus los actores-arista recorriendo la lista de tringulos y accediendo a los dos vrtices de cada lista. A su vez, tambin crearemos las uniones accediendo a los actores-vrtice. El algoritmo es el siguiente:

- Pgina 45 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

funcin crearObjetoElstico(modelo) devuelve objetoElstico inicializa la clase objetoElstico; para cada vrtice v en modelo.lista_vrtices hacer actorVrtice = crearEsfera(v.pos,RADIO_VRTICE,PESO_VRTICE); v.actor = actorVrtice; objetoElstico.listaActoresVrtice.aadir(actorVrtice); fpara para cada tringulo t en modelo.lista_tringulos hacer para i=0 hasta 2 hacer

Parmetros para definir una cpsula


v1 = t.vrtice[i]; v2 = t.vrtice[(i+1) mod 3]; vectorDirector = v2.pos v1.pos; longitud = vectorDirector.modulo() RADIO_VRTICE*2; posicin = v1 + vectorDirector/2; actorArista = crearCpsula(posicin,vectorDirector,longitud,RADIO_ARISTA, PESO_ARISTA); objetoElstico.listaActoresArista.aadir(actorArista);

Creacin de las uniones


vectorDirector.normalizar(); puntoUnin1 = v1+vectorDirector*RADIO_VRTICE; unin1 = crearUninEsferica(puntoUnin1,vectorDirector,v1.actor, actorArista); puntoUnin2 = v2-vectorDirector*RADIO_VRTICE; unin2 = crearUninEsferica(puntoUnin2,-vectorDirector,actorArista, v2.actor); objetoElstico.listaUniones.aadir(unin1); objetoElstico.listaUniones.aadir(unin2); fpara fpara devuelve objetoElastico; ffuncin

- Pgina 46 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

La creacin de las cpsulas necesita un radio, una longitud, una posicin global, un vector director y una masa. El algoritmo para declarar y posicionar el actor sera el siguiente.
funcin crearCapsula(posicion,vectorDirector,longitud,radio,peso) devuelve actorMotor crear el descriptor del actor, de la capsula y del cuerpo; descriptorCapsula.height = longitud; descriptorCapsula.radius = radio; descriptorActor.shapes.pushBack(&descriptorCapsula); descriptorActor.body = &descriptorCuerpo; descriptorActor.density = pes; descriptorActor.globalPose.t = posicin; obtenerAngulosRotacion(vectorDirector,rotX, rotY,rotZ); crear la matriz de rotacin para X, Y y Z; descriptorActor.globalPose.M*=matrizRotacionY; descriptorActor.globalPose.M*=matrizRotacionX; descriptorActor.globalPose.M*=matrizRotacionZ; escena->createActor(descriptorActor); devuelve actorMotor; ffuncin

A partir del vector, se ha de obtenerlos dos o tras ngulos de rotacin necesarios para orientar el objeto correctamente. Con ellas se crean las tres matrices de rotacin y se multiplican por la matriz de transformacin original del objeto.

6.3.5.- RESULTADO FINAL


El resultado final no es lo bueno que esperaba. Pueden pasar objetos por dentro de los tringulos ya que no hay nada que lo impida, solo ofrecen presin los vrtices y aristas. Una solucin para esto no sera hacer slido el interior del tringulo, porque este se puede deformar un poco. Tal vez, si hubiese creado slidos triangulares y hubiese unido los vrtices el resultado sera mejor, aunque me pareci ms lgica la opcin que escog. Si no se configuran bien las fuerzas, el objeto se derrumba sobre si mismo ya que las uniones no pueden aguantar el peso y la fuerza que estn haciendo las dems. - Pgina 47 -

Obtencin de los ngulos de

Resultado final

Simulacin de efectos Fsicos

scar Llorens Maldonado

Esto se hace especialmente notorio en modelos ms complejos. He implementado un algoritmo para subdividir los tringulos pero al crear el modelo, debido a la subdivisin y a la falta de configuracin de las fuerzas, el resultado es bastante malo. Los nuevos vrtices y aristas resultado de la subdivisin quedan colgando de los originales. Tal vez si la subdivisin distinta, el resultado sera mejor.

Subdivisin de un tringulo.

Otro problema derivado de la elasticidad que permiten las uniones viene dado cuando el objeto colisiona, que dependiendo de la fuerza con que lo haga pueden hacerse nudos entre las aristas y vrtices. Parece que las uniones no ejercen la fuerza que deberan, o se anulan entre s. Tal vez se debera crear algn tipo de conectores, de los cuales el motor no dispone, especfico para crear objetos deformables. A pesar de todos los errores mencionados, el objeto (formado por alguna malla sencilla) s que muestra elasticidad al colisionar y rebotar por la escena, volviendo a su posicin original tras librarse de la presin de la colisin.

- Pgina 48 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.4.- ANIMACIN DE ROPA 6.4.1.- OBJETIVO


El objetivo de esta parte es simular el efecto que produce la ropa al moverse, cmo se dobla al estar sometida a una presin. He encontrado dos formas de hacerlo, bastante distintas entre s, en el planteamiento y en el resultado final.

6.4.2.- MTODO 1
6.4.2.1.- IDEA
La ropa debe poder doblarse por cualquier sitio, por lo que debera de estar formada por varios puntos de unin que podrn modificar la posicin entre ellos. Entonces, la primera aproximacin para generar elementos de tela podra ser la de crear varias masas esfricas (para que haya menor rozamiento) y unirlas entre ellas. Para ello usar un tipo de unin especfico para este caso, la unin con efecto de muelle: queremos que dos puntos de masa, cuando se separen hagan fuerza para juntarse (para que la tela tenga elasticidad pero no infinita), y cuando se junten mucho hagan fuerza para separarse (para que no quede arrugada siempre y para eliminar errores como que se haga un lio entre varias masas).
Uniones tipo muelle en horizontal, vertical y diagonal entre los puntos de masa del elemento de tela.

No bastara con unir cada punto de masa con los que tiene en los cuatro puntos cardinales ya que quedara un efecto extrao con la ropa doblndose solo en horizontal y vertical. Por lo que uniremos cada masa con las ocho que tiene alrededor, como muestra la figura de arriba. La parte ms complicada consistir en configurar las fuerzas de estas uniones con las masas de los elementos esfricos para que el efecto sea deseado. Ya anticipo que esto va a ser un problema.

6.4.2.2.- HERRAMIENTAS USADAS


Los puntos de masa sern actores con una nica forma simple de esfera NxSphereShape con una cierta masa y radio. La unin de tipo muelle se llama NxSpringAndDamperEffector. Para configurar es necesario especificar qu dos actores estn sometidos a la unin (mediante la funcin setBodies) y varios valores escalares (con las - Pgina 49 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

funciones setLinearSpring y setLinearDamper) como la distancia que tiene que haber en los dos objetos para que no se apliquen fuerzas (distancia de relajado), las distancias en que la fuerza que une/separa las dos masas es mxima o la velocidad/fuerza de compresin/estiramiento.

6.4.2.3.- IMPLEMENTACIN
Los valores que definirn una pieza de ropa sern los siguientes:
NUM_CONECT_H, NUM_CONECT_V: Se crearn NUM_CONECT_H x NUM_CONECT_V en total. DIST_CONECT_H, DIST_CONECT_V: Distancia vertical y horizontal entre dos conectores. PESO: Peso de todo el objeto. FUERZA_COMRESION: Fuerza que actuara en el objeto al estirarse. FUERZA_ESTIRAMIENTO: Fuerza que actuara en el objeto cuando se comprima. SATURACIN_COMPRESION: Punto a partir del cual la fuerza de compresin ser constante. SATURACIN_ESTIRAMIENTO: Punto a partir del cual la fuerza de estiramiento ser constante. VEL_REGULADOR_ESTIRAMIENTO:

Velocidad en la que acta la fuerza reguladora de estiramiento.

VEL_REGULADOR_COMPRESION: Velocidad en la que acta la fuerza reguladora de compresin. F_REGULADOR_ESTIRAMIENTO:

Fuerza reguladora de estiramiento para que el objeto no alcance demasiada velocidad.

F_REGULADOR_COMPRESION: Igual que la anterior pero para la compresin.

La creacin de las masas esfricas NxSphereShape es anloga a la creacin de cajas que he escrito anteriormente, con la diferencia que solo debe definirse una posicin inicial, un radio (RADIO_MASA) y una masa (VALOR_MASA). Existe un problema al unir dos actores de forma esfrica: se generan fuerzas que hacen rodar las esferas infinitamente y ello puede traer alguna inestabilidad adems de provocar clculos intiles. Se puede desactivar la rotacin de las esferas al crear el descriptor del cuerpo aadiendo el siguiente flag:
descriptorCuerpo.flags |= NX_BF_FROZEN_ROT;

Cada masa tendr asociada una clase ConectorsMasa, que contendrn las cuatro uniones de tipo
NxSpringAndDamperEffector.

Estas uniones correspondern, a la horizontal derecha, vertical superior,

diagonal hacia arriba y diagonal hacia abajo. Obviamente, las masas de los extremos no tendrn todas estas uniones. Dejo para despus comentar la funcin que configura estas uniones. Paso a explicar el algoritmo de creacin de la ropa. Primero crearemos todas las masas, y para ello se debe calcular el radio y el peso a partir de los datos de configuracin. La masa de ser igual a la masa de todo el objeto dividido entre el nmero de puntos de unin que crearemos. El radio hay que configurarlo teniendo - Pgina 50 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

en cuenta que dos masas no pueden solaparse pero es preferible que quede el menor espacio posible para que no pasen un objeto por en medio.
funcin crearRopa(posicin) devuelve RopaMasas crear el objeto RopaMasas; radioMasa = min(DIST_CONECT_H,DIST_CONECT_V)/2.1; pesoMasa = PESO/(NUM_CONECT_H*NUM_CONECT_V); //posicin de inicioMasas.x inicioMasas.y inicioMasas.z la masa que est abajo a la derecha = posicio.x-numConectH*distanciaConectH / 2; = posicio.y-numConectV*distanciaConectV / 2; = posicio.z;

para i=0 hasta NUM_CONECT_V-1 hacer para j=0 hasta NUM_CONECT_H-1 hacer //posicin de la masa[i,j] posicionMasa.x = j * DIST_CONECT_H; posicionMasa.y = i * DIST_CONECT_V; posicionMasa.z = 0; posicionMasa += inicioMasas; ropaMasas.masas[i,j] = crearMasa(posicionMasa, radioMasa, pesoMasa); j++; fpara i++; fpara ...

El bucle de creacin de las masas consiste en calcular la posicin de la


masa[i,j]

y aadirla al motor con la funcin que he comentado antes,

teniendo en cuenta que la i recorre las masas en vertical y la j en horizontal. Ahora queda crear los conectores. Hay que crear para cada masa uno en horizontal-derecha, uno en vertical-arriba y dos en diagonal hacia arriba y hacia abajo (los dos hacia la derecha), como indica la figura de la derecha. Algunas masas de las esferas de los extremos no tendrn esos conectores.
... contador=0; para i=0 hasta NUM_CONECT_V-1 hacer para j=0 hasta NUM_CONECT_H-1 hacer actor1 = ropaMasas.masas[i,j];

Uniones que se deben crear para una masa [i,j].

//conector horizontal con la masa de la derecha si j < (NUM_CONECT_H -1) entonces actor2 = ropaMasas.masas[i,j+1]; ropaMasas.conectores[contador++]=crearConector(actor1, actor2); fsi //conector vertical con la masa de arriba si i < (NUM_CONECT_V -1) entonces actor2 = ropaMasas.masas[i+1,j]; ropaMasas.conectores[contador++]=crearConector(actor1, actor2); fsi

- Pgina 51 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

//conector en diagonal con las masa de arriba-derecha si j<(NUM_CONECT_H - 1) y i<(numConectV - 1) entonces actor2 = ropaMasas.masas[i+1,j+1]; ropaMasas.conectores[contador++]=crearConector(actor1, actor2); fsi //conector en diagonal con la masa de abajo-derecha si j<(NUM_CONECT_H - 1) y i>0 entonces actor2 = ropaMasas.masas[i-1,j+1]; ropaMasas.conectores[contador++]=crearConector(actor1, actor2); fsi fpara fpara devuelve ropaMasas; ffuncin

La funcin crearConector debe configurar el conector con los parmetros que he comentado al principio. Para ello hay dos funciones, una asociada al Spring (setLinearSpring) y la otra al Damper (setLinearDamper). La primera hace actuar fuerzas a los dos actores unidos para que vuelvan a su distancia inicial: hay un estado de reposo en el que no se aplican fuerzas pero si se separan los actores aadir fuerzas para unirlos y si intentan unirse, har fuerza para separarlos. Se deben definir las fuerzas de compresin (FUERZA_COMRESION) y estiramiento (FUERZA_ESTIRAMIENTO) y los puntos de saturacin de cada una de estas fuerzas (SATURACIN_COMPRESION, SATURACIN_ESTIRAMIENTO). Si la unin se estira sin llegar al punto de saturacin, se aplicar una fuerza que es una interpolacin de la fuerza FUERZA_COMRESION con la distancia que se ha estirado la unin (en la figura FI); y a partir de que esta distancia pase el punto de saturacin, se aplica la fuerza FUERZA_COMRESION de manera constante para unir los actores (en la figura FS).

Aplicacin de fuerzas dependiendo de la distancia de relajado y saturacin, solo en el caso de estiramiento (es anlogo para la compresin).

- Pgina 52 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

El efecto de Damper sirve para suavizar y controlar la velocidad en que se mueven los actores a causa del factor Spring del conector. F_REGULADOR_COMPRESION es la fuerza mxima que el conector aplica para contrarrestar la velocidad de compresin. La fuerza empieza en cero cuando los cuerpos estn en estado de reposo y se incrementa hasta alcanzar el valor definido a medida que la velocidad entre los dos objetos se acerca a VEL_REGULADOR_COMPRESION. Y lo mismo ocurre con F_REGULADOR_ESTIRAMIENTO y
VEL_REGULADOR_ESTIRAMIENTO.

Finalmente se usa la funcin setBodies para especificar qu dos actores y en qu puntos actuar el conector:
funcin crearConector(actor1,actor2) devuelve conector crear el conector; vectorConector = actor1.posicin actor2.posicin; distanciaRelajado = vectorConector.modulo(); distanciaSaturacionCompresion = SATURACIN_COMPRESION *distanciaRelajado; distanciaSaturacionEstiramiento= SATURACIN_ESTIRAMIENTO*distanciaRelajado; conector->setLinearSpring(distanciaSaturacionCompresion, distanciaRelajado, distanciaSaturacionEstiramiento, FUERZA_COMRESION, FUERZA_ESTIRAMIENTO); conector->setLinearDamper(VEL_REGULADOR_ESTIRAMIENTO, VEL_REGULADOR_COMPRESION, F_REGULADOR_ESTIRAMIENTO, F_REGULADOR_COMPRESION); conector->setBodies(actor1, actor1.posicin, actor2,actor2.posicin); devuelve conector; ffuncin

Es difcil configurar estos parmetros sin tener en cuenta el nmero de masas o conectores que existirn en la ropa simulada. En mi caso, para una pieza de 16x16 masas, los valores que he configurado para el conector son los siguientes:
FUERZA_COMRESION: 10 FUERZA_ESTIRAMIENTO: 40 SATURACIN_COMPRESION: 0.1 SATURACIN_ESTIRAMIENTO: 0.2 VEL_REGULADOR_ESTIRAMIENTO: -100 VEL_REGULADOR_COMPRESION: 100 F_REGULADOR_ESTIRAMIENTO: 100 F_REGULADOR_COMPRESION: 100

Para la visualizacin, aparte de la de debug que mostrar las masas y las uniones entre stas con esferas y lneas, crearemos una malla de tringulos. Ms adelante detallar este proceso pero para hacer una aproximacin, se deben recorrer todos los puntos de masa creando dos tringulos con los puntos adyacentes de la derecha, arriba y arriba-derecha, como muestra la figura.Una vez se tienen las caras de los tringulos (con sus normales), se calculan las normales por vrtice a partir de las normales de las caras adyacentes.

- Pgina 53 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.4.2.4.- RESULTADO FINAL


El resultado final es bueno en cuanto al movimiento pero demasiado inestable y con algunos errores. Al lanzar una bola contra el objeto de tela sta pasa a travs de de las esferas de masa apartndolas. Es una colisin demasiado rpida como para que las uniones apliquen fuerza para no dejar pasar la bola. Sin embargo, cuando ha pasado el objeto lanzado las uniones s que aplican la fuerza y hay una especie de rebote entre los puntos de unin que hacen saltar la ropa. La solucin de esto no es incrementar la fuerza de las uniones ya que modificando ciertos parmetros de estas uniones el sistema se vuelve muy inestable y hay resonancias enormes (y parece que exponenciales) entre los puntos de unin. Generando una malla de tringulos y aplicando normales por vrtice, el resultado final a nivel visual es bastante realista y, exceptuando los errores de rebotes y resonancias, la animacin pienso que es correcta. Sin embargo, para un objeto con 16x16=256 puntos de masa, hay que crear aproximadamente 1024 uniones, y creo que no es algo muy eficiente aparte de los errores que he comentado. El siguiente mtodo arregla estos errores y adems
Representacin mediante una malla de tringulos con normales por vrtice y sin textura. Resultado final de las masas conectadas con uniones de tipo muelle.

hay menos uniones con lo que la simulacin es ms eficiente.

- Pgina 54 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.4.3.- MTODO 2
Otra forma ms eficiente de simular objetos de tela es la que explicar a continuacin. Tiene alguna desventaja que ya comentar pero en general la animacin es ms correcta y se deben hacer menos clculos ya que se usan menos conectores (la mitad).

6.4.3.1.- IDEA
De la misma forma que antes, se debe dividir la ropa en varios puntos de masa, pero en este caso sern cajas en vez de esferas. Entre dos cajas crearemos y configuraremos una unin de tipo esfrica en el centro de los lados que estn adyacentes. Con ello tendremos que cada caja est unida con las cuatro de los puntos cardinales y permite que roten en cualquier direccin. Es importante que sean cajas y no esferas para que no haya agujeros entre las masas, aparte de que aadir una unin esfrica a una esfera no est soportado por el motor. Creando esta estructura de cajas y uniones se obtiene como resultado un objeto sin agujeros, robusto (ya que no permite elasticidad) y sin resonancias o inestabilidades.
Uniones esfricas entre las cajas que forman el objeto de tela.

Las rotaciones lmite que han de permitir estas uniones son configurables; modificando estos valores se pueden crear ropas ms blandas o duras (en cuanto a la torsin que permiten). Adems para este mtodo creo necesario crear una malla de tringulos que d un volumen a la ropa, calcular las normales por vrtices y aplicar una textura.

6.4.3.2.- HERRAMIENTAS USADAS


Las masas en este caso son cajas, es decir formas simples
NxBoxShape

configuradas a partir de tres longitudes

(alto, ancho, grueso) y una masa. Para la unin de tipo esfera (figura adjunta) se usa la clase
NxSphericalJoint

en

la

que

deberemos

especificar en el descriptor los actores involucrados, la posicin de la unin (globalAnchor), el vector direccin de la unin que define el eje (globalAxis) y las torsiones - Pgina 55 Unin esfrica con lmites de balanceo.

Simulacin de efectos Fsicos

scar Llorens Maldonado

y balanceos mximos que permitimos entre los dos actores a partir de este vector (twistLimit,
swingLimit).

Estos dos ltimos parmetros tambin tienen los efectos de Spring y Damper que he

explicado en el mtodo anterior. Si se quiere configurar todo, hay que aadir los flags
NX_SJF_TWIST_LIMIT_ENABLED, NX_SJF_SWING_SPRING_ENABLED. NX_SJF_SWING_LIMIT_ENABLED, NX_SJF_TWIST_SPRING_ENABLED y

6.4.3.3.- IMPLEMENTACIN
Para este mtodo los valores configurables son:
NUM_CONECT_H, NUM_CONECT_V: Se crearn NUM_CONECT_H x NUM_CONECT_V en total. TAM_X, TAM_Y, GROSOR:

Tamao en altura, amplitud y grosor de cada una de las cajas que

corresponden a los puntos de masa del objeto.


LIM_MIN_TORSION, LIM_MAX_TORSION:

Lmites

mnimo

mximo que puede torcerse un actor sobre el otro.


LIM_BALANCEO:

Lmite de balanceo que tienen los actores

asociados a la unin.
FUERZA_TORSION, FUERZA_BALANCEO:

Fuerza que se impone a la

torsin/balanceo.
REGULADOR_TORSION,REGULADOR_TORSION: Fuerza que no permite

que la fuerza de torsin/balanceo haga que el objeto gire o se balancee a demasiada velocidad.
Significado de torsin y balanceo en una unin esfrica.

Primero creo las partes de la ropa igual que creaba los puntos esfricos de masa en el mtodo anterior, pero en este caso se deben crear cajas.
ropaUniones.partes[i,j] = crearMasa(posicionMasa, TAM_X, TAM_Y, GROSOR, pesoMasa);

Para las conexiones usare la funcin crearConector que explicar despus. De la misma forma que antes, se crean las conexiones con la caja de la derecha y la de arriba, si existen.
... contador=0; para i=0 hasta NUM_CONECT_V-1 hacer para j=0 hasta NUM_CONECT_H-1 hacer actor1 = ropaUniones.partes[i,j]; //conector horizontal con la masa de la derecha si j < (NUM_CONECT_H -1) entonces actor2 = ropaMasas.partes[i,j+1]; ropaUniones.conectores[contador++]=crearConector(actor1, actor2); fsi //conector vertical con la masa de arriba si i < (NUM_CONECT_V -1) entonces actor2 = ropaMasas.partes[i+1,j]; ropaUniones.conectores[contador++]=crearConector(actor1, actor2);

- Pgina 56 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

fsi fpara fpara devuelve ropaUniones; ffuncin

En la simulacin que muestro, la tela esta colgada por dos puntos. Esto se hace definiendo las partes como estticas o igualando el peso a cero (infinito):
ropaUniones.partes[0,0]->raiseBodyFlag(NX_BF_KINEMATIC);

En cuanto a la funcin para crear el conector, solo hay que asignar un valor a los campos que he comentado en el apartado de Herramientas Usadas al configurar el descriptor. Para un objeto de 20x20 partes y 3000 unidades de peso he usado los siguientes valores:
LIM_MIN_TORSION: 0,25Pi LIM_BALANCEO: 0,25Pi FUERZA_TORSION: 0.5 REGULADOR_TORSION: 1 LIM_MAX_TORSION: 0,25Pi FUERZA_BALANCEO: 0.5 REGULADOR_BALANCEO: 1

Ahora quiero que la simulacin parezca ms realista y para ello crear una malla de tringulos. Hay que tener en cuenta que en cada iteracin del bucle de clculo y visualizacin, la posicin de los actores que corresponden a las masas que forman el objeto habr cambiado, por lo que la generacin de la malla se deber hacer cada vez que pintemos el objeto en la escena. Para generar la malla tomo como vrtices los puntos centrales de todas las partes de las que est compuesto el objeto. Entonces genero para cada punto (que no est en los extremos derecho o superior) dos tringulos con los vrtices de la derecha, de arriba y de arriba-derecha, como se muestra en la figura. Despus calculo la normal de la cara que forma estos tringulos y la normalizo. Como quiero tener normales por vrtice, debo sumar para cada vrtice todas las normales de las caras de las cuales forma parte. En la figura de la derecha, para calcular la normal del vrtice de color azul debo sumar las normales de los seis tringulos amarillos. La forma fcil de hacer esto es calcular la normal de cada uno de estos tringulos (una vez), normalizarla y sumarla a los tres vrtices que componen el tringulo. Una vez se hayan calculado todos, solo se debe normalizar la normal de cada vrtice. - Pgina 57 Malla de tringulos a partir de las partes del objeto. Clculo de normales por vrtice.

Simulacin de efectos Fsicos

scar Llorens Maldonado

accin pintarMalla(ropaUniones) //clculo de las normales crear una matriz [NUM_CONECT_H,NUM_CONECT_V] de vectores e inicializarla a (0,0,0); para i=0 hasta NUM_CONECT_V-1 hacer para j=0 hasta NUM_CONECT_H-1 hacer triangulo1 = Triangulo(ropaUniones.partes[i,j].posicion, ropaUniones.partes[i,j+1].posicion, ropaUniones.partes[i+1,j+1].posicion); triangulo2 = Triangulo(ropaUniones.partes[i,j].posicion, ropaUniones.partes[i+1,j+1].posicion, ropaUniones.partes[i+1,j].posicion); normales[i,j]+=triangulo1.normal+triangulo2.normal; normales[i,j+1]+=triangulo1.normal; normales[i+1,j]+= triangulo2.normal; normales[i+1,j+1]+=triangulo1.normal+triangulo2.normal; fpara fpara normalizar todas las normales;

Una vez tenemos calculadas las normales por vrtice, ya se puede crear la malla. Como quiero darle volumen, crearemos una malla para la parte de delante de la ropa y una para la parte de detrs. Los vrtices de la malla de delante estarn a una distancia GROSOR/2 del vrtice original (el centrado en el actor de la parte de la ropa) en direccin de la normal que acabamos de calcular. De la misma forma, la malla de detrs estar a una distancia GROSOR/2. Ver la figura de la izquierda.

Tambin quiero asignarle una textura. Cogiendo una con forma cuadrada cualquiera, las coordenadas (s,t) van de [0,0] a [1,1], por lo que el vrtice (i,j) tendr las coordenadas de textura [i/NUM_CONECT_V,
j/NUM_CONECTH].

La siguiente funcin sirve para dibujar en OpenGL un vrtice con normal por vrtice y textura.
accin dibujarVrtice(vrtice, normal, s, t) glNormal3f(normal.x,normal.y,normal.z); glTexCoord2f(s/NUM_CONECT_V, t/NUM_CONECT_H); glVertex3f(vrtice.x, vrtice.y, vrtice.z); faccin

El siguiente algoritmo dibuja en OpenGL, para cada punto que no sea extremo derecho o superior, cuatro tringulos usando la funcin anterior: dos de la parte de delante del objeto incrementando la posicin de los vrtices con la mitad del grosor de la ropa en direccin a la normal, y los otros dos decrementndola tambin con la mitad del grosor.

- Pgina 58 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

glBindTexture(GL_TEXTURE_2D, textura); glBegin(GL_TRIANGLES); para i=0 hasta NUM_CONECT_V-1 hacer para j=0 hasta NUM_CONECT_H-1 hacer vrtice = ropaMasas.partes[i,j].posicin + normales[i,j]*GROSOR/2; dibujarVrtice(vrtice,normales[i,j],i,j); vrtice = ropaMasas.partes[i,j+1].posicin + normales[i,j]*GROSOR/2; dibujarVrtice(vrtice,normales[i,j+1],i,j+1); vrtice = ropaMasas.partes[i+1,j+1].posicin + normales[i+1,j+1]*GROSOR/2; dibujarVrtice(vrtice,normales[i+1,j+1],i+1,j+1); ... //igual con el otro tringulo del punto, y para los dos de la parte //posterior de la ropa, pero a distncia GROSOR/2 fpara fpara ... // queda dibujar los lados de la ropa faccin

Solo queda dibujar los lados del objeto de forma parecida a lo anterior y usando cualquier parte de la textura.

6.4.3.4.- RESULTADO FINAL


El resultado final es mucho mejor que en el anterior caso. Para una ropa de 20x20=400 masas se han creado
400x2=800

conectores, con lo que la simulacin es

mucho ms eficiente. La animacin tambin es ms correcta y realista, sin inestabilidades al lanzar un objeto: con una tela colgando, sta se dobla cogiendo la forma del objeto lanzado sin saltar ni rebotar como pasaba en el primer mtodo, y la fuerza se propaga a travs de toda la malla del objeto para luego ir recuperando la forma mientras pende de los dos puntos de sujecin superiores. Adems tampoco pueden producirse nudos entre las masas ya que estas estn todas unidas sin espacio para atravesarse.
Resultado final de las masas con forma de caja conectadas con uniones esfricas.

- Pgina 59 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

No se producen resonancias, ya que no se aplican fuerzas como en el muelle (solo se aplican para suavizar los movimientos de las masas, no para modificar su posicin) y es mucho ms fcil de configurar los parmetros para uniones esfricas. Sin embargo, una desventaja es que la tela creada no es elstica, no puede deformarse ya que no hay ninguna unin que permita modificar la distancia entre dos puntos de masa. Y la representacin visual con una malla de tringulos texturizada, con normales por vrtice y generando un volumen ayuda a dar como resultado una buena simulacin.

Malla texturizada con clculo de normales por vrtice que genera un volumen para el objeto.

- Pgina 60 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.5.- ROTURA DE OBJETOS 3D 6.5.1.- OBJETIVO


El objetivo de esta simulacin es que, dado un modelo aleatorio, si el actor colisiona con algn componente de la escena, pueda romperse en trozos. Esto parece un poco difcil de hacer en tiempo real y con un modelo aleatorio. En mi caso, para generar objetos rompibles har un pre-procesado del modelo para dividirlo en partes, que al colisionar se despegarn del modelo original.

6.5.2.- IDEA
Debemos subdividir el modelo original en celdas. Durante un momento pensemos que estamos trabajando en el plano. Subdividimos el modelo en cuadrados de lado L dependiendo de lo pequeos que queremos que sean los trozos. Para un cuadrado, calculamos qu vrtices quedan dentro. Para cada vrtice interior, miramos si la arista asociada a l atraviesa el borde del cuadrado, y si es as calculamos el punto de interseccin. La unin de estos vrtices con aristas da como resultado el borde de la figura en ese cuadrado. El modelo asociado a esa celda debe ser cerrado, por lo que se deben crear ms aristas en los bordes del cuadrado. Hay cuadrados que no tienen ningn vrtice pero son interiores al modelo, por lo que se debern crear aristas en todos los bordes del cuadrado.

Divisin del modelo original

Una vez tenemos todo el modelo subdividido, eliminamos las celdas que no contengan partes del modelo y asignamos un valor de resistencia a cada parte. - Pgina 61 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

En una colisin de fuerza F, esta fuerza se propagar a travs de las celdas del modelo desde la celda donde se ha originado. Su valor ira decrementando a medida que se aleje del punto de impacto. Se restar la fuerza que llegue a una celda con la resistencia de esta. Despus se har un recorrido de todas las celdas. Las que tengan una resistencia igual o inferior a cero, se separarn del modelo original.

Impacto, clculo del efecto y rotura. La resistencia de cada celda es de 2.

No necesariamente todas las partes que se separen deben ser de celdas individuales. Es posible que se hagan varios grupos de celdas como resultado de una colisin. Adems, para dar una cierta aleatoriedad en las partes, para que no todas sean cuadradas, se pueden desplazar los vrtices de cada cuadrado antes de hacer la subdivisin, como en la figura inferior:

Divisin aleatoria del modelo.

El caso en 3D es bastante ms complicado ya que deben construirse tringulos y las intersecciones son entre rectas y planos en el espacio. Para simplificar el problema solo he tratado los casos ms sencillos.

6.5.3.- HERRAMIENTAS USADAS


Para generar la forma del actor en la escena ser necesario cocinar los trozos del modelo. Cada vez que se rompa el modelo en ms trozos, se deber generar una malla para cada uno de los trozos nuevos, crear los actores agrupando las mallas y eliminar el antiguo actor.

- Pgina 62 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Los actores de las subdivisiones debern tener la misma velocidad, orientacin y posicin (global, no relativa) que el actor antes de subdividirlo, por lo que asignaremos la matriz de transformacin (getGlobalPose) y la velocidad (getLinearVelocity, getAngularVelocity). Si se quiere ejecutar una funcin en cada colisin, se debe usar el User Reports. Para cada pareja de actores que queremos que nos informen si ha habido colisin, debemos usar la funcin setActorPairFlags.

6.5.4.- IMPLEMENTACIN
Creo que es mejor no aadir pseudocdigo para explicar la implementacin de este efecto. El proceso de subdividir un modelo en el espacio es el de crear celdas cbicas. Como quiero poder desplazar los vrtices, cada celda cbica va a tener 12 tringulos que la delimitan, es decir 12 planos definidos de manera que el interior de cubo est contenido en el subespacio positivo. Para cada celda se deben encontrar los vrtices interiores a sta (de color azul en la figura) . Para ello hay que definir una operacin que responde cierto o falso dependiendo de si un punto es interior a una celda. Esta funcin mira si el punto est en el plano positivo de todos los tringulos que delimitan la celda. Si es as, quiere decir que el punto se encuentra en el interior. Si el punto se encuentra en el subespacio negativo de alguno de los planos, quiere decir que no est dentro de la celda.Si se encuentran tres vrtices que forman un tringulo dentro de la celda, ese tringulo se declara en la subdivisin final del modelo para esa celda. Para cada vrtice contenido en la celda, se cogen las aristas y se comprueba si atraviesan el lmite de la celda. Esta operacin de corte de un segmento con un plano devuelve falso si no se cortan, o cierto y el punto de interseccin (en verde). Adems de estos puntos, para cada tringulo que contenga estos vrtices interiores, deberemos cortarlos con cada arista del cubo para obtener los puntos de los lmites de los tringulos que forman el cubo (en lila). Esto se hace solucionando un sistema de tres ecuaciones con tres planos: el del tringulo del modelo original y los dos de los lmites de la celda.

- Pgina 63 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Una vez hecho esto, se pueden crear los tringulos necesarios para poder definir completamente la parte del modelo interior a esa celda. Solo queda crear el resto de tringulos para cerrar el objeto. Para esto tenemos que saber cul es el lado interior de la figura. En concreto, se ha de comprobar para cada vrtice de la celda si es interior o no al modelo original (color marrn). Con estos puntos ya se puede cerrar el objeto generando nuevos tringulos.

Ahora solo queda cocinar los modelos subdivididos de todas las celdas para aadirlos (juntos) en el actor original de la escena. Cada vez que este actor reciba una colisin, se determina en qu celda se ha recibido y a partir de la fuerza se propaga hacia ms o menos celdas. Posteriormente hay que recorrer todas las celdas e ir creando los actores, compuestos por una o ms formas, resultantes de la colisin.
Subdivisin completa de un modelo.

6.5.5.- RESULTADO FINAL


El resultado final es bastante bueno. El objeto al colisionar se rompe en pedazos, pero solo en la zona de la colisin. Los pedazos que se separan tienen algunos errores en la geometra, ya que era necesario dedicarle mucho mas tiempo a construir bien los trozos: faltan algunas caras o algunos tringulos son errneos. Al producirse una colisin, la fuerza se propaga a travs de las partes del modelo ms cercanas al punto de impacto y, dependiendo de la magnitud de esta fuerza, se separan ms o menos trozos del modelo.

- Pgina 64 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Las desventajas de utilizar este mtodo son obvias: en el preproceso deben calcularse todas las piezas, y si el modelo es grande o queremos subdividirlo en partes pequeas, vamos a tener que hacer gran cantidad de clculos para generar las subdivisiones. Esto tambin repercute en las colisiones, ya que la fuerza propagada a travs de un objeto, si es suficientemente grande, puede llegar a todas las piezas del modelo. Y la creacin de todos los actores

correspondientes a las piezas puede llegar a ser tambien muy costosa.


Modelo original sin romper

Estas herramientas del motor estan pensadas para generar objetos que se puedan romper en pocas piezas, o para cargar trozos precalculados de un editor de modelos. En cualquier caso, se deben almacenar todas las piezas en la memoria de ejecucin y procesarlas en cada colisin.

Bola colisionando con el modelo y rompindolo en pedazos.

- Pgina 65 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.6.- ROTURA DE OBJETOS 2D 6.6.1.- OBJETIVO


En la anterior simulacin he podido romper un modelo en 3D en varios pedazos (precalculados antes de generar el objeto original sin romper). Los trozos, aunque podan ser aleatorios, tenan tamaos parecidos y se rompan de la misma forma casi siempre. Ahora pretendo crear un objeto que se rompa en tiempo de ejecucin. Se podr disparar al objeto y se calcular qu trozos se van a generar. Tambin, cuando caigan al suelo o choquen entre ellos, si lo hacen con fuerza suficiente, se rompern. Debido a la dificultad que supone y para simplificar el problema, solo voy a simular este efecto para objetos que tengan dos dimensiones. Estos objetos pueden tener volumen (por ejemplo una baldosa), pero a efectos de clculo sern objetos 2D.

6.6.2.- IDEA
Al ser objetos 2D, el problema se reduce a calcular una rotura de un conjunto de vrtices y aristas en un plano. Para un punto de impacto, trazar un crculo de un radio definido entorno al punto y romper el objeto con la forma de ese crculo. Habr casos en que queden vrtices y aristas en el interior del crculo, que alguna arista se vea cortada por el contorno del crculo, o que no haya ningn vrtice interior a ste. En todos los casos deber calcular los puntos de rotura y luego unirlos entre ellos creando las partes en que queda roto el objeto. Pero antes veamos algunos casos y soluciones: a la izquierda aparece la figura que se ha de romper en negro, el punto de impacto en azul y el crculo de rotura en rojo; a la derecha est dibujada la solucin de los trozos resultantes, con los vrtices interiores al crculo en naranja, los puntos de rotura en las aristas originales en verde y los puntos de rotura que se generan en el contorno del crculo en azul. En este caso se debe coger el vrtice que queda dentro del tringulo, los dos puntos de interseccin de las aristas que salen de este vrtice con el crculo de rotura y entre ellos crear varios puntos por el contorno del crculo. Aqu quedan dos vrtices contiguos dentro del crculo de rotura, as que no se ha de crear ningn punto en la arista que los une, pero s en las otras dos. - Pgina 66 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Ningn vrtice queda dentro del crculo de rotura as que se comprueba si alguna arista entra y vuelve a salir por el crculo. Al encontrarla, se crean los puntos en el contorno del crculo por dentro de la figura. Y algn caso un poco ms complicado en el que el nmero de trozos resultantes sern ms que dos, ya que la zona que queda dentro del crculo de rotura acta de puente entre las dos partes de fuera.

Finalmente, para que los trozos que se rompen no tengan forma tan circular, podemos desplazar de forma aleatoria los puntos que creamos entre las aristas que cortan el borde del crculo de rotura. Adems, haciendo esto los objetos nunca se rompern de la misma forma. Sin embargo esto puede acabar produciendo algunos errores ya que puede crearse una
Desplazamiento aleatorio de los puntos del contorno del crculo.

arista entre dos de estos puntos que corte a otra que ya tena el modelo.

Para poder crear los disparos, creo una recta y al pulsar el botn de disparar, miro si corta el plano del objeto y si es as, compruebo si el punto de corte cae dentro o fuera de la figura, que estar compuesta por tringulos, por lo que solo debe comprobarse si hay interseccin entre uno de estos tringulos y la recta. Si cae dentro, ejecuto el algoritmo que partir la figura en trozos. Como tambin quiero que los objetos se rompan al chocar entre ellos o contra el suelo, deber comprobar todas las colisiones que se sucedan entre los actores rompibles, y entre uno rompible y otro que no lo sea (como el suelo).

6.6.3.- HERRAMIENTAS USADAS


Este actor tendr una forma aleatoria as que voy a utilizar la forma del motor NxConvexMesh (que aunque no sea convexa, los errores producidos no son poco importantes). Antes debo crear la estructura interna de la forma as que utilizare la herramienta de cocinado que proporciona el motor. - Pgina 67 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

A este proceso de cocinado se le deben definir una lista de vrtices y una lista de tringulos, que sern grupos de tres ndices a la lista de vrtices. Como la forma que tendr ser aleatoria, usare el teselizador que proporciona la librera Glu de OpenGL que convierte un conjunto de puntos aleatorios contiguos en una malla de tringulos. Para obtener las colisiones entre los objetos y procesarlas, utilizar la funcin de UserReports y para cada par de actores en los que como mnimo uno de los dos sea rompible, utilizar la funcin
setActorPairFlags

pasando como parmetro NX_NOTIFY_ON_START_TOUCH para que el inicio de colisin

entre ellos sea procesado. Hay que tener en cuenta de nuevo que todas las modificaciones que se quiera hacer a la escena, se han de hacer cuando no se estn calculando las fsicas del siguiente frame. Entonces, una colisin que genere una rotura, deber ser guardada y procesada fuera de este periodo de tiempo. Para dividir el objeto en varios, deberemos eliminar el actor de la forma original de la escena y reemplazarlo por varios actores, uno para cada parte en que se haya dividido.

6.6.4.- IMPLEMENTACIN
Para crear un objeto 2D rompible, se deber configurar un descriptor, con los siguientes campos:
POSICIN: Posicin global del objeto. PESO:

Peso del objeto. Cuando se rompa, el peso de cada parte resultante ser una aproximacin que obtendr de dividir el peso original por el nmero de trozos que se crean.

LISTA_VRTICES:

Listado de puntos contiguos (x,y,z) en el mismo plano que unidos en el sentido de las agujas del reloj por aristas definen el borde del polgono que forma la cara del objeto. Ver la imagen contigua como ejemplo.

GROSOR: Grosor del objeto 2D DIRECCIN_GROSOR: Es un vector unitario que indica hacia qu direccin tiene volumen el objeto 2D,

dependiendo de en qu plano se han especificado los vrtices.


RADIO_ROTURA: Radio del crculo de rotura.

- Pgina 68 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Primero se debe crear a partir de los puntos del plano de la figura, la forma en 3D de la baldosa. Para crear la cara de delante utilizo el teselizador de Glu pasando la lista de puntos. Triangula la figura y devuelvo una lista de tringulos que son tres ndices a la lista de vrtices T(v1,v2,v3). Para la cara de detrs creo nuevos vrtices resultado de desplazar los originales en la direccin del grosor, es decir
Vi=Vi-

GROSOR*DIRECCIN_GROSOR.

Para que los

tringulos se definan correctamente debo invertir dos de sus tres ndices a vrtices,
Ti(v1,v2,v3)=Ti(v2,v1,v3) , porque en la Creacin de la figura 3D a partir del polgono 2D usando el teselizador y generando los dems tringulos.

visualizacin solo dibujo los tringulos que son caras frontales.

Y para generar los lados de la baldosa cojo dos puntos consecutivos de la cara de delante y sus correspondientes de la cara de detrs y creo dos tringulos. Esto es crear los tringulos (vi,vi,vi+1) y
(vi,vi+1,vi+1) .

Una vez tengo la figura 3D la he de cocinar con la herramienta que proporciona el motor, creando un actor con una forma NxConvexMesh de la forma que he explicado en el apartado 5.5 . Cuando se dispare a una baldosa, se pasar como parmetro el vector director del rayo y un punto de la recta que lo describe. Tambin se pasar un puntero a una lista de trozos, que se llenar en caso de que el objeto se rompa, y devolver un booleano diciendo si ha habido rotura o no. Tengo que saber si el rayo interseca con la figura, es decir comprobar si interseca con alguno de los tringulos de sta (solo lo miro para los de la cara delantera). El problema es que el rayo nos viene dado en coordenadas del eje de la escena, que no es el mismo que el de la figura (el motor en cada iteracin de clculo modifica la matriz de transformacin del actor, pero no las coordenadas de los vrtices que la componen). Se tiene que situar el rayo en el sistema de coordenadas del actor. Para eso se cogen dos puntos de la recta y se multiplican por la matriz 4x4 de transformacin del actor obtenida a getGlobalPose (hay que aadir un 0 como cuarta componente a los puntos de la recta para poder multiplicarla con la matriz 4x4). Cuando ya se tiene el rayo en el eje de coordenadas del actor, necesitamos una funcin que compruebe si hay interseccin de una recta con un tringulo. Si ha habido, llamaremos a la funcin que romper el objeto pasando como parmetro el punto de interseccin.

- Pgina 69 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

funcin romperPorRayo(baldosa, pRayo, vRayo, sal lista_trozos) devuelve Booleano pRayo2 = pRayo+vRayo; pRayoActor = (pRayo.x, pRayo.y, pRayo.z,0) * baldosa.actor.getGlobalPose(); pRayoActor2 = (pRayo2.x, pRayo2.y, pRayo2.z,0) * baldosa.actor.getGlobalPose(); vRayoActor = pRayoActor2-pRayoActor; si interseccin(baldosa, pRayoActor, vRayoActor, pInterseccin) entonces devolver romper(baldosa,pInterseccin, lista_trozos); sino devolver falso; fsi ffuncin

El caso de la rotura por colisin es ms sencillo ya que nos devuelve el punto de colisin y solo se ha de llamar a la funcin romper pasando como parmetro el mismo punto. Paso a explicar el proceso de romper la baldosa en trozos. No aadir pseudocdigo para no alargar demasiado esta seccin, pero pondr un ejemplo en cada paso a seguir. Los parmetros de la funcin romper son: la baldosa (que solo me interesa la lista de vrtices), el punto (que sabemos que es interior a la forma de la baldosa) y la lista de trozos que rellenaremos con los nuevos actores que se crearn. La funcin devolver cierto si ha habido rotura.
funcin romper (baldosa, pImpacto, sal lista_trozos) devuelve Booleano

Crear una lista de PuntoRotura, que estn formados por un tipo (o color en la figura), un vrtice y un
ndice

a vrtice. Habr tres tipos de puntos de rotura: generados a partir de un vrtice (naranjas) o

generados a partir de una arista, que podrn ser de Entrada (verdes) o Salida (lilas). Primero se aade a la lista los vrtices interiores, comprobando que la distancia al punto de impacto sea menor o igual al radio. En el ejemplo encontramos los puntos 1 y 2 en naranja. Si no hubisemos encontrado ninguno, devolveramos falso ya que o bien el crculo es ms grande que toda la figura y no queremos que el objeto se rompa ms, o el crculo esta en el interior de la figura y esto es un caso que no tratar para simplificar el problema. Ahora se aaden los puntos del contorno del crculo de rotura por los que pasa una arista. Para hacer esto de manera que queden ordenados los puntos en la lista listaPuntosRotura, se debe coger cada uno de los elementos que hemos aadido a la lista de putos de rotura y mirar su situacin. Se generarn puntos de Salida (color lila) y puntos de Entrada (color verde).

- Pgina 70 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Si el ndice del punto de rotura actual no es contiguo al del anterior, quiere decir que la arista anterior al vrtice pasa a travs del crculo y se debe encontrar el punto de interseccin que ser de Entrada. En el ejemplo, el punto 1, que tiene ndice D, tiene como punto de rotura anterior el 2, con ndice E, por lo que la arista DC ha de pasar a travs del contorno).

Si el ndice del punto de rotura actual es contiguo al del siguiente, quiere decir que la arista entre los dos es interior al crculo y no se debe hacer nada. En el ejemplo, el punto 1, que tiene ndice D, tiene como punto de rotura siguiente el 2, con ndice E, por lo que la arista DE es interior al crculo.

Si el ndice del punto de rotura actual no es contiguo al del siguiente, quiere decir que hay una arista que pasa a travs del crculo, y se debe encontrar el punto de interseccin que ser de Salida. Adems se debern comprobar todas las siguientes aristas hasta la que tenga el vrtice correspondiente al siguiente punto de rotura (sin incluirla), ya que puede ser que una arista entre y salga del crculo. Si es as, se generarn dos puntos ms (uno de Entrada y otro de Salida). En el ejemplo, el punto 2, que tiene ndice E, tiene como siguiente punto de rotura el 1 que tiene ndice D, por lo que la arista EA pasa a travs del contorno del crculo. Encontramos el punto 3 de Salida y comprobamos las siguientes aristas hasta la CD, es decir: CB y BC. Utilizando una funcin que nos dice si un segmento corta un crculo, vemos que la arista AB corta por los puntos 4 (de Entrada) y 5 (de Salida).

En la figura, entre el punto 5 y 6 hay mucho espacio como para solo crear una arista, as que se debera rellenar con varios puntos intermedios. Haremos esto cada vez que encontremos un punto de rotura generado a partir de una arista y sea de Salida (color lila). En el caso del punto 3, como la distancia es mnima, no har falta crear ningn punto ms.

- Pgina 71 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Al crear estos puntos, y para dar un mejor efecto de rotura, se pueden desplazar aleatoriamente. Ya solo queda llamar a la funcin creadora tantas veces como fragmentos tengamos para que defina la forma en la escena y cree el actor. La lista de vrtices de la pieza central que ha definido el crculo de rotura es igual a la lista de puntos de rotura, que ya estn en el orden de las agujas del reloj. Para crear las dems piezas se sigue el siguiente mecanismo: si el punto de rotura i es de una arista y de Salida, se crea una nueva pieza con los siguientes puntos (en este orden y poniendo de ejemplo el punto 5): 1. Vrtice del punto de rotura i, es decir (x5,y5,z5). 2. Vrtices de la figura original desde el extremo de la arista i hasta el inicio de la arista del punto de rotura de Entrada (verde), en el ejemplo B y C. 3. Vrtice del siguiente punto de rotura de Entrada, es decir (x6,y6,z6). 4. Puntos de rotura, en orden inverso entre el punto de rotura i y el siguiente punto de Entrada, es decir entre 5 y 6, que son (x5,y5,z5) y (x5,y5,z5). De esta forma declaramos todos actores en la escena, sin olvidarnos de eliminar el original que acabamos de romper y ya no debe aparecer. Hay que tener en cuenta la posicin y la orientacin de la baldosa en el momento de la rotura, ya que los fragmentos debern tener la misma posicin y orientacin (aunque distinta posicin relativa). La velocidad tambin tiene que parecer que sea la del mismo objeto que se ha roto. Para facilitar el procesado de todas las funciones asociadas a las baldosas, he creado un gestor que contiene una lista de baldosas. Las operaciones de rotura por rayo pasan a travs de este gestor, que llama para cada baldosa a la funcin correspondiente. Cada vez que se crea una baldosa, se ha de decir al motor que cuando colisione con otro objeto informe llamando a la funcin de UserReports. Como la funcin setActorPairFlags acta entre pares de objetos, se deber llamar a esta funcin tantas veces como baldosas haya en la lista del gestor. En la funcin de informe de contactos, cuando nos llega una pareja, debemos mirar la velocidad que llevaban los dos para decidir si va a haber rotura o no. Todas las colisiones que se han computado en el clculo de fsicas sern guardadas en otra lista del gestor y tratadas cuando el motor acabe. Si ha habido dos colisiones en una misma baldosa y las dos generaran roturas, solo trato la primera.

- Pgina 72 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

6.6.5.- RESULTADO FINAL


La rotura de un objeto 2D grande es satisfactoria. Donde disparamos se crea un trozo que si acta de puente entre dos partes de la forma, sta se rompe creando como mnimo tres nuevas partes. Adems tambin se rompe si en el crculo de rotura no entra ningn vrtice, creando un nuevo trozo a partir de la arista y el cuerpo del objeto. El nico caso en el que no se rompe es el que ningn vrtice se encuentra en el crculo de rotura ni ninguna arista pasa por l. Podramos crear un agujero en el objeto, pero entonces no seran tiles las estructuras y

procedimientos que he utilizado para el clculo de la rotura. Una solucin a este problema sera la de crear un trozo donde ira el agujero, pero rompiendo la baldosa de manera que se cree un camino hasta ese agujero. De todas formas pienso que no vale tanto la pena dedicarle mucho ms
Rotura de un objeto 2D en todos los casos: que el crculo de rotura contenga vrtices, contenga solo una arista, acte de puente, etc...

tiempo a este caso si los objetos que se crean tienden a ser pequeos.

Se producen algunos errores en la ejecucin del algoritmo que ocurren en muy baja frecuencia, pero son fciles de detectar y para no dedicarle mucho ms tiempo a tratarlos todos, si se encuentra uno de estos errores, no se rompe la baldosa. Otro error es el que se produce al mover aleatoriamente los vrtices que se generan entre dos puntos de rotura y que haya dos aristas que se cortan y el teselizador, se crea las caras de forma errnea. El motor tambin produce algunos errores de colisin que se deben descartar para no producir ms errores. Parece que crear un actor nuevo en la escena en el espacio donde haba otros actores genera colisiones que no deberan generarse. - Pgina 73 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

La aplicacin de una textura es bastante sencilla y la representacin mejora un poco. He creado una pared de baldosas de 2x1 para probar este efecto.

Comparacin de rotura de una baldosa de 2x1 sin texturizar y texturizada.

El proceso es bastante eficiente, o todo lo eficiente que puede ser. Es posible tener muchas baldosas rompindose a la vez, ya sea porque les han disparado o por colisionar con el suelo al caer o con otras baldosas, como es el caso de la imagen de abajo donde en la ejecucin no se ha apreciado ralentizacin.

Resultado final con varias baldosas rompindose a la vez.

- Pgina 74 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

7.- CONCLUSIN
Una motivacin u objetivo de realizar este proyecto era aprender a usar un motor fsico para integrarlo en una aplicacin. El motor escogido, PhysX de AGEIA, tiene las suficientes funcionalidades y herramientas para realizar bastantes efectos fsicos, adems de los que lleva implementados en la distribucin. Puedo decir que s usar casi por completo la versin 2.7, a falta de conocer algunas opciones ms para el cocinado de mallas, el uso de heightmaps, las peculiaridades de algunas uniones y configuraciones especficas para el hardware de PS3 o Xbox360. Por lo dems, puedo crear efectos fsicos derivados de los ya existentes, con mejor o peor resultado (de animacin o de eficiencia). Mientras estaba realizando el proyecto, NVIDIA adquiri AGEIA. En este lapso de tiempo han aparecido nuevas versiones que tal vez mejoren algunos de los puntos dbiles del motor (van por la 2.8.X) y se han empezado a incorporar procesadores de fsicas (solo aprovechables para PhysX) en las tarjetas grficas de NVIDIA. Adems se comercializa el cdigo fuente a un precio de 50000$. Otro objetivo era, una vez habiendo aprendido el funcionamiento, realizar efectos fsicos usando los componentes disponibles en el motor: actores, uniones, asignacin de fuerzas, creacin de mallas (cocinado), etc. Algunos de estos efectos fsicos han dado resultados positivos pero en otros se producan errores inesperados, tal vez por la falta de herramientas especficas. El motor no es sencillo de usar, y se deben configurar muchos parmetros antes de poder crear, por ejemplo, un actor. Esto proporciona un mayor abanico de opciones para que los objetos realicen el comportamiento adecuado, pero por otro lado a veces es muy difcil configurar todos los parmetros a partir de las especificaciones de un objeto que se quiere crear. Un ejemplo de esto han sido las simulaciones de ropa (en el primer mtodo) y de objetos elsticos, en los que la configuracin de todos los campos se hace muy difcil si se quieren generalizar todos los casos. Ambas simulaciones estn relacionadas con la creacin de uniones, y posiblemente este sera uno de los puntos dbiles del motor pese a disponer de muchos tipos. Otra desventaja es la creacin de actores formados por mallas de tringulos. El motor, a partir de una entrada que puede ser una lista de vrtices y una lista de tringulos (ndices a vrtices), debe hacer un preproceso para generar la estructura interna de ese modelo en el motor, que obviamente se desconoce. Si se pudiera declarar directamente la estructura que debe manejar el motor en los clculos, se ganara mucho tiempo en el caso de que se deban crear actores con mallas en tiempo de ejecucin. PhysX sin duda es el motor gratuito ms eficiente y uno de los que tiene ms funcionalidades. Sin embargo, el no disponer del cdigo fuente y no poder acceder a las funciones bsicas de clculo limita la creacin de - Pgina 75 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

efectos ms complejos. Hay otros motores gratuitos que son de cdigo abierto, pero no ofrecen tantas herramientas como este. El motor Tokamak es una buena alternativa si se quiere disponer del cdigo fuente y obtener rendimientos parecidos. Actualmente el motor que ms ha evolucionado estando muy por encima de los dems es el conocido como Havok (por supuesto, de pago). Este motor incluye el llamado Digital Molecular Matter, que puede simular roturas y deformaciones de modelos en tiempo de ejecucin, a partir del material del que est formado el objeto. Se puede simular madera que se rompe y se astilla dependiendo del grosor o la dureza que tenga, objetos en 3D de cristal que se rompe en pedazos, metal que se dobla y objetos hechos de un material orgnico que se deforman. Tambin puede calcular roturas en tiempo de ejecucin de modelos en 3D que afectan a todo su cuerpo: si un objeto rompe gran parte de la zona inferior del modelo, es posible que ste no pueda aguantar el peso de la zona superior y ello provoque un derrumbamiento. A parte se estn usando otras tcnicas para los Ragdolls (cuerpos que se utilizan para simular la cada de un personaje muerto). Con Euphoria, de NaturalMotion, dejan de usarse nicamente para simular cuerpos muertos. Se crea una animacin del personaje de forma dinmica, en tiempo de ejecucin, combinando inteligencia artificial con el comportamiento biomecnico que tienen las personas y el uso de fsicas. Da como resultado que el personaje pueda cogerse de bordes en la escena para no caer, esquivar obstculos o intentar no hacerse dao al caer rodando; todo ello sin aplicar ninguna animacin pre-calculada.
Digital Molecular Matter de Havok

Euphoria, de NaturalMotion

- Pgina 76 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

Se est avanzando mucho en este campo pero el problema sigue siendo la gran cantidad de clculos que se deben hacer para simular estos efectos. Por ejemplo, para la simulacin de agua es necesario crear miles de partculas (si se quiere un volumen algo notable de agua) y en cada frame generar una malla que englobe todas estas partculas. Hacer esto en tiempo real es imposible con solo un procesador actual. Tambin es posible que queramos
Clculo de fsicas en la GPU. Caja desplazndose a travs de un milln de partculas.

simular muchas colisiones a la vez y siempre estaremos limitados por la capacidad de la

CPU. Una solucin a esto era implementar el motor fsico en la GPU, que tiene una potencia de clculo mucho mayor que la CPU (hasta 25 veces mayor en algunos casos). Para Havok empezaron a implementar el clculo de fsicas en la GPU y los resultados fueron bastante buenos. Pero si se utiliza el procesador grfico para otros clculos, quien realizar los asociados a la visualizacin de la escena? Por eso parece que ahora se est tendiendo a incorporar un procesador de fsicas en la GPU, pero aparte, no en el mismo pipeline donde se realizan los clculos de visualizacin. El uso de un motor fsico en una aplicacin da ms dinamismo a las escenas. Son clculos costosos pero que hacen mejorar mucho la interaccin con el entorno que se est representando y generan efectos bastante impresionantes. Estamos muy limitados por los procesadores de clculo y los motores simulan solo un subconjunto de efectos, cada vez mayor, pero an queda mucho por avanzar y perfeccionar.

- Pgina 77 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

- Pgina 78 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

8.- BIBLIOGRAFIA
AGEIA TECHNOLOGIES INC, Documentacin del SDK de PhysX, versin 2.7 ANDJAR, C., BRUNET, P., FAIRN, M., NAVAZO, I., VINACUA, A. Informtica Grfica. Un enfocament Multimdia (Apunts de l'assignatura en CD)., CPET, 2002.

- Pgina 79 -

Simulacin de efectos Fsicos

scar Llorens Maldonado

- Pgina 80 -

S-ar putea să vă placă și