Created
July 9, 2013 08:08
-
-
Save cyrildiagne/5955570 to your computer and use it in GitHub Desktop.
Blender motion capture with OpenNI (via OSC)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
from mathutils import Vector | |
from mathutils import Quaternion | |
from bpy.types import ToolSettings | |
from OSC import OSCServer | |
import types | |
# this method of reporting timeouts only works by convention | |
# that before calling handle_request() field .timed_out is | |
# set to False | |
def handle_timeout(self): | |
self.timed_out = True | |
class OSCOpenNI(bpy.types.Operator): | |
'''OSC OpenNI''' | |
bl_idname = "object.osc_openni" | |
bl_label = "OSC OpenNI" | |
_timer = None | |
_server = None | |
def modal(self, context, event): | |
if event.type == 'ESC': | |
return self.cancel(context) | |
elif event.type == 'TIMER': | |
# clear timed_out flag | |
self._server.timed_out = False | |
# handle all pending requests then return | |
while not self._server.timed_out: | |
self._server.handle_request() | |
return {'PASS_THROUGH'} | |
def execute(self, context): | |
context.window_manager.modal_handler_add(self) | |
self._timer = context.window_manager.event_timer_add(0.06, context.window) | |
self._server = OSCServer( ("localhost", 7110) ) | |
self._server.timeout = 0 | |
# funny python's way to add a method to an instance of a class | |
self._server.handle_timeout = types.MethodType(handle_timeout, self._server) | |
self._server.addMsgHandler( "/skeleton", self.user_callback ) | |
armature = bpy.context.scene.objects['Armature'] | |
bpy.context.scene.objects.active = armature | |
bpy.ops.object.mode_set(mode='POSE') | |
for b in armature.pose.bones: | |
b.rotation_mode = 'QUATERNION' | |
print('- OSC OpenNI started! -') | |
return {'RUNNING_MODAL'} | |
def cancel(self, context): | |
print('- OSC OpenNI stopped! -') | |
context.window_manager.event_timer_remove(self._timer) | |
if self._server: | |
self._server.close() | |
return {'CANCELLED'} | |
# tags lists args type : eg for 3 floats -> 'fff' | |
# args is a OSCMessage with data | |
# source is where the message came from (in case you need to reply) | |
def user_callback(self, path, tags, args, source): | |
a = args | |
armature = bpy.context.scene.objects['Armature'] | |
bones_data = bpy.data.armatures['Armature'].bones | |
scene = bpy.context.scene | |
frame = scene.frame_current+1 | |
scene.frame_end = frame | |
scene.frame_set(frame) | |
for i in range(0, int(len(a)/8)): | |
p = i*8 | |
name = a[p] | |
b = armature.pose.bones[name] | |
q = Quaternion((a[p+1], a[p+2], a[p+3], a[p+4])) | |
bind_pose_inv = bones_data[name].matrix_local.to_quaternion().inverted() | |
b.rotation_quaternion = bind_pose_inv * q | |
b.keyframe_insert("rotation_quaternion", frame=frame) | |
if a[p] == 'waist': | |
armature.location.x = a[p+5] | |
armature.location.y = a[p+6] | |
armature.location.z = a[p+7] | |
armature.keyframe_insert("location", frame=frame) | |
def register(): | |
bpy.utils.register_class(OSCOpenNI) | |
def unregister(): | |
bpy.utils.unregister_class(OSCOpenNI) | |
if __name__ == "__main__": | |
register() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment