Beispiel #1
0
def rigRecon(input, context, timeOffset, rot, transl):
    for name in input.keys():
        entry = input[name]
        bpy.ops.object.select_pattern(pattern=name + "*", extend=False)
        print("pattern: %s" % name + '*')
        obj = context.selected_objects[0]
        print("Keyframing %s" % obj.name)

        prevPose = None
        prevEuler = None
        offset = Vector((0, 0, 0))
        for sFrameId in entry['log'].keys():
            state = entry['log'][sFrameId]
            frameId = int(sFrameId)
            #print( "Adding keyFrame %d" % frameId )
            context.scene.frame_set(frameId)
            obj.location = state['pos']
            obj.rotation_mode = 'QUATERNION'
            q = Quaternion(state['pose'])
            if prevPose:
                if q.dot(prevPose) < 0:
                    q.negate()
                    #print('newq:',q)
                # else:
                #     print('dotok:', prevPose, q, q.dot(prevPose))
            obj.rotation_quaternion = q
            #obj.rotation_euler = q.to_euler('XYZ')
            #obj.rotation_euler.x += offset.x
            #obj.rotation_euler.y += offset.y
            #obj.rotation_euler.z += offset.z
            #if prevEuler:
            #    d = Vector(obj.rotation_euler) - Vector(prevEuler)
            #    if d.length > 1:
            #        print("[",sFrameId,"] d: ", d )
            #        print('prev: ', prevEuler, 'new: ', obj.rotation_euler)
            #     if abs(d.x) > math.pi/2:
            #         offset.x += 2*math.pi
            #         obj.rotation_euler.x += 2*math.pi
            #         print( "offset.x:" , offset.x, 'newx: ', obj.rotation_euler.x )
            #     if abs(d.y) > math.pi/2:
            #       offset.y += 2*math.pi
            #        obj.rotation_euler.y += 2*math.pi
            #        print( "offset.y:" , offset.y, 'newy: ', obj.rotation_euler.y  )
            #    if abs(d.z) > math.pi/2:
            #        offset.z += 2*math.pi
            #        obj.rotation_euler.z += 2*math.pi
            #        print( "offset.z:" , offset.z, 'newz: ', obj.rotation_euler.z  )

            #obj.rotation_euler.x -= math.pi / 2.
            #bpy.ops.anim.keyframe_insert()
            #obj.keyframe_insert( data_path="LocRot", index=-1,frame=frameId)
            bpy.ops.anim.keying_set_active_set(type='BUILTIN_KSI_LocRot')
            bpy.ops.anim.keyframe_insert()
            #obj.keyframe_insert(index=-1)
            #obj.keyframe_insert(data_path="location", index=-1, frame=frameId)
            #obj.keyframe_insert(data_path="rotation", index=-1, frame=frameId)
            prevPose = q.copy()
            prevEuler = obj.rotation_euler.copy()
Beispiel #2
0
def remove_quaternion_discontinuities(target_obj):

    # the interpolation of quaternions may lead to discontinuities
    # if the quaternions show different signs

    # https://blender.stackexchange.com/questions/58866/keyframe-interpolation-instability
    action = target_obj.animation_data.action

    # quaternion curves
    fqw = action.fcurves.find("rotation_quaternion", index=0)
    fqx = action.fcurves.find("rotation_quaternion", index=1)
    fqy = action.fcurves.find("rotation_quaternion", index=2)
    fqz = action.fcurves.find("rotation_quaternion", index=3)

    # invert quaternion so that interpolation takes the shortest path
    if len(fqw.keyframe_points) > 0:
        current_quat = Quaternion((
            fqw.keyframe_points[0].co[1],
            fqx.keyframe_points[0].co[1],
            fqy.keyframe_points[0].co[1],
            fqz.keyframe_points[0].co[1],
        ))

        for i in range(len(fqw.keyframe_points) - 1):
            last_quat = current_quat
            current_quat = Quaternion((
                fqw.keyframe_points[i + 1].co[1],
                fqx.keyframe_points[i + 1].co[1],
                fqy.keyframe_points[i + 1].co[1],
                fqz.keyframe_points[i + 1].co[1],
            ))

            if last_quat.dot(current_quat) < 0:
                current_quat.negate()
                fqw.keyframe_points[i +
                                    1].co[1] = -fqw.keyframe_points[i +
                                                                    1].co[1]
                fqx.keyframe_points[i +
                                    1].co[1] = -fqx.keyframe_points[i +
                                                                    1].co[1]
                fqy.keyframe_points[i +
                                    1].co[1] = -fqy.keyframe_points[i +
                                                                    1].co[1]
                fqz.keyframe_points[i +
                                    1].co[1] = -fqz.keyframe_points[i +
                                                                    1].co[1]
Beispiel #3
0
 def operation_negate(self, q):
     qn = Quaternion(q)
     qn.negate()
     return qn
Beispiel #4
0
 def operation_negate(self, q):
     qn = Quaternion(q)
     qn.negate()
     return qn
