X-Git-Url: http://git.purplebirdman.com/william-skin.git/blobdiff_plain/c84055968443414e67caa33c3a823094ed29365b..c3805c44927b9c7945d932a4c602fbbf6cb0dcb8:/TrackingBone3D.gd diff --git a/TrackingBone3D.gd b/TrackingBone3D.gd index a4ba007..a417f61 100644 --- a/TrackingBone3D.gd +++ b/TrackingBone3D.gd @@ -4,13 +4,15 @@ class_name TrackingBone3D extends SkeletonModifier3D enum Axis { - X_plus, Y_plus, Z_plus + X_plus, Y_plus, Z_plus, X_minus, Y_minus, Z_minus } @export_enum(" ") var bone: String @export var aim_axis := Axis.Z_plus -@export var pivot_axis := Axis.Y_plus -@export var target: Vector3 = Vector3(0, 0, 0) +@export var target: Node3D = null + +var _skeleton: Skeleton3D +var _bone_idx: int func _validate_property(property: Dictionary) -> void: @@ -21,38 +23,47 @@ func _validate_property(property: Dictionary) -> void: property.hint_string = skeleton.get_concatenated_bone_names() -func _process_modification() -> void: - var skeleton: Skeleton3D = get_skeleton() - if !skeleton: - return # Never happen, but for the safety. - var bone_idx: int = skeleton.find_bone(bone) - var _parent_idx: int = skeleton.get_bone_parent(bone_idx) - var pose: Transform3D = skeleton.global_transform * skeleton.get_bone_global_pose(bone_idx) +func _ready() -> void: + # for tweening bone poses + _skeleton = get_skeleton() + if not _skeleton: + push_error("Expected a skeleton!") + _bone_idx = _skeleton.find_bone(bone) + +func _process_modification() -> void: + if target == null: + return + + var pose: Transform3D = _skeleton.global_transform * _skeleton.get_bone_global_pose(_bone_idx) var looked_at: Transform3D = _w_look_at(pose) - #var looked_at: Transform3D = pose.looking_at(target, Vector3.UP) - #var axis: Vector3 = looked_at.basis.y - #looked_at = looked_at.rotated(axis, PI) - skeleton.set_bone_global_pose( - bone_idx, + _skeleton.set_bone_global_pose( + _bone_idx, Transform3D( - (skeleton.global_transform.affine_inverse() * looked_at).basis.orthonormalized(), - skeleton.get_bone_global_pose(bone_idx).origin + (_skeleton.global_transform.affine_inverse() * looked_at).basis.orthonormalized(), + _skeleton.get_bone_global_pose(_bone_idx).origin ) ) func _w_look_at(from: Transform3D) -> Transform3D: - # y look is default - var w: Vector3 = from.basis.x + var w: Vector3 - if aim_axis == Axis.X_plus: + if aim_axis == Axis.Y_plus: + w = from.basis.x + elif aim_axis == Axis.X_plus: w = from.basis.z elif aim_axis == Axis.Z_plus: w = from.basis.y + elif aim_axis == Axis.Y_minus: + w = w.inverse() + elif aim_axis == Axis.X_minus: + w = from.basis.y.inverse() + elif aim_axis == Axis.Z_minus: + w = from.basis.y.inverse() - var t_v: Vector3 = target - from.origin + var t_v: Vector3 = target.global_position - from.origin var v_y: Vector3 = t_v.normalized() var v_z: Vector3 = w.cross(v_y) v_z = v_z.normalized()