KatsBits Community

[MD5] EXPORT script for Blender 2.6x (OPEN)

keless · 228 · 347702

0 Members and 1 Guest are viewing this topic.

Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
The NLA is more of a 'global' animation system in that you can track and animate objects and items, it's basically to top level system where objects and events are animated rather than bones and armatures - you can animate characters using it but it's messy as it's not easy to drill down into the working data. For example you could rig a 'walk' anim for a character, armature legs and body move, but no actual forward motion. Using the NLA would then allow you to move the character forward in *object* mode - you'd *never* do this for an actual game character though, I just use it as an example of how the NLA can be used.

Because of the way I rig my characters, I've never yet had a need to use anything other than the Action Editor, messing with IPO data and what have you has never seemed that intuitive to me.

So in answer to 1) yes (I've got some tutorials in mind to explain why but finding the time as always). 2) As far as I understand, yes, Blender works and relies on those Datablocks, so you're correct.. if there are no connections to them they tend to just sit there - you have to re-load and save the file a couple of times to get rid of them. And again yes, if there are no connections to the datablock they can't be exported from what I understand.

And I agree, Outliner for the win (certainly the way it used to list everything), I often find myself referring to that to see what's in the file and connected to what.. especially the OPPS Schematic of pre 2.49.



Offline keless

  • Newbie
    • Posts: 29
Here is the first pass at exporting the .md5anim data ( http://dl.dropbox.com/u/1556553/io_export_md5.9-17-2010.py )

I'm just using the currently active 'action' and ignoring any others that may be in memory-- to export a series of .md5anims right now, you'd have to select each animation and perform the export one by one.

It seems to output a file in the correct format, however running the file shows the bone matrix values are corrupted. My frog character looks like a twisted mess.

The code in question should be local to:
Code: [Select]
      for bonename in thearmature.data.bones.keys():
        posebonemat = mathutils.Matrix(pose.bones[bonename].matrix ) # @ivar poseMatrix: The total transformation of this PoseBone including constraints. -- different from localMatrix
       
        try:
          bone  = BONES[bonename] #look up md5bone
        except:
          print( "found a posebone animating a bone that is not part of the exported armature: " + bonename )
          continue
        if bone.parent: # need parentspace-matrix
          parentposemat = mathutils.Matrix(pose.bones[bone.parent.name].matrix ) # @ivar poseMatrix: The total transformation of this PoseBone including constraints. -- different from localMatrix
          posebonemat = posebonemat*parentposemat.invert()
        else:
          posebonemat = posebonemat*thearmature.matrix_world
        loc = [posebonemat[3][0],
            posebonemat[3][1],
            posebonemat[3][2],
            ]
        rot = posebonemat.to_quat().normalize()
        rot = [rot.w,rot.x,rot.y,rot.z]
           
        animation.addkeyforbone(bone.id, time, loc, rot)

and changing the .matrix values to .matrix_local changes the result, but its just a slightly different twisted mess.. perhaps something somewhere else is messed up.


Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
Mesh exports OK.. no UVW issues from what I could tell. Will try other characters when I get a chance. Animations mess up quite bad as per your experiences, the bones seem to export OK as the rig looks sound without an animation loaded (into the MD5 viewer again). Loading in the *.md5anim 'breaks' the rig and splats the model all over the place.




Offline keless

  • Newbie
    • Posts: 29
Yay, squishbunny is squishy. Also, didn't I _just_ learn that matrix multiplication order got flipped in Blender 2.5?? Durrrr...

Problem solved, correct script is available at ( http://dl.dropbox.com/u/1556553/io_export_md5.9-17-2010.py ) pending rigorous testing.

There are plenty of bells and whistles that could be added to the script, like the ability to toggle mesh or anim generation off (if you only wanted to cut a new .md5anim file, for example), which I may or may not continue with-- anyone with the moxy is welcome to add their polish.

Also, my dropbox account may get cut off at some point in the future: if someone has a more stable place to host the script, I'd be obliged.


Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
Works perfectly! Excellent work on this btw and don't worry about hosting, I'll sort that out here.

I'd be inclined to add the bells and whistles you can think of to avoid 'feature creep' added by other people, gets confusing sometimes trying to figure out which scripts to use sometimes when there are several version available. Speaking of which I can only really think of two... the export option you mentioned (export either/or/both). And exporting multiple Actions, not sure how that would work based on what you discovered during the development of this though.



Offline keless

  • Newbie
    • Posts: 29
Yeah, I don't know how I'd access the other actions unless they were stored in NLA tracks. There's just no access to them through the API, unless there is some place I haven't looked.

BTW; I know bunny is somewhat low poly, but is he supposed to be that faceted, or am I exporting the normals incorrectly?


Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
Ah yes, everything is fine, that's just the dynamic shadow volumes of the MD5 viewer doing that, the volumes don't 'blend' or 'soften' over edges (which you probably know already), so the edge of the volume tends to be hard, causing the wierd visuals - character models in idtech games generally have 'self-shadow' turned aff because of this problem.

They've moved datablock access again. In the Outliner view click the dropdown list and select "Datablocks", actions are listed in that view under "Actions" - it should be expandable with any animation Action present in the file being listed there. So the data is there, I've just no idea how you get at it to do export all of it in one go  :-\



Offline keless

  • Newbie
    • Posts: 29
Hrm, I thought I'd looked at that Datablocks mode of the Outliner-- guess I missed it. In my frog sample I can see the "rock" animation and the "action" (default that I though I threw away) in the data blocks. Interestingly it seems its the "action" action that has the rocking out keyframes in it, and the "rock" action is empty >.<

In python I can access it from bpy.data.actions['actionName'] so I can definitely iterate over all the actions. But in order to pull the actual animation data from it, I need a way to bind that action to the armature as the active action...

Looks like setting theArmatureObject.animation_data.action = bpy.data.actions['ActionName'] may work.
(Note: dont use theArmatureObject.data.animation_data -- seems to be an empty pointer)

I don't think there's any way to tell if an action BELONGS to an armature before you do this, so it may be error prone if you have actions that belong to other armatures in the same blend file, which may not be common for this usage anyway.


Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
I can't see any connection either looking at the datablock info, there seems to be a lot of recursive data in each Action but nothing that identifies it as being parented to the rig. How about doing it the other way around... If you can pull the blocks, what about a checklist option type approach? That would act as a safeguard in respect to not exporting files the user didn't select? Would that work?

You'll need to go through the save >> reload >> save >> reload process to remove that dead datablock


Offline keless

  • Newbie
    • Posts: 29
Yeah that seems the best solution, I just gotta figure out the UI api necessary to do it.


Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
Was testing the script today and came across a minor issue, it's currently exporting all frames present in the Actions editor time line. Sometimes you need to 'over-pose' an animation to make sure it cycles correctly, right now the script is exporting those extra unwanted frames (its exporting 1>120 instead of 1>100). You need to add a UI input field so "start >> end" frames can be marked? Or read the rendering datablock that has "start >> end" data associated with still image rendering to get the actual limit?.


Offline keless

  • Newbie
    • Posts: 29
Was testing the script today and came across a minor issue, it's currently exporting all frames present in the Actions editor time line. Sometimes you need to 'over-pose' an animation to make sure it cycles correctly, right now the script is exporting those extra unwanted frames (its exporting 1>120 instead of 1>100). You need to add a UI input field so "start >> end" frames can be marked? Or read the rendering datablock that has "start >> end" data associated with still image rendering to get the actual limit?.

Currently the script is pulling the start and stop frames from action.frame_range[0,1]. I don't see any data blocks that specify an "output animation frame set" that I could pull from instead of that range. If I knew the UI api well enough (still cant get the actions list selection interface working), I would add a "force end frame" input and check box so you could toggle that on and type in your end frame.


Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
I've found a couple of references in the Outliner for the start/end datablock info. As it's in two locations I don't know if that means it's two sets of the same datablock info just duplicating each other or two links back to the original datablock (which I can't find).

  • Scenes >> Scene >> Current Frame / End Frame / Start Frame
  • Screens >> Animation >> Scene >> Scene >> Current Frame / End Frame

Any use?


Offline keless

  • Newbie
    • Posts: 29
Okay, looks like I can access that data from bpy.context.scene.frame_start and .frame_end

Try this: http://dl.dropbox.com/u/1556553/io_export_md5.9-20-2010.py

Hrm, busy right now but I should check to see what happens when the "scene frame range" is larger than the "action frame range" (like the scene is from -20 to 200, but the action itself has keyframes from 0 to 202, or -30 to 50, or 20 to 100 ), might need to cap the "scene frame range" down into a subset of "action frame range"..


Offline kat

  • Administrator
  • Hero Member
  • *
    • Posts: 3139
    • KatsBits
I'm not getting any output with that version for some reason and the following error crops up in the console;
Code: [Select]
found bundled python: D:\PROGRA~1\BLENDE~1\BLENDE~1.54B\2.54\python
read blend: F:\IMvu-WIPs\PET bunny\sneakyidle3 v254.blend
Traceback (most recent call last):
  File "C:\Users\[user]\AppData\Roaming\Blender Foundation\Blender\2.54\scripts\io\
io_export_md5.py", line 832, in execute
    name = self.properties.md5name,
AttributeError: 'EXPORT_OT_md5' object has no attribute 'md5name'
I usually select both the mesh and armature with the mesh as the active object when exported (not sure if that makes a difference but it's a force of habit), adding the *.md5mesh extension to the file - tried with and without, nadda from either.

With regards the negative keyframes(?) I'm not sure that's possible, certainly not using the normal Action/Dopesheet editors, traditionally speaking Blender has always had frame "1" as the first frame into which data can be placed as "0" is used as a 'base' frame(? iirc).

Incidentally, are there some export options missing in this version or is that a result of the error? I could have sworn there were some adjustable option fields on previous versions?