MD3 Loading (Vertex Animation)

I wrote a Quake 3 MD3 loader for kicks this weekend and figured people might have use for it in their own projects. I made no attempt to integrate it with Panda’s own loader.loadModel or Actor, but it works well even so.

You can download it here:
http://www.phuce.com/uploads/panda3d/md3.zip

There are several files:* md3.py is the meat of it.

  • lerp.sha is a Cg shader to do interpolation during animation.
  • invalid.jpg is a texture to load when a texture file for the model can’t be found.
    md3.py contains several classes:* md3.Model will load and handle a single MD3 model. It will also attempt to load textures if they are specified in the surfaces.
  • md3.Animation is used to animate an MD3 file.
  • md3.Player combines the other two to facilitate loading a standard Quake 3 player model, the associated .skin files, the animation.cfg file, and can be used to animate the model.
    An example for loading a player model would be:
from direct.directbase import DirectStart
from direct.interval.LerpInterval import LerpHprInterval
from direct.showbase.DirectObject import DirectObject
from direct.task.Task import Task
from pandac.PandaModules import *
import md3

base.disableMouse()
base.camera.setPos(0, -200, 0)

class Test(DirectObject):

    def __init__(self):
        self.player = md3.Player("models/players/visor")
        self.player.reparentTo(render)
        self.player.play("upper_attack")
        self.player.play("lower_walk")
        self.player.setSkin("blue")
        self.weapon = md3.Model("models/weapons2/grenadel/grenadel.md3")
        self.weapon.reparentTo(self.player.find("**/tag_weapon"))
        LerpHprInterval(self.player, 10, VBase3(360, 0, 0)).loop()
        taskMgr.add(self.update, "update")

    def update(self, task):
        self.player.update()
        return Task.cont

Test()
run()

Tags in the MD3 models are handled as nodes, and you can use model.find() to get ahold of them, as above with the weapon model. If you reparent your nodes to the tag it will transform your node with the tag as the model animates.

Available frames of animation for the player are:

both_death1
both_dead1
both_death2
both_dead2
both_death3
both_dead3
upper_gesture
upper_attack
upper_attack2
upper_drop
upper_raise
upper_stand
upper_stand2
lower_walkCrouch
lower_walk
lower_run
lower_back
lower_swim
lower_jump
lower_land
lower_jump2
lower_land2
lower_idle
lower_idleCrouch
lower_turn

Caveats:* The code doesn’t understand .pk3 files, so extract any models you want to use, along with their textures and models.

  • Neither does the code understand Quake 3’s .shader files. Only simple texturing is supported by this code. The lerp.sha file only handles a single texture.
  • Since it’s using the shader, lighting doesn’t work.
  • As I write this I realize I forgot to add support for reversed frames in animation.cfg.

I’ll write some detailed documentation as time permits.

For anyone interested in the implementation method for interpolated vertex animation… I’ll describe it.

The GeomVertexFormat has three arrays:* #1: An array of texcoords.

  • #2: An array of vertexes and normals.
  • #3: A second array of vertexes and normals.
    The texcoord data is shared over all frames in the entire model and is never touched. The vertex and normal data for each frame is loaded it’s own GeomVertexArrayData object, and marked as UHStatic.

A GeomVertexData is created with UHDynamic (I’m not sure if this was the right choice). As the animation frames change, array #2 is set to the current frame of animation, and array #3 is set to the next frame of animation.

The model receives a setShaderInput every frame of rendering with a 0.0-1.0 value representing the percentage of time elapsed until the next frame. The lerp.sha file interpolates between the two sets of data using this value.

It seems to work pretty well. The vertex data is never touched after loading, and only the arrays are swapped out – all the vertex tweening happens in the shader.

What are MD3 models?

MD3 is the model format used by Quake 3.

Another link to download please ?