Panda3D • DESARROLLO
Mundos 3D con Python y Panda3D
CAMPO DE
JUEGO VIRTUAL
Muchos motores libres para juegos están disponibles para usuarios de Linux, pero la programación con ellos
suele ser poco intuitiva. Panda3D es un motor muy fácil de usar y accesible para recién llegados, sin dejar de
ser lo bastante potente para los profesionales de los estudios Disney. POR OLIVER FROMMEL
L
os inventores del ratón Mickey y C++ garantiza que el resultado será lo último parámetro, Makepanda hará una
el pato Donald ya habían montado bastante fino. Los programadores que lista con las diferentes opciones de insta-
unos cuantos parques temáticos confíen en Panda3D podrán acceder a su lación. El archivo doc/INSTALL-MK
en la vida real para cuando decidieron infraestructura vía Python, mucho más incluye más detalles.
aventurarse en el mundo del entreteni- intuitivo y fácil de usar que C++. Los mundos virtuales básicamente
miento virtual de Internet. En el año consisten en elementos geométricos sim-
2000, los programadores de los Disney Comenzando ples que resultan más verosímiles
VR Studios empezaron a crear una apli- El motor Panda es fácil de instalar, siem- cuando se les aplican ciertas texturas (es
cación de software para ayudarse a pre que tengas una distribución basada decir, imágenes de objetos reales). El
desarrollar su propio juego online en 3d: en RPM o DPKG. El paquete Debian de la realismo no siempre es el objetivo: por
Toontown. página del proyecto también es fácil con
El resultado de este trabajo es el último Ubuntu. Todo lo que hizo falta Listado 1: Un sencillo
Panda3D [1], un motor de juego que para tener Panda funcionando fue un
soporta el lenguaje de programación link simbólico de /usr/lib/[Link].0.9.8 script de Panda
Python. En 2002 Disney publicó el a /usr/lib/[Link].0.9.7. En los demás 01 import
paquete bajo una licencia libre para faci- casos tendrás que instalar Panda a partir [Link]
litar la contribución de las universidades del código fuente. Aunque esto no tiene 02
al proyecto. mucha importancia, se lleva un rato, y 03 panda =
Un motor de juego como Panda3D hay un buen número de dependencias en [Link](“models/panda
saca el trabajo repetitivo (como cargar paquetes de desarrollador que cubrir ”)
personajes y sonidos, control básico del (Open SSL y LibTIFF, por ejemplo). Cam- 04 [Link](render)
movimiento y algunas otras cosas) de las bia el directorio a panda3d-1.2.3 para la 05 [Link](0,30,-5)
manos del programador. El hecho de que instalación, y arranca makepanda/make- 06
estas funciones están programadas bajo [Link] —everything. Si se te olvida el 07 run()
[Link]- [Link] Número 25 49
DESARROLLO • Panda3D
informática, se trata de un gráfico que
contiene y jerarquiza los objetos mostra-
dos en escena. En cualquier caso, toda
Listado 2: Moviendo la
cámara
01 import sys
02 import
[Link]
03 from [Link] import Actor
04 from [Link] import
DirectObject
05
06 class
Game([Link]
):
07 angle = 0
Figura 1: Toontown, el juego online de Disney, se implementó usando el motor libre Panda3D.
08 distance = 0
09 def __init__(self):
ejemplo, Toontown emplea un estilo de ruta de instalación por defecto de estos
10 [Link] =
personajes cercano al cómic (ver Imagen archivos es /usr/share/panda3d/models.
[Link](“models/panda
1), aunque esto no influye para nada en Un script de Panda3D extremadamente
”)
la distinción entre geometría y propieda- simple carga y muestra un modelo (Lis-
11 [Link](render)
des de la superficie en un modelo 3D. tado 1). El resultado de esto se muestra
12 [Link](0, 1000,
Los modelos suelen estar dibujados en en la Figura 3.
-100)
programas especialistas para, posterior- El script comienza cargando el modelo
13 [Link](0.5, 0.5,
mente, convertirlos a un formato que un básico de Pyhon [Link]-
0.5)
motor 3D pueda manejar. Hay plugins de Start, lo cual vuelve disponible un carga-
14
exportación para el formato que usa dor de objetos. El objeto provee el load-
15 [Link](‘escape’ ,
Panda3D en herramientas profesionales Model que finalmente cargará el modelo.
[Link] )
de Windows como Maya, 3dStudio Max Como puedes ver, aquí dejo fuera la
16 [Link](‘arrow_right’,
y Softimage XS. Milkshape (un programa extensión .egg, ya que el motor no nece-
[Link], [1])
shareware) ofrece una útil alternativa sita la extensión para encontrar lo que
17 [Link](‘arrow_left’,
para los usuarios caseros: muchos lo uti- busca.
[Link], [-1])
lizan para editar modelos de Quake. La función de carga devuelve un
18 [Link](‘arrow_down’,
Los usuarios de Linux no tienen objeto Python que puede usarse como
[Link], [1])
mucha elección aquí, ya que Blender 3D referencia del modelo cargado a lo largo
19 [Link](‘arrow_up’,
es la única opción a mano. Lamentable- del programa. El setPos() cambia la posi-
[Link], [-1])
mente, no soporta el formato de ción del modelo en el espacio 3D. La pri-
20
Panda3D (también conocido como Egg) mera variable representa las coordena-
21 [Link]()
por defecto. Para añadir soporte para das X, seguidas por Y y Z. De manera
22 [Link](10000)
Egg, tendrás que instalar uno de los tres similar, setScale() escala el objeto en tres
23
plugins que existen para Blender, y todos dimensiones: en el sistema de coordena-
24 def spinCamera(self,
ellos tienen limitaciones. El más maduro das de Panda, X puntos a la derecha, Z
direction):
de todos es Chicken [2], del desarrolla- hacia arriba e Y hacia dentro de la panta-
25 [Link] += direction * 1.0
dor de Peruvia, Daniel Amthauer. Mien- lla, desde el punto de vista del usuario.
26 [Link](self.
tras se escribía este artículo, Daniel Ahora puedes usar el ratón para rotar,
angle, 0, 0)
lanzó la versión mejorada 1.0a, que mover y escalar el modelo. Prueba los
27
ahora incluye documentación muy útil tres botones. La rotación puede parecer
28 def zoomCamera(self,
(Imagen 2). un poco extraña al principio; la razón
direction):
Para instalar Chicken, descomprime el para ello es que el eje de rotación queda
29 [Link] += direction *
archivo zip en tu directorio .blender/ fuera del modelo.
10.0
scripts. Ahora lanza Blender; deberías
30 [Link](0,
encontrar la opción de exportar a Egg en El Árbol de la Escena
[Link], 0)
File | Export | Chicken. No he explicado todavía la Línea 4 del
31
Listado 1. Se apoya en un concepto
32 game = Game()
Creando un Mundo básico de los gráficos tridimensionales
33 run()
Los archivos de ejemplo te irán bien para por ordenador: los gráficos de escena.
tus primeros pasos en el motor 3D; la Desde el punto de vista de la ciencia
50 Número 25 [Link]- [Link]
Panda3D • DESARROLLO
yen su posición en la En el Listado 2, el único parámetro
escena, el ángulo de que la cámara puede definir es la direc-
uno o de los tres ejes, ción del movimiento (1 y -1). En cual-
la distancia del foco y quier caso, aún hace falta anotar el lis-
otras muchas cosas. tado con corchetes. El disableMouse()
El ejemplo en el Lis- (“Desactivar ratón”) con el método Init
tado 2 muestra cómo apaga el movimiento automático de la
mover la cámara para cámara. La última instrucción, [Link]-
cambiar la visión del Lens, utiliza la lente para definir el punto
modelo en uso en de superposición (a partir del cual
pantalla. Panda3D ocultará las partes de los obje-
Al mismo tiempo, tos que correspondan) a un valor de
Figura 2: El plugin Chicken de Blender exporta modelos al formato el ejemplo demuestra 10.000. Es igual de fácil usar la lente para
Egg de Panda. cómo Panda3D pro- modificar el foco, por ejemplo.
cesa las teclas que el Las funciones para mover y rotar la
esta teoría no viene al caso para este usuario pulsa. Dado que es más sencillo cámara se controlan con facilidad. Angle
asunto; aún así, trata de imaginarte un de manejar si tu programa Panda está y distance (“ángulo” y “distancia”) se
árbol de la escena. basado en una clase que provea métodos multiplican por un factor de corrección,
El modelo de un humano puede repre- de teclado adecuados, este ejemplo está y entonces se añaden (o se restan,
sentarse en un árbol de escena de tal orientado a objetos, al contrario que el dependiendo de la dirección) al valor
modo que el trasero está en la raíz del anterior. actual. setHpr() y setPos() asigna el valor
árbol, los brazos y piernas son las ramas, Para que las cosas sigan siendo senci- resultante a la cámara por defecto (a la
y pies y manos son brotes. La ventaja de llas, la función completa reside en la cual puedes referirte en tus script como
este sistema es que los modelos con clase Game, dentro del objeto DirectOb- [Link]).
estructuras jerárquicas son más fáciles [Link] de Panda (Línea 6). Para
de mover en un código. En nuestro ejem- que esto pueda ocurrir, la Línea 4 Movimiento
plo, si el código de Python mueve el tra- importa el módulo requerido. El código, En nuestro último ejemplo, movía-
sero, los miembros del modelo humano que previamente se ha listado al final del mos la cámara alrededor del oso
se moverán, siguiéndolo, de manera script, mueve ahora la clase de construc- panda, pero el oso en sí estaba
automática. ción de Game __init__. A partir de este quieto. Se puede añadir más acción
El mismo principio se aplica a los atri- momento, cuando un nuevo objeto con dos opciones que se complemen-
butos de renderizado, que describen la Game sea creado mediante una llamada tan a la perfección entre sí: mover el
apariencia de la superficie del modelo. a Game() en la línea 32, Python recurrirá modelo a través de la escena y
Por defecto, los elementos más abajo en automáticamente al constructor. moverlo solo.
el árbol heredan las propiedades de los Tras cargar, posicionar y escalar el
nodos de que proceden. Por ejemplo, te modelo, necesitaremos algunas instruc- Listado 3: Trabajo con
basta con definir el color del trasero para ciones para hacer que funcione la
que se aplique el mismo color a los entrada de teclado. El método accept()
fases de movimiento
01 def __init__(self):
miembros. Siempre puedes cambiar la que ofrece el DirectObject se preocupa de
02 [Link] =
apariencia y la subordinación de los esto. Como la clase Game se deriva de
[Link](“models/panda-mode
nodos como tú quieras. aquí, el método es una instancia que
l”,{“walk”:”models/panda-walk4
Para asegurarte de que Panda3D mos- puede ser direccionada mediante la
”})
trará los modelos que cargues, debes misma palabra clave. El primer paráme-
03 ...
insertarlos en la posición bajo el objeto tro que solicita es una línea con el nom-
04 [Link]. reparentTo(render)
de renderizado en el árbol de la escena. bre de la tecla que está pulsada. A esto le
05 ...
Y exactamente eso es lo que hace la sigue la función que queremos que
06
Línea 4 del Listado 1. Al final del script Panda3D ejecute cuando el usuario pre-
07 [Link](‘a’, self.
puedes ver una instrucción run(), que sione la tecla. Además, la línea 15 apaga
animate_start)
comienza el bucle de evento; es un bucle el programa cuando se pulse [Esc].
08 [Link](‘s’, self.
infinito en el cual el programa funciona,
actualiza la pantalla, procesa las teclas Cámara animate_stop)
09 ...
pulsadas, etc. Las siguientes cuatro líneas encargan el
10
movimiento de la cámara a los cursores. Las
Teclas y claves flechas izquierda y derecha utilizan el spin- 11 def animate_start(self):
12 [Link](“walk”)
La cámara muestra la apariencia de una Camera() (girar la cámara); arriba y abajo,
13
escena en pantalla. Por supuesto es un zoomCamera() (acercar o alejar el punto de
14 def animate_stop(self):
objeto virtual como todos los demás, vista). Cuando esta función pasa gracias al
15 [Link]()
pero de todos modos tiene propiedades accept(), Panda puede añadir unos cuantos
similares a una cámara real. Éstas inclu- parámetros más para poder realizarla.
[Link]- [Link] Número 25 51
DESARROLLO • Panda3D
Figura 3: Panda3D mostrando un modelo terminado, conseguido con Figura 4: Rotación y movimiento del panda. Una sola línea de código
sólo 5 líneas de Python (Listado 1). lanza el texto de ayuda (Listado 4).
Algunos movimientos, como andar, saltar, El primer parámetro del hprInterval espe- GUI que permiten crear menús también
etc., se crean mejor en un modelador 3D cifica la duración del movimiento en segun- están disponibles.
como Blender. Deberías usarlo para diseñar dos. Éste va seguido por el punto final y el Panda3D tiene, además, un shader (fun-
las fases del movimiento y asignar armaduras principio del movimiento; en este caso, el ción para dibujar sombras) que se ha vuelto
al modelo para representar los huesos de un ángulo de rotación es de 360º. Además, el bastante popular, aunque de hecho sólo
ser vivo. Tras hacer esto puedes animarlo a Listado 4 muestra, en la función create- soporte el lenguaje de Nvidia Cg (preferible al
través de puntos de movimiento individuales, menu(), cómo mostrar un texto de ayuda standard de OpenGL, GLSL). Por desgracia,
igual que si fuera una marioneta. con una sencilla línea de código (Figura 4). presenta un importante fallo para los fans del
Tras exportar tus secuencias con Chicken, Las tareas son otra de las características software libre: su motor de sonido interno.
carga las fases de movimiento para mejorar el de Panda que ahorran trabajo al programa- Panda3D utiliza FMOD, que no está disponi-
modelo básico. Panda3D te ofrece la clase dor. El motor ejecutará cualquier tarea que ble bajo este tipo de licencia. Por otro lado,
Actor con este propósito; esta clase reacciona registres en el gestor general de tareas de Panda3D trabaja bien con otros frameworks;
más o menos como un modelo normal, pero objetos, taskMgr; tanto da que se deba eje- por ejemplo, puedes reemplazar la función de
procesa, además, fases de movimiento. El Lis- cutar en el momento o posponerla utili- sonido con el paquete libre Pygame.
tado 3 muestra un extracto de un programa zando el comando doMethodLater().
que utiliza esta posibilidad. Sólo mencionaré un par de posibilida- Mejora Garantizada
El primer parámetro de Actor, que especi- des más de Panda; todas ellas son bas- Si prefieres no usar lenguajes compilados
fica el modelo básico, es seguido por un dic- tante complejas. Por ejemplo, el pro- como C++, podrás construir modelos 3D
cionario Python cuyas claves definen la fase grama tiene una función básica de detec- utilizando el potente y útil motor
del movimiento (walk) y cuyos valores ción de colisiones para prevenir superpo- Panda3D, que te librará de dolores de
corresponden a las secuencias del modelo siciones poco realistas en modelos 3D en cabeza en tus primeros pasos en el mode-
(models/panda-walk4). Puedes entonces pantalla. Incluso tiene su propio motor lado 3D. Con unas cuantas líneas de
comenzar la animación mediante el loop() físico, el cual conforma la base de un Python podrás cargar y animar modelos.
habitual y repetirlo infinitas veces (Línea 12). comportamiento realista de los objetos La documentación del sitio web incluye
La función stop() detiene el movimiento: en asignándoles una masa. Las funciones un simple tutorial y un manual que
nuestro ejemplo, las Líneas 7 y 8 asignan las explica los conceptos y funciones más
teclas [A] y [S] a estas funciones. Listado 4: Trabajo con importantes.
El movimiento en escena puede imple- intervalos Por contra, las referencias de clase y
mentarse usando la función setPos() de método dejan mucho que desear. Afortu-
01 def rotate(self):
la que antes hablábamos. En todo caso, nadamente, dado que Panda3D tiene una
02 hprInterval = [Link].
Panda te ofrece una opción mucho más enorme comunidad de usuarios, las pre-
hprInterval(4,
potente: los intervalos. Los intervalos guntas inteligentes se responden muy
Point3(360,0,0),
dan a los programadores la posibilidad rápido en el foro de la web. ■
startHpr=Point3(0,0,0))
de, sencillamente, especificar valores de
03 [Link]()
principio y fin y la duración de las ani-
04
RECURSOS
maciones (es decir, posiciones, etc). [1] Panda 3D: [Link]
05 def createmenu(self):
Panda3D se encarga automáticamente de
06 text = OnscreenText(text = ‘a: [2] Chicken, el exportador a Egg para
los valores intermedios. El Listado 4
animate, s: stop, r: rotate, Blender: [Link]
demuestra cómo puedes usar un inter- com/panda
esc: exit’, pos
valo para rotar el modelo cargado sobre
07 = (-0.8, 0.9), scale = 0.07) [3] Pygame: [Link]
su propio eje.
52 Número 25 [Link]- [Link]