initial parent code

This commit is contained in:
pullusb
2023-12-12 14:04:35 +01:00
parent 6197aa622b
commit 8cccc7ba8c
6 changed files with 227 additions and 142 deletions
+72
View File
@@ -159,6 +159,72 @@ def plane_on_bone(bone, arm=None, cam=None, set_rotation=True, mesh=True):
plane = plane_coords()
return matrix_transform(plane, mat @ mat_scale)
def place_object_to_ref_facing_cam(obj, ref_ob, bone=None, cam=None, set_rotation=True):
'''
obj (Object): the object to place
ref_ob (Object): the reference object or armature
bone (posebone): reference pose bone
arm (optional: Armature): Armature of the pose bone (if not passed found using bone.id_data)
cam (optional: Camera) : Camera to align plane to (if not passed use scene camera)
set_rotation (bool): rotate the plane on cam view axis according to bone direction in 2d cam space
'''
if cam is None:
cam = bpy.context.scene.camera
# if ref_ob is None:
# ref_ob = bone.id_data
mat = cam.matrix_world.copy()
if set_rotation:
if bone:
head_world_coord = ref_ob.matrix_world @ bone.head
mat.translation = head_world_coord
## Apply 2d bone rotation facing camera
# Get 2d camera space coords (NDC: normalized device coordinate, 0,0 is bottom-left)
head_2d, tail_2d = get_bone_head_tail_2d(bone, cam=cam)
else:
mat.translation = ref_ob.matrix_world
# Get 2d camera space coords (NDC: normalized device coordinate, 0,0 is bottom-left)
scene = bpy.context.scene
up_vec = Vector((0,0,1))
up_vec.rotate(ref_ob.matrix_world)
tail_3d = ref_ob.matrix_world.to_translation() + up_vec
head_2d = world_to_camera_view(scene, cam, ref_ob.matrix_world.to_translation())
tail_2d = world_to_camera_view(scene, cam, tail_3d)
ratio = scene.render.resolution_y / scene.render.resolution_x
head_2d.y *= ratio
tail_2d.y *= ratio
vec_from_corner_2d = (tail_2d - head_2d).normalized()
up_vec_2d = Vector((0,1))
# angle = acos(up_vec_2d.dot(vec_from_corner_2d)) ## equivalent but not signed!
angle = up_vec_2d.angle_signed(vec_from_corner_2d)
## Axis camera aim (seem slightly off)
# rot_axis = Vector((0, 0, -1))
# rot_axis.rotate(cam.matrix_world)
## Axis camera origin -> pivot
rot_axis = head_world_coord - cam.matrix_world.translation
mat = rotate_matrix_around_pivot(mat, angle, head_world_coord, rot_axis)
else:
if bone:
## Use mid bone to better follow movement
mat.translation = ref_ob.matrix_world @ ((bone.tail + bone.head) / 2) # Mid bone
else:
mat.translation = ref_ob.matrix_world
## change/adapt scale
# mat_scale = Matrix.Scale(10, 4) # maybe move above mesh condition
# mat = mat @ mat_scale
obj.matrix_world = mat
def create_plane(name='Plane', collection=None):
'''Create a plane using pydata
collection: link in passed collection, else do not link in scene
@@ -335,3 +401,9 @@ def following_keys(forward=True, all_keys=False) -> list:# -> list[int] | list |
if new is None:
return []
return [int(new)]
## -- animation
def is_animated(obj):
return True