Merge pull request #382 from TwistedTwigleg/Godot_3_2_IK_Fix

Fixed GDScript IK demo so it works with Godot 3.2
This commit is contained in:
Aaron Franke
2020-02-17 18:34:54 -05:00
committed by GitHub
10 changed files with 391 additions and 208 deletions

View File

@@ -1,5 +1,6 @@
tool
extends Spatial
# A FABRIK IK chain with a middle joint helper.
# The delta/tolerance for the bone chain (how do the bones need to be before it is considered satisfactory)
@@ -189,53 +190,29 @@ func solve_chain():
# If we are using middle joint target (and have more than 2 bones), move our middle joint towards it!
if use_middle_joint_target == true:
if bone_nodes.size() > 2:
var middle_point_pos = middle_joint_target.global_transform
bone_nodes[bone_nodes.size()/2].global_transform.origin = middle_point_pos.origin
var middle_point_pos = middle_joint_target.global_transform.origin
var middle_point_pos_diff = (middle_point_pos - bone_nodes[bone_nodes.size()/2].global_transform.origin)
bone_nodes[bone_nodes.size()/2].global_transform.origin += middle_point_pos_diff.normalized()
# Get the distance from the origin to the target
var distance = (chain_origin - target_pos).length()
# Get the difference between our end effector (the final bone in the chain) and the target
var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
# If the distance is farther than our total reach, the target cannot be reached.
# Make the bone chain a straight line pointing towards the target
if distance > total_length:
for i in range (0, bones_in_chain.size()):
# Create a direct line to target and make this bone travel down that line
var curr_origin = bone_nodes[i].global_transform.origin
var r =(target_pos - curr_origin).length()
var l = bones_in_chain_lengths[i] / r
# Find new join position
var new_pos = curr_origin.linear_interpolate(target_pos, l)
# Apply it to the bone node
bone_nodes[i].look_at(new_pos, Vector3.UP)
bone_nodes[i].global_transform.origin = new_pos
# Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE).
# If it not, move the chain towards the target (going forwards, backwards, and then applying rotation)
while dif > CHAIN_TOLERANCE:
chain_backward()
chain_forward()
chain_apply_rotation()
# Apply the rotation to the first node in the bone chain, making it look at the next bone in the bone chain
bone_nodes[0].look_at(bone_nodes[1].global_transform.origin, Vector3.UP)
# If the distance is NOT farther than our total reach, the target can be reached.
else:
# Get the difference between our end effector (the final bone in the chain) and the target
var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
# Update the difference between our end effector (the final bone in the chain) and the target
dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
# Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE).
# If it not, move the chain towards the target (going forwards, backwards, and then applying rotation)
while dif > CHAIN_TOLERANCE:
chain_backward()
chain_forward()
chain_apply_rotation()
# Update the difference between our end effector (the final bone in the chain) and the target
dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
# Add one to chain_iterations. If we have reached our max iterations, then break
chain_iterations = chain_iterations + 1
if chain_iterations >= CHAIN_MAX_ITER:
break
# Add one to chain_iterations. If we have reached our max iterations, then break
chain_iterations = chain_iterations + 1
if chain_iterations >= CHAIN_MAX_ITER:
break
# Reset the bone node transforms to the skeleton bone transforms
#if constrained == false: # Resetting seems to break bone constraints...
for i in range(0, bone_nodes.size()):
var reset_bone_trans = get_bone_transform(i)
bone_nodes[i].global_transform = reset_bone_trans
@@ -307,10 +284,25 @@ func chain_apply_rotation():
# Make this bone look in the same the direction as the last bone
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
# Set the position of the bone to the bone target.
# Prior to Godot 3.2, this was not necessary, but because we can now completely
# override bone transforms, we need to set the position as well as rotation.
bone_trans.origin = b_target.origin
else:
var b_target = target.global_transform
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
bone_trans = bone_trans.looking_at(b_target.origin, Vector3.UP)
# A bit of a hack. Because we only have two bones, we have to use the previous
# bone to position the last bone in the chain.
var last_bone = bone_nodes[i-1].global_transform
# Because we know the length of adjacent bone to this bone in the chain, we can
# position this bone by taking the last bone's position plus the length of the
# bone on the Z axis.
# This will place the position of the bone at the end of the last bone
bone_trans.origin = last_bone.origin - last_bone.basis.z.normalized() * bones_in_chain_lengths[i-1]
# If this is NOT the last bone in the bone chain, rotate the bone to look at the next
# bone in the bone chain.
@@ -328,6 +320,11 @@ func chain_apply_rotation():
# Make this bone look towards the direction of the next bone
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
# Set the position of the bone to the bone target.
# Prior to Godot 3.2, this was not necessary, but because we can now completely
# override bone transforms, we need to set the position as well as rotation.
bone_trans.origin = b_target.origin
# The the bone's (updated) transform
set_bone_transform(i, bone_trans)
@@ -347,7 +344,7 @@ func get_bone_transform(bone, convert_to_world_space = true):
func set_bone_transform(bone, trans):
# Set the global transform of the bone
skeleton.set_bone_global_pose(bone_IDs[bones_in_chain[bone]], trans)
skeleton.set_bone_global_pose_override(bone_IDs[bones_in_chain[bone]], trans, 1.0, true)
############# END OF IK SOLVER RELATED FUNCTIONS #############

