add BoneFlipper for flipping bone poses
This commit is contained in:
@@ -93,7 +93,7 @@ func _ready() -> void:
|
||||
continue
|
||||
for bone_name in bone_to_flatten.bone_names:
|
||||
var bone_idx := _skeleton.find_bone(bone_name)
|
||||
assert(bone_idx != -1, bone_name + " missing!")
|
||||
assert(bone_idx != -1, str(self) + ": bone " + bone_name + " missing!")
|
||||
|
||||
|
||||
func _process_modification() -> void:
|
||||
|
||||
93
scripts/effects/bones/bone_flipper.gd
Normal file
93
scripts/effects/bones/bone_flipper.gd
Normal file
@@ -0,0 +1,93 @@
|
||||
@tool
|
||||
class_name BoneFlipper
|
||||
extends SkeletonModifier3D
|
||||
|
||||
@export var flip: bool = false
|
||||
|
||||
@export_enum(" ") var _bones_to_flip: Array[String] = []
|
||||
@export var _flip_all_bones: bool = true
|
||||
@export_enum(" ") var _bones_to_exclude: Array[String] = []
|
||||
@export var _bone_prefixes_to_exclude: Array[String] = []
|
||||
|
||||
var _skeleton: Skeleton3D
|
||||
|
||||
|
||||
func _validate_property(property: Dictionary) -> void:
|
||||
if property.name == "_bones_to_flip" or property.name == "_bones_to_exclude":
|
||||
if _skeleton:
|
||||
property.hint = PROPERTY_HINT_TYPE_STRING
|
||||
property.hint_string = (
|
||||
"%d/%d:%s"
|
||||
% [
|
||||
TYPE_STRING,
|
||||
PROPERTY_HINT_ENUM,
|
||||
_skeleton.get_concatenated_bone_names()
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_skeleton = get_skeleton()
|
||||
assert(_skeleton, str(self) + ": _skeleton missing!")
|
||||
|
||||
for bone_name in _bones_to_flip:
|
||||
var bone_idx := _skeleton.find_bone(bone_name)
|
||||
assert(bone_idx != -1, str(self) + ": bone " + bone_name + " missing!")
|
||||
for bone_name in _bones_to_exclude:
|
||||
var bone_idx := _skeleton.find_bone(bone_name)
|
||||
assert(bone_idx != -1, str(self) + ": bone " + bone_name + " missing!")
|
||||
|
||||
|
||||
func _process_modification() -> void:
|
||||
if !_skeleton or !flip:
|
||||
for bone_idx in range(_skeleton.get_bone_count()):
|
||||
_skeleton.set_bone_pose(bone_idx, _skeleton.get_bone_pose(bone_idx))
|
||||
return
|
||||
|
||||
if _flip_all_bones:
|
||||
for bone_idx in range(_skeleton.get_bone_count()):
|
||||
_flip_bone_if_not_excluded(bone_idx)
|
||||
else:
|
||||
for bone_name in _bones_to_flip:
|
||||
var bone_idx := _skeleton.find_bone(bone_name)
|
||||
if bone_idx == -1:
|
||||
continue
|
||||
_flip_bone(bone_idx, bone_name)
|
||||
|
||||
|
||||
func _flip_bone_if_not_excluded(bone_idx: int) -> void:
|
||||
var bone_name := _skeleton.get_bone_name(bone_idx)
|
||||
if bone_name in _bones_to_exclude:
|
||||
return
|
||||
for bone_prefix in _bone_prefixes_to_exclude:
|
||||
if bone_prefix and bone_name.begins_with(bone_prefix):
|
||||
return
|
||||
_flip_bone(bone_idx, bone_name)
|
||||
|
||||
|
||||
func _flip_bone(bone_idx: int, bone_name: String) -> void:
|
||||
var pose: Transform3D = _skeleton.get_bone_pose(bone_idx)
|
||||
|
||||
if bone_name.ends_with("_R") or (bone_name.ends_with("_L") and !_flip_all_bones):
|
||||
var other_side_bone_name: String = (
|
||||
bone_name.replace("_R", "_L")
|
||||
if bone_name.ends_with("_R")
|
||||
else bone_name.replace("_L", "_R")
|
||||
)
|
||||
var other_side_bone_idx := _skeleton.find_bone(other_side_bone_name)
|
||||
if other_side_bone_idx == -1:
|
||||
return
|
||||
var other_side_pose: Transform3D = _skeleton.get_bone_pose(other_side_bone_idx)
|
||||
_mirror_bone_transform(bone_idx, other_side_pose)
|
||||
_mirror_bone_transform(other_side_bone_idx, pose)
|
||||
elif !bone_name.ends_with("_R") and !bone_name.ends_with("_L"):
|
||||
_mirror_bone_transform(bone_idx, pose)
|
||||
|
||||
|
||||
func _mirror_bone_transform(bone_idx: int, pose: Transform3D) -> void:
|
||||
pose.origin.x = -pose.origin.x
|
||||
var pose_rot := pose.basis.get_euler()
|
||||
pose_rot.z = -pose_rot.z
|
||||
pose_rot.y = -pose_rot.y
|
||||
pose.basis = Basis.from_euler(pose_rot)
|
||||
_skeleton.set_bone_pose(bone_idx, pose)
|
||||
1
scripts/effects/bones/bone_flipper.gd.uid
Normal file
1
scripts/effects/bones/bone_flipper.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bmbbkpkqtugwy
|
||||
Reference in New Issue
Block a user