Skip to content

Instantly share code, notes, and snippets.

@cyrildiagne
Created July 9, 2013 08:08
Show Gist options
  • Save cyrildiagne/5955570 to your computer and use it in GitHub Desktop.
Save cyrildiagne/5955570 to your computer and use it in GitHub Desktop.
Blender motion capture with OpenNI (via OSC)
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