Beispiel #5
0
    def execute(self, context):
        data = []

        objId = 0
        for ob in bpy.data.objects:
            if (ob.physacq.is_actor):
                print(ob.name)
                o = {}
                o['name'] = ob.name
                o['objId'] = objId
                o['shape'] = ob.physacq.shape
                o['size'] = {
                    "x": ob.dimensions[0],
                    "y": ob.dimensions[1],
                    "z": ob.dimensions[2]
                }
                o['mass'] = ob.physacq.mass

                log = {}

                if not ob.animation_data:
                    continue

                action = ob.animation_data.action
                for fcu in action.fcurves:
                    #print( "fcu: ", fcu )
                    #print( "prop: ", fcu.data_path )
                    #print( "propId: ", fcu.array_index )

                    if fcu.data_path == 'location':
                        logKey = 'pos'
                    elif fcu.data_path == 'rotation_euler':
                        logKey = 'pose'
                    elif fcu.data_path == 'rotation_quaternion':
                        logKey = 'pose'
                    elif fcu.data_path == 'scale':
                        continue
                    else:
                        print("Can't interpret keyframe type, attention!!!",
                              fcu.data_path)
                        continue

                    if fcu.array_index == 0:
                        subKey = 'x'
                    elif fcu.array_index == 1:
                        subKey = 'y'
                    elif fcu.array_index == 2:
                        subKey = 'z'
                    elif fcu.array_index == 3:
                        subKey = 'w'
                    else:
                        print("Unprepared!")

                    keyframe_points = fcu.keyframe_points
                    for entry in keyframe_points:
                        #print( entry.co )
                        #print( "key:", str(int(entry.co[0])) )
                        frameId = str(int(entry.co[0]))
                        if frameId not in log:
                            log[frameId] = {}
                        if logKey not in log[frameId]:
                            log[frameId][logKey] = {}
                        log[frameId][logKey][subKey] = entry.co[1]
                prevKey = None
                prevQ = None
                for key, frame in log.items():
                    if 'pos' in log[key]:
                        pos = Vector(
                            coordinatesUtil.jsonVector3ToTuple(
                                log[key]['pos']))
                        log[key]['pos'] = coordinatesUtil.vector3ToJson(
                            self.coordChangeM * pos)

                    if 'pose' not in log[key]:
                        continue

                    #print( 'ob.rotation_mode:', ob.rotation_mode)
                    if ob.rotation_mode == 'XYZ':
                        v = Vector(
                            coordinatesUtil.jsonVector3ToTuple(
                                log[key]['pose']))
                        eul = Euler(v, ob.rotation_mode)
                        q = eul.to_quaternion()
                    elif ob.rotation_mode == 'QUATERNION':
                        entry = log[key]['pose']
                        print(entry)
                        q = Quaternion((
                            entry['x'], entry['y'], entry['z'],
                            entry['w']))  # yes, array_index==3 was parsed to w
                    if prevQ:
                        dotProd = q.dot(prevQ)
                        if dotProd < 0:
                            print("dot: ", dotProd)
                            #q.negate()

                    #print( "q: %s" % (q.__repr__()) )
                    #log[ key ] ['pose'] = { 'x' : q[1], 'y' : -q[3], 'z': q[2], 'w' : q[0] }
                    log[key]['pose'] = coordinatesUtil.quatToJson(
                        coordinatesUtil.quatFromBlender(q))
                    if prevKey:
                        #print( "check: ", log[prevKey]['pose'], "\n",log[key]['pose'] )
                        q2 = Quaternion(q)
                        q2.negate()
                        #print( "q:", q, "negative: ", q2 )

                    prevKey = key
                    prevQ = q

                o['log'] = log
                data.append(o)
                objId += 1

        if not len(data):
            self.report({'WARNING'}, "No keyframes, not saving")
            return {'FINISHED'}

        fp = context.scene.physacq.savePath
        if len(bpy.path.basename(fp)) == 0:
            fp = "//cuboids.json"

        if fp.find("//") >= 0:
            fp = bpy.path.abspath(fp)
        self.report({'INFO'}, "Saving poses to %s" % (fp))

        f = open(fp, 'w')
        json.dump(data, f)
        f.close()

        return {'FINISHED'}
Beispiel #6
0
    fqz = action.fcurves.find('rotation_quaternion', index = 3)

    # invert quaternion so that interpolation takes the shortest path
    if fqw is not None and fqw.keyframe_points is not None and len(fqw.keyframe_points) > 0:
        endQuat = Quaternion(
            (
                fqw.keyframe_points[0].co[1],
                fqx.keyframe_points[0].co[1],
                fqy.keyframe_points[0].co[1],
                fqz.keyframe_points[0].co[1]
            )
        )

        for i in range(len(fqw.keyframe_points)-1):
            startQuat = endQuat
            endQuat = Quaternion(
                (
                    fqw.keyframe_points[i+1].co[1],
                    fqx.keyframe_points[i+1].co[1],
                    fqy.keyframe_points[i+1].co[1],
                    fqz.keyframe_points[i+1].co[1]
                )
            )

            if startQuat.dot(endQuat) < 0:
                endQuat.negate()
                fqw.keyframe_points[i+1].co[1] = -fqw.keyframe_points[i+1].co[1]
                fqx.keyframe_points[i+1].co[1] = -fqx.keyframe_points[i+1].co[1]
                fqy.keyframe_points[i+1].co[1] = -fqy.keyframe_points[i+1].co[1]
                fqz.keyframe_points[i+1].co[1] = -fqz.keyframe_points[i+1].co[1]