]> Untitled Git - william-skin.git/blob - TrackingBone3D.gd
a4ba0075749d25a67e74e41590372df8fb57ef58
[william-skin.git] / TrackingBone3D.gd
1 @tool
2
3 class_name TrackingBone3D
4 extends SkeletonModifier3D
5
6 enum Axis {
7         X_plus, Y_plus, Z_plus
8 }
9
10 @export_enum(" ") var bone: String
11 @export var aim_axis := Axis.Z_plus
12 @export var pivot_axis := Axis.Y_plus
13 @export var target: Vector3 = Vector3(0, 0, 0)
14
15
16 func _validate_property(property: Dictionary) -> void:
17         if property.name == "bone":
18                 var skeleton: Skeleton3D = get_skeleton()
19                 if skeleton:
20                         property.hint = PROPERTY_HINT_ENUM
21                         property.hint_string = skeleton.get_concatenated_bone_names()
22
23
24 func _process_modification() -> void:
25         var skeleton: Skeleton3D = get_skeleton()
26         if !skeleton:
27                 return # Never happen, but for the safety.
28         var bone_idx: int = skeleton.find_bone(bone)
29         var _parent_idx: int = skeleton.get_bone_parent(bone_idx)
30         var pose: Transform3D = skeleton.global_transform * skeleton.get_bone_global_pose(bone_idx)
31         
32         var looked_at: Transform3D = _w_look_at(pose)
33         #var looked_at: Transform3D = pose.looking_at(target, Vector3.UP)
34         #var axis: Vector3 = looked_at.basis.y
35         #looked_at = looked_at.rotated(axis, PI)
36         
37         skeleton.set_bone_global_pose(
38                 bone_idx,
39                 Transform3D(
40                         (skeleton.global_transform.affine_inverse() * looked_at).basis.orthonormalized(), 
41                         skeleton.get_bone_global_pose(bone_idx).origin
42                         )
43                 )
44
45
46 func _w_look_at(from: Transform3D) -> Transform3D:
47         # y look is default
48         var w: Vector3 = from.basis.x
49         
50         if aim_axis == Axis.X_plus:
51                 w = from.basis.z
52         elif aim_axis == Axis.Z_plus:
53                 w = from.basis.y
54         
55         var t_v: Vector3 = target - from.origin
56         var v_y: Vector3 = t_v.normalized()
57         var v_z: Vector3 = w.cross(v_y)
58         v_z = v_z.normalized()
59         var v_x: Vector3 = v_y.cross(v_z)
60         from.basis = Basis(v_x, v_y, v_z)
61         return from