View File

@@ -10,10 +10,14 @@ export(bool) var use_our_rotation_y = false
export(bool) var use_our_rotation_z = false
export(bool) var use_negative_our_rot = false
export(Vector3) var additional_rotation = Vector3()
export(bool) var position_using_additional_bone = false
export(String) var additional_bone_name = ""
export(float) var additional_bone_length = 1
export(bool) var debug_messages = false
var skeleton_to_use
var first_call = true
var skeleton_to_use: Skeleton = null
var first_call: bool = true
var _editor_indicator: Spatial = null
func _ready():
@@ -63,42 +67,42 @@ func update_skeleton():
if update_mode >= 3:
return
# Get the bone
var bone = skeleton_to_use.find_bone(bone_name)
# Get the bone index.
var bone: int = skeleton_to_use.find_bone(bone_name)
# If no bone is found (-1), then return (and optionally print an error)
# If no bone is found (-1), then return and optionally print an error.
if bone == -1:
if debug_messages == true:
print (name, " - IK_LookAt: No bone in skeleton found with name [", bone_name, "]!")
return
# get the bone's rest position
# get the bone's global transform pose.
var rest = skeleton_to_use.get_bone_global_pose(bone)
# Convert our position relative to the skeleton's transform
# Convert our position relative to the skeleton's transform.
var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin)
# Call helper's look_at function with the chosen up axis.
if look_at_axis == 0:
rest = rest.looking_at(target_pos, Vector3(1, 0, 0))
rest = rest.looking_at(target_pos, Vector3.RIGHT)
elif look_at_axis == 1:
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
rest = rest.looking_at(target_pos, Vector3.UP)
elif look_at_axis == 2:
rest = rest.looking_at(target_pos, Vector3(0, 0, 1))
rest = rest.looking_at(target_pos, Vector3.FORWARD)
else:
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
rest = rest.looking_at(target_pos, Vector3.UP)
if debug_messages == true:
print (name, " - IK_LookAt: Unknown look_at_axis value!")
# Get our rotation euler, and the bone's rotation euler
# Get the rotation euler of the bone and of this node.
var rest_euler = rest.basis.get_euler()
var self_euler = global_transform.basis.orthonormalized().get_euler()
# If we using negative rotation, we flip our rotation euler
# Flip the rotation euler if using negative rotation.
if use_negative_our_rot == true:
self_euler = -self_euler
# Apply our rotation euler, if wanted/required
# Apply this node's rotation euler on each axis, if wanted/required.
if use_our_rotation_x == true:
rest_euler.x = self_euler.x
if use_our_rotation_y == true:
@@ -106,53 +110,61 @@ func update_skeleton():
if use_our_rotation_z == true:
rest_euler.z = self_euler.z
# Rotate the bone by the (potentially) changed euler angle(s)
# Make a new basis with the, potentially, changed euler angles.
rest.basis = Basis(rest_euler)
# If we have additional rotation, then rotate it by the local rotation vectors
# Apply additional rotation stored in additional_rotation to the bone.
if additional_rotation != Vector3.ZERO:
rest.basis = rest.basis.rotated(rest.basis.x, deg2rad(additional_rotation.x))
rest.basis = rest.basis.rotated(rest.basis.y, deg2rad(additional_rotation.y))
rest.basis = rest.basis.rotated(rest.basis.z, deg2rad(additional_rotation.z))
# Finally, apply the bone rotation to the skeleton
skeleton_to_use.set_bone_global_pose(bone, rest)
# If the position is set using an additional bone, then set the origin
# based on that bone and its length.
if position_using_additional_bone:
var additional_bone_id = skeleton_to_use.find_bone(additional_bone_name)
var additional_bone_pos = skeleton_to_use.get_bone_global_pose(additional_bone_id)
rest.origin = additional_bone_pos.origin - additional_bone_pos.basis.z.normalized() * additional_bone_length
# Finally, apply the new rotation to the bone in the skeleton.
skeleton_to_use.set_bone_global_pose_override(bone, rest, 1.0, true)
func _setup_for_editor():
# So we can see the target in the editor, let's create a mesh instance,
# Add it as our child, and name it
var indicator = MeshInstance.new()
add_child(indicator)
indicator.name = "(EditorOnly) Visual indicator"
# To see the target in the editor, let's create a MeshInstance,
# add it as a child of this node, and name it.
_editor_indicator = MeshInstance.new()
add_child(_editor_indicator)
_editor_indicator.name = "(EditorOnly) Visual indicator"
# We need to make a mesh for the mesh instance.
# The code below makes a small sphere mesh
# Make a sphere mesh for the MeshInstance
var indicator_mesh = SphereMesh.new()
indicator_mesh.radius = 0.1
indicator_mesh.height = 0.2
indicator_mesh.radial_segments = 8
indicator_mesh.rings = 4
# The mesh needs a material (unless we want to use the defualt one).
# Let's create a material and use the EditorGizmoTexture to texture it.
# Create a new SpatialMaterial for the sphere and give it the editor
# gizmo texture so it is textured.
var indicator_material = SpatialMaterial.new()
indicator_material.flags_unshaded = true
indicator_material.albedo_texture = preload("editor_gizmo_texture.png")
indicator_material.albedo_color = Color(1, 0.5, 0, 1)
# Assign the material and mesh to the MeshInstance.
indicator_mesh.material = indicator_material
indicator.mesh = indicator_mesh
_editor_indicator.mesh = indicator_mesh
func _set_update(new_value):
update_mode = new_value
# Set all of our processes to false
# Set all of our processes to false.
set_process(false)
set_physics_process(false)
set_notify_transform(false)
# Based on the value of upate, change how we handle updating the skeleton
# Based on the value of passed to update, enable the correct process.
if update_mode == 0:
set_process(true)
if debug_messages == true:
@@ -171,13 +183,13 @@ func _set_update(new_value):
func _set_skeleton_path(new_value):
# Because get_node doesn't work in the first call, we just want to assign instead
# This is to get around a issue with NodePaths exposed to the editor
# Because get_node doesn't work in the first call, we just want to assign instead.
# This is to get around a issue with NodePaths exposed to the editor.
if first_call == true:
skeleton_path = new_value
return
# Assign skeleton_path to whatever value is passed
# Assign skeleton_path to whatever value is passed.
skeleton_path = new_value
if skeleton_path == null:
@@ -185,15 +197,13 @@ func _set_skeleton_path(new_value):
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
return
# Get the node at that location, if there is one
# Get the node at that location, if there is one.
var temp = get_node(skeleton_path)
if temp != null:
# If the node has the method "find_bone" then we can assume it is (likely) a skeleton
if temp.has_method("find_bone") == true:
if temp is Skeleton:
skeleton_to_use = temp
if debug_messages == true:
print (name, " - IK_LookAt: attached to (new) skeleton")
# If not, then it's (likely) not a skeleton
else:
skeleton_to_use = null
if debug_messages == true:

