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:
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.