123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- from .animation import *
- from .logger import *
- from .package_level import *
- import bpy
- #===============================================================================
- class FCurveAnimatable:
- def define_animations(self, object, supportsRotation, supportsPosition, supportsScaling, xOffsetForRotation = 0):
- # just because a sub-class can be animatable does not mean it is
- self.animationsPresent = object.animation_data and object.animation_data.action
- if (self.animationsPresent):
- Logger.log('animation processing begun', 2)
- # instance each type of animation support regardless of whether there is any data for it
- if supportsRotation:
- if object.rotation_mode == 'QUATERNION':
- if object.type == 'CAMERA':
- # if it's a camera, convert quaternions to euler XYZ
- rotAnimation = QuaternionToEulerAnimation(object, 'rotation', 'rotation_quaternion', -1, xOffsetForRotation)
- else:
- rotAnimation = QuaternionAnimation(object, 'rotationQuaternion', 'rotation_quaternion', 1, xOffsetForRotation)
- else:
- rotAnimation = VectorAnimation(object, 'rotation', 'rotation_euler', -1, xOffsetForRotation)
- if supportsPosition:
- posAnimation = VectorAnimation(object, 'position', 'location')
- if supportsScaling:
- scaleAnimation = VectorAnimation(object, 'scaling', 'scale')
- self.ranges = []
- frameOffset = 0
- currentAction = object.animation_data.action
- for action in bpy.data.actions:
- # get the range / assigning the action to the object
- animationRange = AnimationRange.actionPrep(object, action, False, frameOffset)
- if animationRange is None:
- continue
- if supportsRotation:
- hasData = rotAnimation.append_range(object, animationRange)
- if supportsPosition:
- hasData |= posAnimation.append_range(object, animationRange)
- if supportsScaling:
- hasData |= scaleAnimation.append_range(object, animationRange)
- if hasData:
- Logger.log('processing action ' + animationRange.to_string(), 3)
- self.ranges.append(animationRange)
- frameOffset = animationRange.frame_end
- object.animation_data.action = currentAction
- #Set Animations
- self.animations = []
- if supportsRotation and len(rotAnimation.frames) > 0:
- self.animations.append(rotAnimation)
- if supportsPosition and len(posAnimation.frames) > 0:
- self.animations.append(posAnimation)
- if supportsScaling and len(scaleAnimation.frames) > 0:
- self.animations.append(scaleAnimation)
- if (hasattr(object.data, "autoAnimate") and object.data.autoAnimate):
- self.autoAnimate = True
- self.autoAnimateFrom = bpy.context.scene.frame_end
- self.autoAnimateTo = 0
- for animation in self.animations:
- if self.autoAnimateFrom > animation.get_first_frame():
- self.autoAnimateFrom = animation.get_first_frame()
- if self.autoAnimateTo < animation.get_last_frame():
- self.autoAnimateTo = animation.get_last_frame()
- self.autoAnimateLoop = True
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- def to_scene_file(self, file_handler):
- if (self.animationsPresent):
- file_handler.write('\n,"animations":[')
- first = True
- for animation in self.animations:
- if first == False:
- file_handler.write(',')
- animation.to_scene_file(file_handler)
- first = False
- file_handler.write(']')
- file_handler.write(',"ranges":[')
- first = True
- for range in self.ranges:
- if first != True:
- file_handler.write(',')
- first = False
- range.to_scene_file(file_handler)
- file_handler.write(']')
- if (hasattr(self, "autoAnimate") and self.autoAnimate):
- write_bool(file_handler, 'autoAnimate', self.autoAnimate)
- write_int(file_handler, 'autoAnimateFrom', self.autoAnimateFrom)
- write_int(file_handler, 'autoAnimateTo', self.autoAnimateTo)
- write_bool(file_handler, 'autoAnimateLoop', self.autoAnimateLoop)
|