View File

@@ -1,7 +1,14 @@
[plugin]
name="S.A.D.E (Skeleton additions and extensions)"
description="S.A.D.E is A bunch of helpful nodes designed to make using skeletons in Godot powerful and easy."
author="TwistedTwigleg"
version="0.1.1"
description="S.A.D.E is just an example plugin that adds a few nodes
to show how to create an IK system in
Godot using GDScript.
Originally Authored by TwistedTwigleg.
Developed by the Godot Community.
All assets are licensed under MIT.
"
author="Godot Community"
version="0.2.0"
script="plugin_main.gd"

View File

@@ -27,11 +27,13 @@ sky_curve = 0.25
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
sun_energy = 16.0
[sub_resource type="Environment" id=4]
background_mode = 2
background_sky = SubResource( 3 )
ambient_light_color = Color( 1, 0.909804, 0.784314, 1 )
ambient_light_energy = 1.4
ambient_light_sky_contribution = 0.72
tonemap_mode = 3
glow_enabled = true
glow_levels/1 = true
@@ -67,14 +69,14 @@ material/0 = ExtResource( 3 )
material/1 = ExtResource( 4 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.5, 8.8 )
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.5, 11 )
fov = 74.0
script = ExtResource( 5 )
MOVEMENT_SPEED = -6.0
MOVEMENT_SPEED = -8.0
flip_axis = true
[node name="targets" type="Spatial" parent="Camera"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -5.41814 )
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -8 )
[node name="IK_LookAt_Head" type="Spatial" parent="Camera/targets"]
script = ExtResource( 6 )
@@ -83,14 +85,7 @@ __meta__ = {
}
skeleton_path = NodePath("../../../BattleBot/Armature/Skeleton")
bone_name = "Head"
update_mode = 0
look_at_axis = 1
use_our_rotation_x = false
use_our_rotation_y = false
use_our_rotation_z = false
use_negative_our_rot = false
additional_rotation = Vector3( 90, 0, 0 )
debug_messages = false
[node name="IK_FABRIK_Left_Arm" type="Spatial" parent="Camera/targets"]
script = ExtResource( 8 )
@@ -100,10 +95,8 @@ __meta__ = {
skeleton_path = NodePath("../../../BattleBot/Armature/Skeleton")
bones_in_chain = PoolStringArray( "Left_UpperArm", "Left_LowerArm" )
bones_in_chain_lengths = PoolRealArray( 1.97, 3 )
update_mode = 0
chain_iterations = 10
limit_chain_iterations = false
reset_iterations_on_update = false
use_middle_joint_target = true
[node name="target" type="Spatial" parent="Camera/targets/IK_FABRIK_Left_Arm"]
@@ -117,14 +110,10 @@ __meta__ = {
}
skeleton_path = NodePath("../../../../../BattleBot/Armature/Skeleton")
bone_name = "Left_Hand"
update_mode = 0
look_at_axis = 1
use_our_rotation_x = false
use_our_rotation_y = false
use_our_rotation_z = false
use_negative_our_rot = false
additional_rotation = Vector3( 0, 0, 90 )
debug_messages = false
position_using_additional_bone = true
additional_bone_name = "Left_LowerArm"
additional_bone_length = 3.0
[node name="middle_joint_target" type="Spatial" parent="Camera/targets/IK_FABRIK_Left_Arm"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 7.16849, 0, -5.31922 )
@@ -143,10 +132,7 @@ __meta__ = {
skeleton_path = NodePath("../../../BattleBot/Armature/Skeleton")
bones_in_chain = PoolStringArray( "Right_UpperArm", "Right_LowerArm", "Right_Hand" )
bones_in_chain_lengths = PoolRealArray( 1.97, 3, 1.2 )
update_mode = 0
chain_iterations = 2
limit_chain_iterations = false
reset_iterations_on_update = false
use_middle_joint_target = true
[node name="target" type="Spatial" parent="Camera/targets/IK_FABRIK_Right_Arm"]
@@ -160,14 +146,7 @@ __meta__ = {
}
skeleton_path = NodePath("../../../../../BattleBot/Armature/Skeleton")
bone_name = "Right_Hand"
update_mode = 0
look_at_axis = 1
use_our_rotation_x = false
use_our_rotation_y = false
use_our_rotation_z = false
use_negative_our_rot = false
additional_rotation = Vector3( 0, 0, 90 )
debug_messages = false
[node name="middle_joint_target" type="Spatial" parent="Camera/targets/IK_FABRIK_Right_Arm"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -6.34515, 0, -3.7843 )
@@ -186,21 +165,28 @@ mesh = SubResource( 5 )
material/0 = SubResource( 6 )
[node name="Control" type="Control" parent="."]
margin_right = 40.0
margin_bottom = 40.0
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Panel" type="Panel" parent="Control"]
modulate = Color( 1, 1, 1, 0.784314 )
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -2.0
margin_top = 530.0
margin_right = 1028.0
margin_bottom = 600.0
margin_top = -70.0
margin_right = 4.0
[node name="Label" type="Label" parent="Control/Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 12.0
margin_top = 10.0
margin_right = 1012.0
margin_bottom = 41.0
margin_right = -18.0
margin_bottom = -29.0
text = "F.A.B.R.I.K IK
Move mouse to move IK targets
(Using 3 bones in the right hand, only 2 in the left. 3+ recommended)"
@@ -208,20 +194,27 @@ align = 1
valign = 1
[node name="Label_extra" type="Label" parent="Control/Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 12.0
margin_top = 80.0
margin_right = 1012.0
margin_bottom = 128.0
margin_right = -18.0
margin_bottom = 58.0
text = "NOTE: You will get a few errors when saving with FABRIK IK nodes in your scene
This is a known bug. Please ignore the errors for now, as they do not do anything
(They're just annoying. If you find a fix, please add it to the demo repository!)"
align = 1
valign = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label_left" type="Label" parent="Control/Panel"]
margin_left = 782.0
anchor_left = 1.0
anchor_right = 1.0
margin_left = -248.0
margin_top = 4.0
margin_right = 895.0
margin_right = -135.0
margin_bottom = 18.0
text = "Left Hand"
align = 1
@@ -235,19 +228,25 @@ text = "Right Hand"
align = 1
[node name="Button_Next" type="Button" parent="Control"]
margin_left = 900.0
margin_top = 540.0
margin_right = 1019.0
margin_bottom = 590.0
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -124.0
margin_top = -60.0
margin_right = -5.0
margin_bottom = -10.0
text = "Next scene"
script = ExtResource( 10 )
scene_to_change_to = "res://fps/fps_example.tscn"
scene_to_change_to = "res://skeleton_ik.tscn"
[node name="Button_Prev" type="Button" parent="Control"]
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = 540.0
margin_top = -60.0
margin_right = 129.0
margin_bottom = 590.0
margin_bottom = -10.0
text = "Previous scene"
script = ExtResource( 10 )
scene_to_change_to = "res://look_at_ik.tscn"

View File

@@ -49,27 +49,20 @@ sky_curve = 0.25
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
sun_energy = 16.0
[sub_resource type="Environment" id=9]
background_mode = 2
background_sky = SubResource( 8 )
ambient_light_color = Color( 1, 1, 1, 1 )
ambient_light_energy = 0.4
ambient_light_sky_contribution = 0.0
fog_depth_begin = 20.0
fog_depth_curve = 0.406126
fog_transmit_enabled = true
ambient_light_color = Color( 1, 0.909804, 0.784314, 1 )
ambient_light_energy = 1.4
ambient_light_sky_contribution = 0.72
tonemap_mode = 3
ss_reflections_max_steps = 32
ssao_enabled = true
ssao_light_affect = 1.0
glow_enabled = true
glow_levels/1 = true
glow_levels/2 = true
glow_levels/5 = false
glow_intensity = 0.6
glow_bloom = 0.06
glow_intensity = 0.2
glow_bloom = 0.03
glow_blend_mode = 0
[sub_resource type="CapsuleShape" id=10]
@@ -412,47 +405,63 @@ shadow_enabled = true
environment = SubResource( 9 )
[node name="Control" type="Control" parent="."]
margin_right = 40.0
margin_bottom = 40.0
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Panel" type="Panel" parent="Control"]
modulate = Color( 1, 1, 1, 0.784314 )
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -2.0
margin_top = 530.0
margin_right = 1028.0
margin_bottom = 600.0
margin_top = -70.0
margin_right = 4.0
[node name="Label" type="Label" parent="Control/Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 12.0
margin_top = 10.0
margin_right = 1012.0
margin_bottom = 41.0
text = "Example use case: Dynamic FPS Animations
margin_right = -18.0
margin_bottom = -29.0
text = "F.A.B.R.I.K IK Example use case: Dynamic FPS Animations
Controls: WASD/Arrows to move, left click to fire, right click to look down sights, Q/E to lean left/right
Escape to free/lock mouse cursor"
align = 1
valign = 1
[node name="Button_Prev" type="Button" parent="Control"]
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = 540.0
margin_top = -60.0
margin_right = 129.0
margin_bottom = 590.0
margin_bottom = -10.0
text = "Previous scene"
script = ExtResource( 2 )
scene_to_change_to = "res://fabrik_ik.tscn"
[node name="Crosshair" type="Control" parent="Control"]
modulate = Color( 1, 1, 1, 0.784314 )
margin_left = 492.0
margin_top = 280.0
margin_right = 532.0
margin_bottom = 320.0
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -20.0
margin_top = -20.0
margin_right = 20.0
margin_bottom = 20.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ColorRect" type="ColorRect" parent="Control/Crosshair"]
margin_left = 19.0
margin_right = 21.0
margin_bottom = 40.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ColorRect2" type="ColorRect" parent="Control/Crosshair"]
margin_left = 40.0
@@ -488,14 +497,8 @@ __meta__ = {
}
skeleton_path = NodePath("../../../../BattleBot/Armature/Skeleton")
bone_name = "Chest"
update_mode = 0
look_at_axis = 2
use_our_rotation_x = false
use_our_rotation_y = false
use_our_rotation_z = false
use_negative_our_rot = false
additional_rotation = Vector3( -10, 0, 0 )
debug_messages = false
[node name="Camera" type="Camera" parent="KinematicBody/CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest"]
transform = Transform( -1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0 )
@@ -512,10 +515,7 @@ __meta__ = {
skeleton_path = NodePath("../../../../../../BattleBot/Armature/Skeleton")
bones_in_chain = PoolStringArray( "Left_UpperArm", "Left_LowerArm", "Left_Hand" )
bones_in_chain_lengths = PoolRealArray( 1.97, 3, 0.1 )
update_mode = 0
chain_iterations = 6
limit_chain_iterations = false
reset_iterations_on_update = false
use_middle_joint_target = true
[node name="target" type="Spatial" parent="KinematicBody/CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Aim_pos/IK_FABRIK"]
@@ -529,14 +529,8 @@ __meta__ = {
}
skeleton_path = NodePath("../../../../../../../../BattleBot/Armature/Skeleton")
bone_name = "Left_Hand"
update_mode = 0
look_at_axis = 1
use_our_rotation_x = false
use_our_rotation_y = false
use_our_rotation_z = false
use_negative_our_rot = true
additional_rotation = Vector3( 0, 0, 90 )
debug_messages = false
[node name="middle_joint_target" type="Spatial" parent="KinematicBody/CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Aim_pos/IK_FABRIK"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 5.85263, -2.91316, -2.77555 )
@@ -558,10 +552,7 @@ __meta__ = {
skeleton_path = NodePath("../../../../../../BattleBot/Armature/Skeleton")
bones_in_chain = PoolStringArray( "Right_UpperArm", "Right_LowerArm", "Right_Hand" )
bones_in_chain_lengths = PoolRealArray( 1.97, 3, 0.1 )
update_mode = 0
chain_iterations = 3
limit_chain_iterations = false
reset_iterations_on_update = false
use_middle_joint_target = true
[node name="target" type="Spatial" parent="KinematicBody/CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Aim_pos/IK_FABRIK_RightArm"]
@@ -575,14 +566,8 @@ __meta__ = {
}
skeleton_path = NodePath("../../../../../../../../BattleBot/Armature/Skeleton")
bone_name = "Right_Hand"
update_mode = 0
look_at_axis = 1
use_our_rotation_x = false
use_our_rotation_y = false
use_our_rotation_z = false
use_negative_our_rot = true
additional_rotation = Vector3( 0, 0, 90 )
debug_messages = false
[node name="middle_joint_target" type="Spatial" parent="KinematicBody/CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Aim_pos/IK_FABRIK_RightArm"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -5.73318, -2.91316, -2.77555 )
@@ -606,14 +591,6 @@ __meta__ = {
}
skeleton_path = NodePath("../../../../BattleBot/Armature/Skeleton")
bone_name = "Head"
update_mode = 0
look_at_axis = 1
use_our_rotation_x = false
use_our_rotation_y = false
use_our_rotation_z = false
use_negative_our_rot = false
additional_rotation = Vector3( 0, 0, 0 )
debug_messages = false
[node name="AnimationPlayer" type="AnimationPlayer" parent="KinematicBody/CameraHolder"]
autoplay = "Start"

View File

@@ -25,11 +25,13 @@ sky_curve = 0.25
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
sun_energy = 16.0
[sub_resource type="Environment" id=4]
background_mode = 2
background_sky = SubResource( 3 )
ambient_light_color = Color( 1, 0.909804, 0.784314, 1 )
ambient_light_energy = 1.4
ambient_light_sky_contribution = 0.72
tonemap_mode = 3
glow_enabled = true
glow_levels/1 = true
@@ -58,10 +60,10 @@ material/0 = ExtResource( 3 )
material/1 = ExtResource( 4 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.5014, 8.81922 )
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.501, 11 )
fov = 74.0
script = ExtResource( 5 )
MOVEMENT_SPEED = -2.0
MOVEMENT_SPEED = -3.0
flip_axis = true
[node name="targets" type="Spatial" parent="Camera"]
@@ -93,33 +95,50 @@ bone_name = "Right_UpperArm"
additional_rotation = Vector3( 0, 0, 180 )
[node name="Control" type="Control" parent="."]
margin_right = 40.0
margin_bottom = 40.0
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Panel" type="Panel" parent="Control"]
modulate = Color( 1, 1, 1, 0.784314 )
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -2.0
margin_top = 530.0
margin_right = 1028.0
margin_bottom = 600.0
margin_top = -70.0
margin_right = 4.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="Control/Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 12.0
margin_top = 10.0
margin_right = 1012.0
margin_bottom = 41.0
margin_right = -18.0
margin_bottom = -29.0
text = "LookAt IK
Move mouse to move IK targets"
align = 1
valign = 1
[node name="Button_Next" type="Button" parent="Control"]
margin_left = 900.0
margin_top = 540.0
margin_right = 1019.0
margin_bottom = 590.0
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -124.0
margin_top = -60.0
margin_right = -5.0
margin_bottom = -10.0
text = "Next scene"
script = ExtResource( 8 )
__meta__ = {
"_edit_use_anchors_": false
}
scene_to_change_to = "res://fabrik_ik.tscn"
[editable path="BattleBot"]

View File

@@ -19,11 +19,6 @@ config/name="3D IK"
run/main_scene="res://look_at_ik.tscn"
config/icon="res://icon.png"
[display]
window/stretch/mode="2d"
window/stretch/aspect="keep"
[editor_plugins]
enabled=PoolStringArray( "sade" )

175
3d/ik/skeleton_ik.tscn Normal file
View File

@@ -0,0 +1,175 @@
[gd_scene load_steps=16 format=2]
[ext_resource path="res://skeleton_ik_runner.gd" type="Script" id=1]
[ext_resource path="res://addons/sade/ik_look_at.png" type="Texture" id=2]
[ext_resource path="res://addons/sade/editor_gizmo_texture.png" type="Texture" id=3]
[ext_resource path="res://godot_battle_bot.dae" type="PackedScene" id=4]
[ext_resource path="res://target_from_mousepos.gd" type="Script" id=5]
[ext_resource path="res://battle_bot_color.tres" type="Material" id=6]
[ext_resource path="res://battle_bot_emission.tres" type="Material" id=7]
[ext_resource path="res://button_change_scene.gd" type="Script" id=8]
[ext_resource path="res://addons/sade/ik_look_at.gd" type="Script" id=9]
[sub_resource type="PlaneMesh" id=1]
size = Vector2( 40, 40 )
[sub_resource type="SpatialMaterial" id=2]
albedo_texture = ExtResource( 3 )
roughness = 0.2
uv1_scale = Vector3( 0.25, 0.25, 0.25 )
uv1_triplanar = true
[sub_resource type="ProceduralSky" id=3]
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
sky_curve = 0.25
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
[sub_resource type="Environment" id=4]
background_mode = 2
background_sky = SubResource( 3 )
ambient_light_color = Color( 1, 0.909804, 0.784314, 1 )
ambient_light_energy = 1.4
ambient_light_sky_contribution = 0.72
tonemap_mode = 3
glow_enabled = true
glow_levels/1 = true
glow_levels/2 = true
glow_levels/5 = false
glow_intensity = 0.2
glow_bloom = 0.03
glow_blend_mode = 0
[sub_resource type="CubeMesh" id=5]
size = Vector3( 1, 1, 1 )
[sub_resource type="SpatialMaterial" id=6]
albedo_color = Color( 0, 0.191406, 0.765625, 1 )
roughness = 0.0
[node name="Skeleton_IK" type="Spatial"]
[node name="Floor_plane" type="MeshInstance" parent="."]
mesh = SubResource( 1 )
material/0 = SubResource( 2 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 0.56827, 0.673454, -0.472789, 0, 0.574581, 0.818448, 0.822842, -0.465099, 0.326517, -9.77531, 11.5204, 11.766 )
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource( 4 )
[node name="BattleBot" parent="." instance=ExtResource( 4 )]
[node name="godot_battle_bot" parent="BattleBot/Armature/Skeleton" index="0"]
material/0 = ExtResource( 6 )
material/1 = ExtResource( 7 )
[node name="SkeletonIK_Left" type="SkeletonIK" parent="BattleBot/Armature/Skeleton" index="1"]
process_priority = 1
root_bone = "Left_UpperArm"
tip_bone = "Left_Hand"
use_magnet = true
magnet = Vector3( 8, 6, 0 )
target_node = NodePath("../../../../Camera/targets/Target_Left")
script = ExtResource( 1 )
[node name="SkeletonIK_Right" type="SkeletonIK" parent="BattleBot/Armature/Skeleton" index="2"]
process_priority = 1
root_bone = "Right_UpperArm"
tip_bone = "Right_Hand"
use_magnet = true
magnet = Vector3( -8, 6, 0 )
target_node = NodePath("../../../../Camera/targets/Target_Right")
script = ExtResource( 1 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.5, 11 )
fov = 74.0
script = ExtResource( 5 )
MOVEMENT_SPEED = -8.0
flip_axis = true
[node name="targets" type="Spatial" parent="Camera"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -8 )
[node name="IK_LookAt_Head" type="Spatial" parent="Camera/targets"]
script = ExtResource( 9 )
__meta__ = {
"_editor_icon": ExtResource( 2 )
}
skeleton_path = NodePath("../../../../Skeleton_IK/BattleBot/Armature/Skeleton")
bone_name = "Head"
additional_rotation = Vector3( 90, 0, 0 )
[node name="MeshInstance" type="MeshInstance" parent="Camera/targets"]
mesh = SubResource( 5 )
material/0 = SubResource( 6 )
[node name="Target_Left" type="Position3D" parent="Camera/targets"]
transform = Transform( -0.179447, 0.98366, -0.0145678, 0.981822, 0.178142, -0.0654973, -0.0618319, -0.0260563, -0.997746, 0.653517, -0.112305, -0.760886 )
[node name="Target_Right" type="Position3D" parent="Camera/targets"]
transform = Transform( -0.0217688, 0.998559, -0.0490576, 0.992503, 0.0274873, 0.119085, 0.120262, -0.0460975, -0.991671, -0.683053, 0.0251284, -0.811513 )
[node name="Control" type="Control" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Panel" type="Panel" parent="Control"]
modulate = Color( 1, 1, 1, 0.784314 )
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -2.0
margin_top = -70.0
margin_right = 4.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="Control/Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 12.0
margin_top = 10.0
margin_right = -18.0
margin_bottom = -29.0
text = "SkeletonIK node
Move mouse to move IK targets"
align = 1
valign = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Button_Next" type="Button" parent="Control"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -124.0
margin_top = -60.0
margin_right = -5.0
margin_bottom = -10.0
text = "Next scene"
script = ExtResource( 8 )
scene_to_change_to = "res://fps/fps_example.tscn"
[node name="Button_Prev" type="Button" parent="Control"]
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = -60.0
margin_right = 129.0
margin_bottom = -10.0
text = "Previous scene"
script = ExtResource( 8 )
scene_to_change_to = "res://fabrik_ik.tscn"
[editable path="BattleBot"]

View File

@@ -0,0 +1,4 @@
extends SkeletonIK
func _ready():
start(false)

View File

@@ -1,6 +1,6 @@
extends Camera
export(float) var MOVEMENT_SPEED = 10
export(float) var MOVEMENT_SPEED = 12
export(bool) var flip_axis = false
var targets = null