提交 9ae28c89 编写于 作者: B Ben Houston

rotate blender tracks by 90 degrees around x-axis.

上级 03269bf7
......@@ -131,82 +131,109 @@ def material(obj):
except IndexError:
pass
QUAT_CONVERSION = axis_conversion(from_forward='Y', from_up='Z', to_forward='Z', to_up='Y')
def __swap_quaternions(track):
for t in track:
a = t["value"]
q = mathutils.Quaternion(a)
q = (QUAT_CONVERSION*q.to_matrix()).to_quaternion()
a[0] =-q.x
a[1] =-q.y
a[2] =-q.z
a[3] =-q.w
pass
def __swap_vector3(track):
for t in track:
v = t["value"]
tmp = v[1]
v[1] = v[2]
v[2] = tmp
pass
def __parse_tracked_vector(fcurves, start_index, nb_curves):
track = []
def extract_time(fcurves, start_index):
time = []
for xx in fcurves[start_index].keyframe_points:
track.append({ "time": xx.co.x, "value": [xx.co.y] })
time.append(xx.co.x)
return time
def merge_sorted_lists(l1, l2):
sorted_list = []
l1 = l1[:]
l2 = l2[:]
while (l1 and l2):
h1 = l1[0]
h2 = l2[0]
if h1 == h2:
sorted_list.append(h1)
l1.pop(0)
l2.pop(0)
elif h1 < h2:
l1.pop(0)
sorted_list.append(h1)
else:
l2.pop(0)
sorted_list.append(h2)
# Add the remaining of the lists
sorted_list.extend(l1 if l1 else l2)
return sorted_list
swapFunction = __swap_vector3 if nb_curves == 3 else __swap_quaternions
def appendVec3(track, time, vec3):
track.append({ "time": time, "value": [ vec3.x, vec3.y, vec3.z ] })
nb_curves += start_index
start_index += 1
while start_index < nb_curves:
i = 0
for xx in fcurves[start_index].keyframe_points:
track[i]["value"].append(xx.co.y)
i += 1
start_index += 1
swapFunction(track)
return track
def appendQuat(track, time, quat):
track.append({ "time": time, "value": [ quat.x, quat.y, quat.z, quat.w ] })
# trackable transform fields ( <output field>, <nb fcurve>, <type> )
# trackable transform fields ( <output field>, <nb fcurve> )
TRACKABLE_FIELDS = {
"location": ( ".position", 3, "vector3" ),
"scale": ( ".scale", 3, "vector3" ),
"rotation_euler": ( ".rotation", 3, "vector3" ),
"rotation_quaternion": ( ".quaternion", 4, "quaternion" )
}
EXPORTED_TRACKABLE_FIELDS = [ "location", "scale", "rotation_quaternion" ]
@_object
def animated_xform(obj):
def animated_xform(obj, options):
fcurves = obj.animation_data
if not fcurves:
return {}
return []
fcurves = fcurves.action.fcurves
tracks = []
i = 0
nb_curves = len(fcurves)
# extract unique frames
times = None
while i < nb_curves:
field_info = TRACKABLE_FIELDS.get(fcurves[i].data_path)
if field_info:
nb_curves_local = field_info[1]
tracks.append({
constants.NAME: field_info[0],
constants.TYPE: field_info[2],
constants.KEYS: __parse_tracked_vector(fcurves, i, nb_curves_local)
})
i += nb_curves_local
newTimes = extract_time(fcurves, i)
times = merge_sorted_lists(times, newTimes) if times else newTimes # merge list
i += field_info[1]
else:
i += 1
animation = [{
# init tracks
track_loc = []
for fld in EXPORTED_TRACKABLE_FIELDS:
field_info = TRACKABLE_FIELDS[fld]
track = []
track_loc.append(track)
tracks.append({
constants.NAME: field_info[0],
constants.TYPE: field_info[2],
constants.KEYS: track
})
# track arrays
track_sca = track_loc[1]
track_qua = track_loc[2]
track_loc = track_loc[0]
use_inverted = options.get(constants.HIERARCHY, False) and obj.parent
# for each frame
inverted_fallback = mathutils.Matrix() if use_inverted else None
convert_matrix = AXIS_CONVERSION # matrix to convert the exported matrix
original_frame = context.scene.frame_current
for time in times:
context.scene.frame_set(time, 0.0)
if use_inverted: # need to use the inverted, parent matrix might have chance
convert_matrix = obj.parent.matrix_world.inverted(inverted_fallback)
wm = convert_matrix * obj.matrix_world
appendVec3(track_loc, time, wm.to_translation())
appendVec3(track_sca, time, wm.to_scale() )
appendQuat(track_qua, time, wm.to_quaternion() )
context.scene.frame_set(original_frame, 0.0) # restore to original frame
# TODO: remove duplicated key frames
return [{
constants.KEYFRAMES: tracks,
constants.FPS: context.scene.render.fps,
constants.NAME: obj.name
}]
return animation
@_object
def mesh(obj, options):
......
......@@ -124,7 +124,7 @@ class Object(base_classes.BaseNode):
no_anim = (None, False, constants.OFF)
if self.options.get(constants.KEYFRAMES) not in no_anim:
logger.info("Export Transform Animation for %s", self.node)
self[constants.CLIPS] = api.object.animated_xform(self.node)
self[constants.CLIPS] = api.object.animated_xform(self.node, self.options)
if self.options.get(constants.HIERARCHY, False):
for child in api.object.children(self.node, self.scene.valid_types):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册