Browse Source

Testing out normalization of quaternion values

repsac 10 years ago
parent
commit
9566ec9da2

+ 1 - 1
utils/exporters/blender/addons/io_three/__init__.py

@@ -41,7 +41,7 @@ SETTINGS_FILE_EXPORT = 'three_settings_export.js'
 bl_info = {
 bl_info = {
     'name': "Three.js Format",
     'name': "Three.js Format",
     'author': "repsac, mrdoob, yomotsu, mpk, jpweeks",
     'author': "repsac, mrdoob, yomotsu, mpk, jpweeks",
-    'version': (1, 2, 3),
+    'version': (1, 2, 4),
     'blender': (2, 7, 3),
     'blender': (2, 7, 3),
     'location': "File > Export",
     'location': "File > Export",
     'description': "Export Three.js formatted JSON files.",
     'description': "Export Three.js formatted JSON files.",

+ 33 - 0
utils/exporters/blender/addons/io_three/exporter/api/animation.py

@@ -1,3 +1,4 @@
+import math
 import mathutils
 import mathutils
 from bpy import data, context
 from bpy import data, context
 from .. import constants, logger, utilities
 from .. import constants, logger, utilities
@@ -274,6 +275,7 @@ def _parse_pose_action(action, armature, options, round_off, round_val):
                 bone_matrix = parent_matrix.inverted() * bone_matrix
                 bone_matrix = parent_matrix.inverted() * bone_matrix
 
 
             pos, rot, scl = bone_matrix.decompose()
             pos, rot, scl = bone_matrix.decompose()
+            rot = _normalize_quaternion(rot)
 
 
             pchange = True or has_keyframe_at(
             pchange = True or has_keyframe_at(
                 channels_location[bone_index], frame)
                 channels_location[bone_index], frame)
@@ -569,3 +571,34 @@ def _handle_position_channel(channel, frame, position):
             position.z = value
             position.z = value
 
 
     return change
     return change
+
+
+def _quaternion_length(quat):
+    """Calculate the length of a quaternion
+
+    :param quat: Blender quaternion object
+    :rtype: float
+
+    """
+    return math.sqrt(quat.x * quat.x + quat.y * quat.y +
+                     quat.z * quat.z + quat.w * quat.w)
+
+
+def _normalize_quaternion(quat):
+    """Normalize a quaternion
+
+    :param quat: Blender quaternion object
+    :returns: generic quaternion enum object with normalized values
+    :rtype: object
+
+    """
+    enum = type('Enum', (), {'x': 0, 'y': 0, 'z': 0, 'w': 1})
+    length = _quaternion_length(quat)
+    if length is not 0:
+        length = 1 / length
+        enum.x = quat.x * length
+        enum.y = quat.y * length
+        enum.z = quat.z * length
+        enum.w = quat.w * length
+    return enum
+