Last active
April 16, 2018 15:44
-
-
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
This file contains 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
# 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