diff --git a/3d/ik/addons/sade/ik_fabrik.gd b/3d/ik/addons/sade/ik_fabrik.gd index f972c014..cd3263c1 100644 --- a/3d/ik/addons/sade/ik_fabrik.gd +++ b/3d/ik/addons/sade/ik_fabrik.gd @@ -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 ############# diff --git a/3d/ik/addons/sade/ik_look_at.gd b/3d/ik/addons/sade/ik_look_at.gd index 802f4b2e..e0875e21 100644 --- a/3d/ik/addons/sade/ik_look_at.gd +++ b/3d/ik/addons/sade/ik_look_at.gd @@ -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: diff --git a/3d/ik/addons/sade/plugin.cfg b/3d/ik/addons/sade/plugin.cfg index e6aed4cf..dfbec35a 100644 --- a/3d/ik/addons/sade/plugin.cfg +++ b/3d/ik/addons/sade/plugin.cfg @@ -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" diff --git a/3d/ik/fabrik_ik.tscn b/3d/ik/fabrik_ik.tscn index 4839465d..485bc404 100644 --- a/3d/ik/fabrik_ik.tscn +++ b/3d/ik/fabrik_ik.tscn @@ -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" diff --git a/3d/ik/fps/fps_example.tscn b/3d/ik/fps/fps_example.tscn index 8d7bffbd..dab2bb07 100644 --- a/3d/ik/fps/fps_example.tscn +++ b/3d/ik/fps/fps_example.tscn @@ -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" diff --git a/3d/ik/look_at_ik.tscn b/3d/ik/look_at_ik.tscn index 1b6ad770..ee909ee4 100644 --- a/3d/ik/look_at_ik.tscn +++ b/3d/ik/look_at_ik.tscn @@ -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"] diff --git a/3d/ik/project.godot b/3d/ik/project.godot index 176cf6fb..abcf5706 100644 --- a/3d/ik/project.godot +++ b/3d/ik/project.godot @@ -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" ) diff --git a/3d/ik/skeleton_ik.tscn b/3d/ik/skeleton_ik.tscn new file mode 100644 index 00000000..6dd7dd47 --- /dev/null +++ b/3d/ik/skeleton_ik.tscn @@ -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"] diff --git a/3d/ik/skeleton_ik_runner.gd b/3d/ik/skeleton_ik_runner.gd new file mode 100644 index 00000000..de6e43fc --- /dev/null +++ b/3d/ik/skeleton_ik_runner.gd @@ -0,0 +1,4 @@ +extends SkeletonIK + +func _ready(): + start(false) diff --git a/3d/ik/target_from_mousepos.gd b/3d/ik/target_from_mousepos.gd index 396e3a93..84045f44 100644 --- a/3d/ik/target_from_mousepos.gd +++ b/3d/ik/target_from_mousepos.gd @@ -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