[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33985] trunk/blender/release/scripts/op/ io_anim_bvh: BVH Importing native order eulers was broken, simplify conversion between rotation orders.

Campbell Barton ideasman42 at gmail.com
Sat Jan 1 14:20:36 CET 2011


Revision: 33985
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33985
Author:   campbellbarton
Date:     2011-01-01 14:20:35 +0100 (Sat, 01 Jan 2011)

Log Message:
-----------
BVH Importing native order eulers was broken, simplify conversion between rotation orders.

Modified Paths:
--------------
    trunk/blender/release/scripts/op/io_anim_bvh/__init__.py
    trunk/blender/release/scripts/op/io_anim_bvh/import_bvh.py

Modified: trunk/blender/release/scripts/op/io_anim_bvh/__init__.py
===================================================================
--- trunk/blender/release/scripts/op/io_anim_bvh/__init__.py	2011-01-01 10:38:28 UTC (rev 33984)
+++ trunk/blender/release/scripts/op/io_anim_bvh/__init__.py	2011-01-01 13:20:35 UTC (rev 33985)
@@ -53,7 +53,7 @@
             ),
                 name="Rotation",
                 description="Rotation conversion.",
-                default='QUATERNION')  # XXX, eulers are broken!
+                default='NATIVE')
 
     def execute(self, context):
         from . import import_bvh
@@ -89,8 +89,6 @@
             self.frame_end = context.scene.frame_end
 
         from . import export_bvh
-        import imp
-        imp.reload(export_bvh)
         return export_bvh.save(self, context, **self.as_keywords(ignore=("check_existing", "filter_glob")))
 
 

Modified: trunk/blender/release/scripts/op/io_anim_bvh/import_bvh.py
===================================================================
--- trunk/blender/release/scripts/op/io_anim_bvh/import_bvh.py	2011-01-01 10:38:28 UTC (rev 33984)
+++ trunk/blender/release/scripts/op/io_anim_bvh/import_bvh.py	2011-01-01 13:20:35 UTC (rev 33985)
@@ -39,11 +39,20 @@
     'rest_tail_local',  # worldspace rest location for the tail of this node
     'channels',  # list of 6 ints, -1 for an unused channel, otherwise an index for the BVH motion data lines, lock triple then rot triple
     'rot_order',  # a triple of indicies as to the order rotation is applied. [0,1,2] is x/y/z - [None, None, None] if no rotation.
-    'anim_data',  # a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz)
+    'rot_order_str',  # same as above but a string 'XYZ' format.
+    'anim_data',  # a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz), euler rotation ALWAYS stored xyz order, even when native used.
     'has_loc',  # Conveinience function, bool, same as (channels[0]!=-1 or channels[1]!=-1 channels[2]!=-1)
     'has_rot',  # Conveinience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 channels[5]!=-1)
     'temp')  # use this for whatever you want
 
+    _eul_order_lookup = {\
+        (0, 1, 2): 'XYZ',
+        (0, 2, 1): 'XZY',
+        (1, 0, 2): 'YXZ',
+        (1, 2, 0): 'YZX',
+        (2, 0, 1): 'ZXY',
+        (2, 1, 0): 'ZYX'}
+
     def __init__(self, name, rest_head_world, rest_head_local, parent, channels, rot_order):
         self.name = name
         self.rest_head_world = rest_head_world
@@ -52,7 +61,8 @@
         self.rest_tail_local = None
         self.parent = parent
         self.channels = channels
-        self.rot_order = rot_order
+        self.rot_order = tuple(rot_order)
+        self.rot_order_str = __class__._eul_order_lookup[self.rot_order]
 
         # convenience functions
         self.has_loc = channels[0] != -1 or channels[1] != -1 or channels[2] != -1
@@ -72,24 +82,6 @@
         self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z)
 
 
-# Change the order rotation is applied.
-MATRIX_IDENTITY_3x3 = Matrix([1, 0, 0], [0, 1, 0], [0, 0, 1])
-MATRIX_IDENTITY_4x4 = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
-
-
-def eulerRotate(x, y, z, rot_order):
-    # Clamp all values between 0 and 360, values outside this raise an error.
-    mats = [Matrix.Rotation(x, 3, 'X'), Matrix.Rotation(y, 3, 'Y'), Matrix.Rotation(z, 3, 'Z')]
-    return (MATRIX_IDENTITY_3x3 * mats[rot_order[0]] * (mats[rot_order[1]] * (mats[rot_order[2]]))).to_euler()
-
-    # Should work but doesnt!
-    '''
-    eul = Euler((x, y, z))
-    eul.order = "XYZ"[rot_order[0]] + "XYZ"[rot_order[1]] + "XYZ"[rot_order[2]]
-    return tuple(eul.to_matrix().to_euler())
-    '''
-
-
 def read_bvh(context, file_path, rotate_mode='XYZ', global_scale=1.0):
     # File loading stuff
     # Open the file for importing
@@ -229,13 +221,15 @@
                 lz = global_scale * float(line[channels[2]])
 
             if channels[3] != -1 or channels[4] != -1 or channels[5] != -1:
-                rx, ry, rz = float(line[channels[3]]), float(line[channels[4]]), float(line[channels[5]])
 
-                if rotate_mode != 'NATIVE':
-                    rx, ry, rz = eulerRotate(radians(rx), radians(ry), radians(rz), bvh_node.rot_order)
-                else:
-                    rx, ry, rz = radians(rx), radians(ry), radians(rz)
+                rot = radians(float(line[channels[3]])), \
+                      radians(float(line[channels[4]])), \
+                      radians(float(line[channels[5]])),
 
+                # apply rotation order and convert to XYZ
+                # note that the rot_order_str is reversed.
+                rx, ry, rz = Euler(rot, bvh_node.rot_order_str[::-1]).to_matrix().to_euler('XYZ')
+
             # Done importing motion data #
             anim_data.append((lx, ly, lz, rx, ry, rz))
         lineIdx += 1
@@ -431,18 +425,10 @@
     pose_bones = pose.bones
 
     if rotate_mode == 'NATIVE':
-        eul_order_lookup = {\
-            (0, 1, 2): 'XYZ',
-            (0, 2, 1): 'XZY',
-            (1, 0, 2): 'YXZ',
-            (1, 2, 0): 'YZX',
-            (2, 0, 1): 'ZXY',
-            (2, 1, 0): 'ZYX'}
-
         for bvh_node in bvh_nodes.values():
             bone_name = bvh_node.temp  # may not be the same name as the bvh_node, could have been shortened.
             pose_bone = pose_bones[bone_name]
-            pose_bone.rotation_mode = eul_order_lookup[tuple(bvh_node.rot_order)]
+            pose_bone.rotation_mode = bvh_node.rot_order_str
 
     elif rotate_mode != 'QUATERNION':
         for pose_bone in pose_bones:





More information about the Bf-blender-cvs mailing list