Skip to content

Instantly share code, notes, and snippets.

@daylanKifky
Last active April 16, 2018 15:44
Show Gist options
  • Save daylanKifky/29544842f1becb5255ec9c9c1dc15043 to your computer and use it in GitHub Desktop.
Save daylanKifky/29544842f1becb5255ec9c9c1dc15043 to your computer and use it in GitHub Desktop.
Send the projected 2D joint points of an armature in Blender trough OSC
# Point projection from:
# - https://blender.stackexchange.com/questions/16472/how-can-i-get-the-cameras-projection-matrix#answer-86570
# (@fnunnari's response)
import bpy
from mathutils import Vector
def project_3d_point(camera: bpy.types.Object,
p: Vector,
render: bpy.types.RenderSettings = bpy.context.scene.render) -> Vector:
"""
Given a camera and its projection matrix M;
given p, a 3d point to project:
Compute P’ = M * P
P’= (x’, y’, z’, w')
Ignore z'
Normalize in:
x’’ = x’ / w’
y’’ = y’ / w’
x’’ is the screen coordinate in normalised range -1 (left) +1 (right)
y’’ is the screen coordinate in normalised range -1 (bottom) +1 (top)
:param camera: The camera for which we want the projection
:param p: The 3D point to project
:param render: The render settings associated to the scene.
:return: The 2D projected point in normalized range [-1, 1] (left to right, bottom to top)
"""
if camera.type != 'CAMERA':
raise Exception("Object {} is not a camera.".format(camera.name))
if len(p) != 3:
raise Exception("Vector {} is not three-dimensional".format(p))
# Get the two components to calculate M
modelview_matrix = camera.matrix_world.inverted()
projection_matrix = camera.calc_matrix_camera(
render.resolution_x,
render.resolution_y,
render.pixel_aspect_x,
render.pixel_aspect_y,
)
# print(projection_matrix * modelview_matrix)
# Compute P’ = M * P
p1 = projection_matrix * modelview_matrix * Vector((p.x, p.y, p.z, 1))
# Normalize in: x’’ = x’ / w’, y’’ = y’ / w’
p2 = Vector(((p1.x/p1.w, p1.y/p1.w)))
return p2
D=bpy.data
cam = D.objects['Camera']
from pythonosc import osc_message_builder
from pythonosc import udp_client
from mathutils import Matrix
IP='127.0.0.1'
PORT = 6767
client = udp_client.SimpleUDPClient(IP, PORT)
def send_Armature(arm: bpy.types.Armature):
res = project_3d_point(cam, arm.location)
client.send_message("/point", (res[0], res[1]))
for b in arm.pose.bones:
M = arm.matrix_world * b.matrix * Matrix.Translation((0,b.vector.magnitude,0))
res = project_3d_point(cam, M.to_translation())
client.send_message("/point", (res[0], res[1]))
print(res)
send_Armature(D.objects["Armature"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment