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.
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: Both arms are swinging in the same direction when it should not.
Climb Ladder animation: The right arm! Argh!
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.)
2nd Sample
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?