1
$\begingroup$

What I have: Blender 2.70, a XML file of Ogre3D origin with data of armature and animations.

What I've done so far:

I have managed to create an armature using the data from the XML file. enter image description here

I tried to create animation for my armature with the data from the very same XML file that has created my armature.

These are the results:

Walking animation on Make A Gif

Walking animation: Both arms are swinging in the same direction when it should not.

Climb Ladder Animation on Make A Gif

Climb Ladder animation: The right arm! Argh!

Climb Window Animation on Make A Gif

Climb Over Window animation: The legs are messed up! Only the left arm appears to be correct.

This is the script that I've created to enable my non-perfect animations.

def xCollectAnimationData(animationData, xDoc):
    OGRE_ANIMATIONS = {}
    AnimationDuration = {}
    animationData['animation'] = OGRE_ANIMATIONS
    animationData['animationLength'] = AnimationDuration

    scn = bpy.context.scene
    arm = bpy.data.armatures["Rig"]
    rigobj = bpy.data.objects["Rig"]
    scn.objects.active = rigobj
    rigobj.select = True

    bpy.ops.object.mode_set(mode = 'POSE')

    for animations in xDoc.getElementsByTagName('animations'):
        for animation in animations.childNodes:
            OGRE_Animation = {}
            if animation.localName == 'animation':
                animationName = str(animation.getAttributeNode('name').value)
                animationLength = float(animation.getAttributeNode('length').value)
                OGRE_Animation['name'] = animationName
                OGRE_Animation['length'] = animationLength

                action = bpy.data.actions.new(animationName)

                for tracks in animation.getElementsByTagName('tracks'):
                    for track in tracks.childNodes:
                        if track.localName == 'track':
                            trackName = str(track.getAttributeNode('bone').value)
                            OGRE_Animation['track'] = trackName

                            #Select the bones
                            try:                   
                                boneSelect = bpy.context.object.data.bones[trackName]
                                boneSelect.select = True
                            except:
                                boneSelect.select = False
                                print (trackName + " not found!")                           

                            for keyframes in track.getElementsByTagName('keyframes'):
                                for keyframe in keyframes.childNodes:
                                    if keyframe.localName == 'keyframe':
                                        time = float(keyframe.getAttributeNode('time').value)
                                        OGRE_Animation['time'] = time

                                        for a in keyframe.childNodes:

                                            if a.localName == 'rotate':
                                                boneSelect.select = True

                                                angle = float(a.getAttributeNode('angle').value)
                                                axis = a.childNodes[1]

                                                try:
                                                    axisx = float(axis.getAttributeNode('x').value)
                                                except ValueError:
                                                    axisx = 0.0
                                                try:
                                                    axisy = float(axis.getAttributeNode('y').value)
                                                except ValueError:
                                                    axisy = 0.0
                                                try:
                                                    axisz = float(axis.getAttributeNode('z').value)
                                                except ValueError:
                                                    axisz = 0.0
                                                print (trackName + ": " + str(angle)+ ", " + str(axisx)+ ", "+str(axisy)+ ", "+str(axisz))
                                                OGRE_Animation['rotation'] = [axisx,axisy,axisz,angle]
                                                bpy.ops.transform.rotate(value=(angle), axis=(axisz,axisy,axisx))  
                                                bpy.data.objects["Rig"].pose.bones[boneSelect.name].keyframe_insert(data_path='rotation_quaternion', frame = (time * 30), group = trackName)
                                                bpy.ops.transform.rotate(value=(-angle), axis=(axisz,axisy,axisx))

                                            if a.localName == 'translate':
                                                boneSelect.select = True

                                                x = float(a.getAttributeNode('x').value)
                                                y = float(a.getAttributeNode('y').value)
                                                z = float(a.getAttributeNode('z').value)
                                                OGRE_Animation['translate'] = [x,y,z]
                                                bpy.ops.transform.translate(value=(x,y,z))
                                                print (x,y,z)
                                                scn.update()   
                                                bpy.data.objects["Rig"].pose.bones[boneSelect.name].keyframe_insert(data_path='location', frame = (time * 30), group = trackName)
                                                bpy.ops.transform.translate(value=(-x,-y,-z)) 

                                            boneSelect.select = False   
                                        #except:
                                        #    return 
                            boneSelect.select = False



                OGRE_ANIMATIONS[animationName] = OGRE_Animation
                print (animationName)

    scn.update() 
    bpy.ops.object.mode_set(mode='OBJECT')                                           
    return OGRE_ANIMATIONS

TLDR: What I did is that I select my rig, make it as my current active object, then switch to pose mode.

From there, I select the specific bone I want to animate to be current active bone; I give it a rotation by doing a bpy.ops.transform.rotate(value=(angle), axis=(axisz,axisy,axisx)) (angle,axisx, etc are gathered from the XML file), keyframe it at a specific time (timing also from XML), and then rotating it back to the original position. The same goes for translation of bones.

This is the snipplet of the XML files. (I have no idea if I should give the entire XML file, companies..., though the file doesn't seems so secret to me.)

enter image description here

2nd Sample

enter image description here

Conclusions: My task for importing this xml file into blender seems so close to completion yet feels so far. I've tried messing around with the rotation but to no avail and have been stuck with this issue for a week. The animations appear to be almost correct with the exception of certain bones.

Colleagues have suggested that I used matrix to rotate the bones for animations, but I would not if it's possible and would rather stick with my current way of rotating the bones and tweaking/resolving it to make my animations the way it is.

By doing a bpy.ops.transform.rotate(value=(angle), axis=(axisz, axisy, axisx), am I rotating as an axis-angle rotation or quaternion rotation?

$\endgroup$
1
  • 3
    $\begingroup$ This question appears to be off-topic because it is too long for this format for a scripting question. $\endgroup$
    – CodeManX
    Jul 14, 2014 at 11:56

1 Answer 1

1
$\begingroup$

Solved it. Turns out, I don't have to do rotation with the data at all. I simply did a

bpy.data.objects["Rig"].pose.bones[boneSelect.name].rotation_axis_angle = [angle,axisz,axisx,axisy]

and keyframe it.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .