Merge pull request #226 from TwistedTwigleg/3D_IK_Demo
3D IK demo (fixed)
BIN
3d/ik/GunMaterial.material
Normal file
597
3d/ik/addons/sade/IK_FABRIK.gd
Normal file
@@ -0,0 +1,597 @@
|
||||
tool
|
||||
extends Spatial
|
||||
|
||||
"""
|
||||
A FABRIK IK chain with a middle joint helper.
|
||||
"""
|
||||
|
||||
export (NodePath) var skeleton_path setget _set_skeleton_path
|
||||
export (PoolStringArray) var bones_in_chain setget _set_bone_chain_bones
|
||||
export (PoolRealArray) var bones_in_chain_lengths setget _set_bone_chain_lengths
|
||||
|
||||
export (int, "_process", "_physics_process", "_notification", "none") var update_mode = 0 setget _set_update_mode
|
||||
|
||||
var target = null
|
||||
|
||||
var skeleton
|
||||
|
||||
# A dictionary holding all of the bone IDs (from the skeleton) and a dictionary holding
|
||||
# all of the bone helper nodes
|
||||
var bone_IDs = {}
|
||||
var bone_nodes = {}
|
||||
|
||||
# The position of the origin
|
||||
var chain_origin = null
|
||||
# The combined length of every bone in the bone chain
|
||||
var total_length = null
|
||||
# The delta/tolerance for the bone chain (how do the bones need to be before it is considered satisfactory)
|
||||
const CHAIN_TOLERANCE = 0.01
|
||||
# The amount of interations the bone chain will go through in an attempt to get to the target position
|
||||
const CHAIN_MAX_ITER = 10
|
||||
# The amount of iterations we've been through, and whether or not we want to limit our solver to CHAIN_MAX_ITER
|
||||
# amounts of interations.
|
||||
export (int) var chain_iterations = 0
|
||||
export (bool) var limit_chain_iterations = true
|
||||
# Should we reset chain_iterations on movement during our update method?
|
||||
export (bool) var reset_iterations_on_update = false
|
||||
|
||||
# A boolean to track whether or not we want to move the middle joint towards middle joint target.
|
||||
export (bool) var use_middle_joint_target = false
|
||||
var middle_joint_target = null
|
||||
|
||||
# NOT WORKING.
|
||||
# A boolean to track whether or not we want to constrain the bones in the bone chain.
|
||||
#export (bool) var constrained = false
|
||||
# A array of strings contraining the bone constraints for each bone (assuming the order is the same
|
||||
# as bones_in_chain). (ORDER: Left,Right,Up,Down)
|
||||
#export (PoolStringArray) var bone_constraints
|
||||
|
||||
# Have we called _set_skeleton_path or not already. Due to some issues using exported NodePaths,
|
||||
# we need to ignore the first _set_skeleton_path call.
|
||||
var first_call = true
|
||||
|
||||
# A boolean to track whether or not we want to print debug messages
|
||||
var debug_messages = false
|
||||
|
||||
func _ready():
|
||||
|
||||
if (target == null):
|
||||
# NOTE: you HAVE to have a node called target as a child of this node!
|
||||
# so we create one if one doesn't already exist
|
||||
if has_node("target") == false:
|
||||
target = Spatial.new()
|
||||
add_child(target)
|
||||
|
||||
if Engine.editor_hint == true:
|
||||
if get_tree() != null:
|
||||
if get_tree().edited_scene_root != null:
|
||||
target.set_owner(get_tree().edited_scene_root)
|
||||
|
||||
target.name = "target"
|
||||
else:
|
||||
target = get_node("target")
|
||||
|
||||
# If we are in the editor, we want to make a sphere at this node
|
||||
if Engine.editor_hint == true:
|
||||
_make_editor_sphere_at_node(target, Color(1, 0, 1, 1))
|
||||
|
||||
if middle_joint_target == null:
|
||||
if has_node("middle_joint_target") == false:
|
||||
middle_joint_target = Spatial.new()
|
||||
add_child(middle_joint_target)
|
||||
|
||||
if Engine.editor_hint == true:
|
||||
if get_tree() != null:
|
||||
if get_tree().edited_scene_root != null:
|
||||
middle_joint_target.set_owner(get_tree().edited_scene_root)
|
||||
|
||||
middle_joint_target.name = "middle_joint_target"
|
||||
else:
|
||||
middle_joint_target = get_node("middle_joint_target")
|
||||
|
||||
# If we are in the editor, we want to make a sphere at this node
|
||||
if Engine.editor_hint == true:
|
||||
_make_editor_sphere_at_node(middle_joint_target, Color(1, 0.24, 1, 1))
|
||||
|
||||
# Make all of the bone nodes for each bone in the IK chain
|
||||
_make_bone_nodes()
|
||||
|
||||
# Make sure we're using the right update mode
|
||||
_set_update_mode(update_mode)
|
||||
|
||||
|
||||
func _make_editor_sphere_at_node(node, color):
|
||||
# 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()
|
||||
node.add_child(indicator)
|
||||
indicator.name = "(EditorOnly) Visual indicator"
|
||||
|
||||
# We need to make a mesh for the mesh instance.
|
||||
# The code below makes a small sphere mesh
|
||||
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.
|
||||
var indicator_material = SpatialMaterial.new()
|
||||
indicator_material.flags_unshaded = true
|
||||
indicator_material.albedo_texture = preload("editor_gizmo_texture.png")
|
||||
indicator_material.albedo_color = color
|
||||
indicator_mesh.material = indicator_material
|
||||
indicator.mesh = indicator_mesh
|
||||
|
||||
|
||||
############# SETGET FUNCTIONS #############
|
||||
|
||||
|
||||
func _set_update_mode(new_value):
|
||||
update_mode = new_value
|
||||
|
||||
set_process(false)
|
||||
set_physics_process(false)
|
||||
set_notify_transform(false)
|
||||
|
||||
if update_mode == 0:
|
||||
set_process(true)
|
||||
elif update_mode == 1:
|
||||
set_process(true)
|
||||
elif update_mode == 2:
|
||||
set_notify_transform(true)
|
||||
else:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: Unknown update mode. NOT updating skeleton")
|
||||
return
|
||||
|
||||
|
||||
func _set_skeleton_path(new_value):
|
||||
|
||||
# Because get_node doesn't work in the first call, we just want to assign instead
|
||||
if first_call == true:
|
||||
skeleton_path = new_value
|
||||
return
|
||||
|
||||
skeleton_path = new_value
|
||||
|
||||
if skeleton_path == null:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
||||
return
|
||||
|
||||
var temp = get_node(skeleton_path)
|
||||
if temp != null:
|
||||
# If it has the method "get_bone_global_pose" it is likely a Skeleton
|
||||
if temp.has_method("get_bone_global_pose") == true:
|
||||
skeleton = temp
|
||||
bone_IDs = {}
|
||||
|
||||
# (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain
|
||||
_make_bone_nodes()
|
||||
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: Attached to a new skeleton")
|
||||
# If not, then it's (likely) not a Skeleton node
|
||||
else:
|
||||
skeleton = null
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: skeleton_path does not point to a skeleton!")
|
||||
else:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
||||
|
||||
############# OTHER (NON IK SOLVER RELATED) FUNCTIONS #############
|
||||
|
||||
|
||||
func _make_bone_nodes():
|
||||
# Remove all of the old bone nodes
|
||||
# TODO: (not a huge concern, as these can be removed in the editor)
|
||||
|
||||
for bone in range(0, bones_in_chain.size()):
|
||||
|
||||
var bone_name = bones_in_chain[bone]
|
||||
if has_node(bone_name) == false:
|
||||
var new_node = Spatial.new()
|
||||
bone_nodes[bone] = new_node
|
||||
add_child(bone_nodes[bone])
|
||||
|
||||
if Engine.editor_hint == true:
|
||||
if get_tree() != null:
|
||||
if get_tree().edited_scene_root != null:
|
||||
bone_nodes[bone].set_owner(get_tree().edited_scene_root)
|
||||
|
||||
bone_nodes[bone].name = bone_name
|
||||
|
||||
else:
|
||||
bone_nodes[bone] = get_node(bone_name)
|
||||
|
||||
# If we are in the editor, we want to make a sphere at this node
|
||||
if Engine.editor_hint == true:
|
||||
_make_editor_sphere_at_node(bone_nodes[bone], Color(0.65, 0, 1, 1))
|
||||
|
||||
|
||||
func _set_bone_chain_bones(new_value):
|
||||
bones_in_chain = new_value
|
||||
|
||||
_make_bone_nodes()
|
||||
|
||||
func _set_bone_chain_lengths(new_value):
|
||||
bones_in_chain_lengths = new_value
|
||||
total_length = null
|
||||
|
||||
|
||||
# NOT USED -- part of the (not working) constraint system
|
||||
"""
|
||||
func get_bone_constraints(index):
|
||||
# NOTE: assumed angle constraint order:
|
||||
# Left angle in degrees, right angle in degrees, up angle in degress, down angle in degrees.
|
||||
if index <= bones_in_chain.size()-1:
|
||||
var index_str = bone_constraints[index]
|
||||
var floats = index_str.split_floats(",", false)
|
||||
if (floats.size() >= 4):
|
||||
return floats
|
||||
else:
|
||||
print (self.name, " - IK_FABRIK: Not all constraints are present for bone number ", index, " found!")
|
||||
return null
|
||||
|
||||
print (self.name, " - IK_FABRIK: No constraints for bone number ", index, " found!")
|
||||
return null
|
||||
"""
|
||||
|
||||
|
||||
# Various upate methods
|
||||
# ---------------------
|
||||
func _process(delta):
|
||||
if reset_iterations_on_update == true:
|
||||
chain_iterations = 0
|
||||
update_skeleton()
|
||||
func _physics_process(delta):
|
||||
if reset_iterations_on_update == true:
|
||||
chain_iterations = 0
|
||||
update_skeleton()
|
||||
func _notification(what):
|
||||
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
||||
if reset_iterations_on_update == true:
|
||||
chain_iterations = 0
|
||||
update_skeleton()
|
||||
|
||||
|
||||
############# IK SOLVER RELATED FUNCTIONS #############
|
||||
|
||||
func update_skeleton():
|
||||
|
||||
#### ERROR CHECKING conditions
|
||||
if first_call == true:
|
||||
_set_skeleton_path(skeleton_path)
|
||||
first_call = false
|
||||
|
||||
if skeleton == null:
|
||||
_set_skeleton_path(skeleton_path)
|
||||
|
||||
return
|
||||
|
||||
if bones_in_chain == null:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: No Bones in IK chain defined!")
|
||||
return
|
||||
if bones_in_chain_lengths == null:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: No Bone lengths in IK chain defined!")
|
||||
return
|
||||
|
||||
if bones_in_chain.size() != bones_in_chain_lengths.size():
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_FABRIK: bones_in_chain and bones_in_chain_lengths!")
|
||||
return
|
||||
|
||||
################################
|
||||
|
||||
# Set all of the bone IDs in bone_IDs, if they are not already made
|
||||
var i = 0
|
||||
if bone_IDs.size() <= 0:
|
||||
for bone_name in bones_in_chain:
|
||||
bone_IDs[bone_name] = skeleton.find_bone(bone_name)
|
||||
|
||||
# Set the bone node to the currect bone position
|
||||
bone_nodes[i].global_transform = get_bone_transform(i)
|
||||
# If this is not the last bone in the bone chain, make it look at the next bone in the bone chain
|
||||
if i < bone_IDs.size()-1:
|
||||
bone_nodes[i].look_at(get_bone_transform(i+1).origin + skeleton.global_transform.origin, Vector3(0, 1, 0))
|
||||
|
||||
i += 1
|
||||
|
||||
# Set the total length of the bone chain, if it is not already set
|
||||
if total_length == null:
|
||||
total_length = 0
|
||||
for bone_length in bones_in_chain_lengths:
|
||||
total_length += bone_length
|
||||
|
||||
|
||||
# Solve the bone chain
|
||||
solve_chain()
|
||||
|
||||
|
||||
|
||||
func solve_chain():
|
||||
|
||||
# If we have reached our max chain iteration, and we are limiting ourselves, then return.
|
||||
# Otherwise set chain_iterations to zero (so we constantly update)
|
||||
if chain_iterations >= CHAIN_MAX_ITER and limit_chain_iterations == true:
|
||||
return
|
||||
else:
|
||||
chain_iterations = 0
|
||||
|
||||
# Update the origin with the current bone's origin
|
||||
chain_origin = get_bone_transform(0)
|
||||
|
||||
# Get the direction of the final bone by using the next to last bone if there is more than 2 bones.
|
||||
# If there are only 2 bones, we use the target's forward Z vector instead (not ideal, but it works fairly well)
|
||||
#var dir = -target.global_transform.basis.z.normalized()
|
||||
var dir
|
||||
if bone_nodes.size() > 2:
|
||||
dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized()
|
||||
else:
|
||||
dir = -target.global_transform.basis.z.normalized()
|
||||
|
||||
# Get the target position (accounting for the final bone and it's length)
|
||||
var target_pos = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
||||
|
||||
# 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
|
||||
|
||||
# Get the distance from the origin to the target
|
||||
var distance = (chain_origin.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 r = (target_pos - bone_nodes[i].global_transform.origin).length()
|
||||
var l = bones_in_chain_lengths[i] / r
|
||||
|
||||
# Find new join position
|
||||
var new_pos = (1-l) * bone_nodes[i].global_transform.origin + l * target_pos
|
||||
|
||||
# Apply it to the bone node
|
||||
bone_nodes[i].look_at(new_pos, Vector3(0, 1, 0))
|
||||
bone_nodes[i].global_transform.origin = new_pos
|
||||
|
||||
# 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(0, 1, 0))
|
||||
|
||||
# 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()
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
func chain_backward():
|
||||
# Backward reaching pass
|
||||
|
||||
#var dir = -target.global_transform.basis.z.normalized()
|
||||
|
||||
# Get the direction of the final bone by using the next to last bone if there is more than 2 bones.
|
||||
# If there are only 2 bones, we use the target's forward Z vector instead (not ideal, but it works fairly well)
|
||||
var dir
|
||||
if bone_nodes.size() > 2:
|
||||
dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized()
|
||||
else:
|
||||
dir = -target.global_transform.basis.z.normalized()
|
||||
|
||||
# Set the position of the end effector (the final bone in the chain) to the target position
|
||||
bone_nodes[bone_nodes.size()-1].global_transform.origin = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
||||
|
||||
# For all of the other bones, move them towards the target
|
||||
var i = bones_in_chain.size() - 1
|
||||
while i >= 1:
|
||||
|
||||
i -= 1
|
||||
|
||||
var r = bone_nodes[i+1].global_transform.origin - bone_nodes[i].global_transform.origin
|
||||
var l = bones_in_chain_lengths[i] / r.length()
|
||||
# Apply the new joint position
|
||||
bone_nodes[i].global_transform.origin = (1 - l) * bone_nodes[i+1].global_transform.origin + l * bone_nodes[i].global_transform.origin
|
||||
|
||||
|
||||
func chain_forward():
|
||||
# Forward reaching pass
|
||||
|
||||
# Set root at initial position
|
||||
bone_nodes[0].global_transform.origin = chain_origin.origin
|
||||
|
||||
# Go through every bone in the bone chain
|
||||
var i = 0
|
||||
while i < bones_in_chain.size() - 1:
|
||||
|
||||
var r = (bone_nodes[i+1].global_transform.origin - bone_nodes[i].global_transform.origin)
|
||||
var l = bones_in_chain_lengths[i] / r.length()
|
||||
|
||||
# Set the new joint position
|
||||
var new_pos = (1 - l) * bone_nodes[i].global_transform.origin + l * bone_nodes[i+1].global_transform.origin
|
||||
|
||||
# Apply constraints (if we have them)
|
||||
# NOTE: this does not work. It is left in as an example to help others if they decide to add constraints
|
||||
"""
|
||||
if (constrained == true):
|
||||
|
||||
var cf = bone_nodes[i].global_transform
|
||||
cf = cf.looking_at(bone_nodes[i+1].global_transform.origin, Vector3(0, 1, 0))
|
||||
|
||||
var line = (new_pos - bone_nodes[i+1].global_transform.origin).normalized() * bones_in_chain_lengths[i]
|
||||
|
||||
new_pos += chain_constrain(new_pos, line, cf, i+1)
|
||||
"""
|
||||
|
||||
# Apply the new joint position, (potentially with constraints), to the bone node
|
||||
bone_nodes[i+1].global_transform.origin = new_pos
|
||||
|
||||
i += 1
|
||||
|
||||
|
||||
|
||||
# NOT USED -- part of the (not working) constraint system
|
||||
"""
|
||||
func chain_constrain(calc, line, cf, bone):
|
||||
var scalar = calc.dot(line) / line.length()
|
||||
var proj = scalar * line.normalized()
|
||||
# NOTE: Something in the calculation for proj may be wrong.
|
||||
|
||||
# get axis that is closest
|
||||
# NOTE: Not sure if we need to do a calculation or not. For now, we are just going to use Basis
|
||||
var tmp = cf.looking_at(cf.origin - Vector3(0, 1, 0), Vector3(1, 0, 0))
|
||||
var upvec = cf.basis.x
|
||||
tmp = cf.looking_at(cf.origin - Vector3(1, 0, 0), Vector3(0, 1, 0))
|
||||
var rightvec = cf.basis.z
|
||||
|
||||
|
||||
# Get the vector from the projection to the calculated vector
|
||||
var adjust = calc - proj
|
||||
if scalar > 0:
|
||||
# If we are below the cone, flip the projection vector
|
||||
proj = -proj
|
||||
pass
|
||||
|
||||
# Get the 2D components
|
||||
var xaspect = adjust.dot(rightvec)
|
||||
var yaspect = adjust.dot(upvec)
|
||||
|
||||
# Get the cross section of the cone
|
||||
var constraint_angles = get_bone_constraints(bone)
|
||||
var left = -(proj.length() * tan(deg2rad(constraint_angles[0])) )
|
||||
var right = (proj.length() * tan(deg2rad(constraint_angles[1])) )
|
||||
var up = (proj.length() * tan(deg2rad(constraint_angles[2])) )
|
||||
var down = -(proj.length() * tan(deg2rad(constraint_angles[3])) )
|
||||
|
||||
# Find the quadrant
|
||||
var xbound = xaspect >= 0 and right or left
|
||||
var ybound = yaspect >= 0 and up or down
|
||||
|
||||
if xbound == true:
|
||||
xbound = 1
|
||||
else:
|
||||
xbound = 0
|
||||
if ybound == true:
|
||||
ybound = 1
|
||||
else:
|
||||
ybound = 0
|
||||
|
||||
|
||||
var f = calc
|
||||
# Check if in 2D point lies in the ellipse
|
||||
var ellipse = pow(xaspect, 2)/pow(xbound, 2) + pow(yaspect, 2)/pow(ybound, 2)
|
||||
var inbounds = ellipse <= 1 and scalar >= 0
|
||||
|
||||
if not inbounds:
|
||||
# Get the angle of our out of ellipse point
|
||||
var a = atan2(yaspect, xaspect)
|
||||
# Find the nearest point
|
||||
var x = xbound * cos(a)
|
||||
var y = ybound * sin(a)
|
||||
# Convert back to 3D
|
||||
#f = (proj + rightvec * x + upvec * y ).normalized() * calc.length()
|
||||
f = (proj + rightvec * x + upvec * y ).normalized() * bones_in_chain_lengths[bone]
|
||||
|
||||
return f
|
||||
"""
|
||||
|
||||
|
||||
func chain_apply_rotation():
|
||||
# Make all of the bones rotated correctly.
|
||||
|
||||
# For each bone in the bone chain
|
||||
for i in range(0, bones_in_chain.size()):
|
||||
|
||||
# Get the bone's transform, NOT converted to world space
|
||||
var bone_trans = get_bone_transform(i, false)
|
||||
|
||||
# If this is the last bone in the bone chain, rotate the bone so it faces
|
||||
# the same direction as the next to last bone in the bone chain if there are more than
|
||||
# two bones. If there are only two bones, rotate the end effector towards the target
|
||||
if i == bones_in_chain.size()-1:
|
||||
|
||||
if bones_in_chain.size() > 2:
|
||||
# Get the bone node for this bone, and the previous bone
|
||||
var b_target = bone_nodes[i].global_transform
|
||||
var b_target_two = bone_nodes[i-1].global_transform
|
||||
|
||||
# Convert the bone nodes positions from world space to bone/skeleton space
|
||||
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
||||
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
|
||||
|
||||
# Get the direction that the previous bone is pointing towards
|
||||
var dir = (target.global_transform.origin - b_target_two.origin).normalized()
|
||||
|
||||
# Make this bone look in the same the direction as the last bone
|
||||
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3(0, 1, 0))
|
||||
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(0, 1, 0))
|
||||
|
||||
# If this is NOT the last bone in the bone chain, rotate the bone to look at the next
|
||||
# bone in the bone chain.
|
||||
else:
|
||||
# Get the bone node for this bone, and the next bone
|
||||
var b_target = bone_nodes[i].global_transform
|
||||
var b_target_two = bone_nodes[i+1].global_transform
|
||||
|
||||
# Convert the bone nodes positions from world space to bone/skeleton space
|
||||
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
||||
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
|
||||
|
||||
# Get the direction towards the next bone
|
||||
var dir = (b_target_two.origin - b_target.origin).normalized()
|
||||
|
||||
# Make this bone look towards the direction of the next bone
|
||||
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3(0, 1, 0))
|
||||
|
||||
# The the bone's (updated) transform
|
||||
set_bone_transform(i, bone_trans)
|
||||
|
||||
|
||||
func get_bone_transform(bone, convert_to_world_space=true):
|
||||
|
||||
# Get the global transform of the bone
|
||||
var ret = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]])
|
||||
|
||||
# If we need to convert the bone position from bone/skeleton space to world space, we
|
||||
# use the Xform of the skeleton (because bone/skeleton space is relative to the position of the skeleton node).
|
||||
if convert_to_world_space == true:
|
||||
ret.origin = skeleton.global_transform.xform(ret.origin)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
BIN
3d/ik/addons/sade/editor_gizmo_texture.png
Normal file
|
After Width: | Height: | Size: 180 B |
33
3d/ik/addons/sade/editor_gizmo_texture.png.import
Normal file
@@ -0,0 +1,33 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path.s3tc="res://.import/editor_gizmo_texture.png-be14d96c2d7829c8511766ceb15d5a7f.s3tc.stex"
|
||||
path.etc2="res://.import/editor_gizmo_texture.png-be14d96c2d7829c8511766ceb15d5a7f.etc2.stex"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/sade/editor_gizmo_texture.png"
|
||||
source_md5="14289d2a3712e442d3d3adf307a54241"
|
||||
|
||||
dest_files=[ "res://.import/editor_gizmo_texture.png-be14d96c2d7829c8511766ceb15d5a7f.s3tc.stex", "res://.import/editor_gizmo_texture.png-be14d96c2d7829c8511766ceb15d5a7f.etc2.stex" ]
|
||||
dest_md5="3279a3a982c66d6f404c81517b218531"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=true
|
||||
flags/filter=false
|
||||
flags/mipmaps=true
|
||||
flags/anisotropic=false
|
||||
flags/srgb=1
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=false
|
||||
svg/scale=1.0
|
||||
BIN
3d/ik/addons/sade/ik_fabrik.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
32
3d/ik/addons/sade/ik_fabrik.png.import
Normal file
@@ -0,0 +1,32 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ik_fabrik.png-c3d637ec075c87710a4a8abbfbd526e1.stex"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SADE/ik_fabrik.png"
|
||||
source_md5="2909090602f64d38ce0bb7314ec7b39d"
|
||||
|
||||
dest_files=[ "res://.import/ik_fabrik.png-c3d637ec075c87710a4a8abbfbd526e1.stex" ]
|
||||
dest_md5="80bbb72f55f6ea1f119b08dc61b9526e"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
205
3d/ik/addons/sade/ik_look_at.gd
Normal file
@@ -0,0 +1,205 @@
|
||||
tool
|
||||
extends Spatial
|
||||
|
||||
export (NodePath) var skeleton_path setget _set_skeleton_path
|
||||
export (String) var bone_name = ""
|
||||
export (int, "_process", "_physics_process", "_notification", "none") var update_mode = 0 setget _set_update
|
||||
export (int, "X-up", "Y-up", "Z-up") var look_at_axis = 1
|
||||
export (bool) var use_our_rot_x = false
|
||||
export (bool) var use_our_rot_y = false
|
||||
export (bool) var use_our_rot_z = false
|
||||
export (bool) var use_negative_our_rot = false
|
||||
export (Vector3) var additional_rotation = Vector3()
|
||||
export (bool) var debug_messages = false
|
||||
|
||||
var skeleton_to_use
|
||||
var first_call = true
|
||||
const empty_vector = Vector3()
|
||||
|
||||
func _ready():
|
||||
|
||||
set_process(false)
|
||||
set_physics_process(false)
|
||||
set_notify_transform(false)
|
||||
|
||||
if update_mode == 0:
|
||||
set_process(true)
|
||||
elif update_mode == 1:
|
||||
set_physics_process(true)
|
||||
elif update_mode == 2:
|
||||
set_notify_transform(true)
|
||||
else:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: Unknown update mode. NOT updating skeleton")
|
||||
|
||||
if Engine.editor_hint == true:
|
||||
_setup_for_editor()
|
||||
|
||||
|
||||
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"
|
||||
|
||||
# We need to make a mesh for the mesh instance.
|
||||
# The code below makes a small sphere mesh
|
||||
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.
|
||||
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)
|
||||
indicator_mesh.material = indicator_material
|
||||
indicator.mesh = indicator_mesh
|
||||
|
||||
|
||||
func _set_update(new_value):
|
||||
update_mode = new_value
|
||||
|
||||
# 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
|
||||
if update_mode == 0:
|
||||
set_process(true)
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: updating skeleton using _process...")
|
||||
elif update_mode == 1:
|
||||
set_physics_process(true)
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: updating skeleton using _physics_process...")
|
||||
elif update_mode == 2:
|
||||
set_notify_transform(true)
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: updating skeleton using _notification...")
|
||||
else:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: NOT updating skeleton due to unknown update method...")
|
||||
|
||||
|
||||
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
|
||||
if first_call == true:
|
||||
skeleton_path = new_value
|
||||
return
|
||||
|
||||
# Assign skeleton_path to whatever value is passed
|
||||
skeleton_path = new_value
|
||||
|
||||
if skeleton_path == null:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
||||
return
|
||||
|
||||
# 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:
|
||||
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:
|
||||
print (name, " - IK_LookAt: skeleton_path does not point to a skeleton!")
|
||||
else:
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
||||
|
||||
|
||||
func update_skeleton():
|
||||
|
||||
# NOTE: Because get_node doesn't work in _ready, we need to skip
|
||||
# a call before doing anything.
|
||||
if first_call == true:
|
||||
first_call = false
|
||||
if skeleton_to_use == null:
|
||||
_set_skeleton_path(skeleton_path)
|
||||
|
||||
|
||||
# If we do not have a skeleton and/or we're not supposed to update, then return.
|
||||
if skeleton_to_use == null:
|
||||
return
|
||||
if update_mode >= 3:
|
||||
return
|
||||
|
||||
# Get the bone
|
||||
var bone = skeleton_to_use.find_bone(bone_name)
|
||||
|
||||
# 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, and our position
|
||||
var rest = skeleton_to_use.get_bone_global_pose(bone)
|
||||
var our_position = global_transform.origin
|
||||
|
||||
# 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))
|
||||
elif look_at_axis == 1:
|
||||
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
|
||||
elif look_at_axis == 2:
|
||||
rest = rest.looking_at(target_pos, Vector3(0, 0, 1))
|
||||
else:
|
||||
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
|
||||
if debug_messages == true:
|
||||
print (name, " - IK_LookAt: Unknown look_at_axis value!")
|
||||
|
||||
# Get our rotation euler, and the bone's rotation euler
|
||||
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
|
||||
if use_negative_our_rot == true:
|
||||
self_euler = -self_euler
|
||||
|
||||
# Apply our rotation euler, if wanted/required
|
||||
if use_our_rot_x == true:
|
||||
rest_euler.x = self_euler.x
|
||||
if use_our_rot_y == true:
|
||||
rest_euler.y = self_euler.y
|
||||
if use_our_rot_z == true:
|
||||
rest_euler.z = self_euler.z
|
||||
|
||||
# Rotate the bone by the (potentially) changed euler angle(s)
|
||||
rest.basis = Basis(rest_euler)
|
||||
|
||||
# If we have additional rotation, then rotate it by the local rotation vectors
|
||||
if additional_rotation != empty_vector:
|
||||
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)
|
||||
|
||||
|
||||
# Various upate methods
|
||||
# ---------------------
|
||||
func _process(delta):
|
||||
update_skeleton()
|
||||
func _physics_process(delta):
|
||||
update_skeleton()
|
||||
func _notification(what):
|
||||
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
||||
update_skeleton()
|
||||
BIN
3d/ik/addons/sade/ik_look_at.png
Normal file
|
After Width: | Height: | Size: 328 B |
32
3d/ik/addons/sade/ik_look_at.png.import
Normal file
@@ -0,0 +1,32 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ik_look_at.png-ec8164b5f09a539e05ec8153e50e1d99.stex"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SADE/ik_look_at.png"
|
||||
source_md5="49fed7fb3ba1856215d1f334ed8bc583"
|
||||
|
||||
dest_files=[ "res://.import/ik_look_at.png-ec8164b5f09a539e05ec8153e50e1d99.stex" ]
|
||||
dest_md5="690d9e1323d33b31eefd4014776d78d4"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
7
3d/ik/addons/sade/plugin.cfg
Normal file
@@ -0,0 +1,7 @@
|
||||
[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.0"
|
||||
script="plugin_main.gd"
|
||||
21
3d/ik/addons/sade/plugin_main.gd
Normal file
@@ -0,0 +1,21 @@
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
func _enter_tree():
|
||||
# Plugin Initialization here!
|
||||
|
||||
# ------ IK STUFF ------
|
||||
add_custom_type("IK_LookAt", "Spatial", preload("ik_look_at.gd"), preload("ik_look_at.png"))
|
||||
add_custom_type("IK_FABRIK", "Spatial", preload("ik_fabrik.gd"), preload("ik_fabrik.png"))
|
||||
# ------ ---------- ------
|
||||
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
# Plugin Clean-up here!
|
||||
|
||||
# ------ IK STUFF ------
|
||||
remove_custom_type("IK_LookAt")
|
||||
remove_custom_type("IK_FABRIK")
|
||||
# ------ ---------- ------
|
||||
|
||||
BIN
3d/ik/battle_bot_colors.material
Normal file
BIN
3d/ik/battle_bot_emission.material
Normal file
10
3d/ik/button_change_scene.gd
Normal file
@@ -0,0 +1,10 @@
|
||||
extends Button
|
||||
|
||||
export (String, FILE) var scene_to_change_to = null
|
||||
|
||||
func _ready():
|
||||
connect("pressed", self, "change_scene")
|
||||
|
||||
func change_scene():
|
||||
if scene_to_change_to != null:
|
||||
get_tree().change_scene(scene_to_change_to)
|
||||
101
3d/ik/default_env.tres
Normal file
@@ -0,0 +1,101 @@
|
||||
[gd_resource type="Environment" load_steps=2 format=2]
|
||||
|
||||
[sub_resource type="ProceduralSky" id=1]
|
||||
|
||||
radiance_size = 4
|
||||
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
|
||||
sky_energy = 1.0
|
||||
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
|
||||
ground_energy = 1.0
|
||||
sun_color = Color( 1, 1, 1, 1 )
|
||||
sun_latitude = 35.0
|
||||
sun_longitude = 0.0
|
||||
sun_angle_min = 1.0
|
||||
sun_angle_max = 100.0
|
||||
sun_curve = 0.05
|
||||
sun_energy = 16.0
|
||||
texture_size = 2
|
||||
|
||||
[resource]
|
||||
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 1 )
|
||||
background_sky_custom_fov = 0.0
|
||||
background_color = Color( 0, 0, 0, 1 )
|
||||
background_energy = 1.0
|
||||
background_canvas_max_layer = 0
|
||||
ambient_light_color = Color( 0, 0, 0, 1 )
|
||||
ambient_light_energy = 1.0
|
||||
ambient_light_sky_contribution = 1.0
|
||||
fog_enabled = false
|
||||
fog_color = Color( 0.5, 0.6, 0.7, 1 )
|
||||
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
|
||||
fog_sun_amount = 0.0
|
||||
fog_depth_enabled = true
|
||||
fog_depth_begin = 10.0
|
||||
fog_depth_curve = 1.0
|
||||
fog_transmit_enabled = false
|
||||
fog_transmit_curve = 1.0
|
||||
fog_height_enabled = false
|
||||
fog_height_min = 0.0
|
||||
fog_height_max = 100.0
|
||||
fog_height_curve = 1.0
|
||||
tonemap_mode = 0
|
||||
tonemap_exposure = 1.0
|
||||
tonemap_white = 1.0
|
||||
auto_exposure_enabled = false
|
||||
auto_exposure_scale = 0.4
|
||||
auto_exposure_min_luma = 0.05
|
||||
auto_exposure_max_luma = 8.0
|
||||
auto_exposure_speed = 0.5
|
||||
ss_reflections_enabled = false
|
||||
ss_reflections_max_steps = 64
|
||||
ss_reflections_fade_in = 0.15
|
||||
ss_reflections_fade_out = 2.0
|
||||
ss_reflections_depth_tolerance = 0.2
|
||||
ss_reflections_roughness = true
|
||||
ssao_enabled = false
|
||||
ssao_radius = 1.0
|
||||
ssao_intensity = 1.0
|
||||
ssao_radius2 = 0.0
|
||||
ssao_intensity2 = 1.0
|
||||
ssao_bias = 0.01
|
||||
ssao_light_affect = 0.0
|
||||
ssao_color = Color( 0, 0, 0, 1 )
|
||||
ssao_quality = 0
|
||||
ssao_blur = 3
|
||||
ssao_edge_sharpness = 4.0
|
||||
dof_blur_far_enabled = false
|
||||
dof_blur_far_distance = 10.0
|
||||
dof_blur_far_transition = 5.0
|
||||
dof_blur_far_amount = 0.1
|
||||
dof_blur_far_quality = 1
|
||||
dof_blur_near_enabled = false
|
||||
dof_blur_near_distance = 2.0
|
||||
dof_blur_near_transition = 1.0
|
||||
dof_blur_near_amount = 0.1
|
||||
dof_blur_near_quality = 1
|
||||
glow_enabled = false
|
||||
glow_levels/1 = false
|
||||
glow_levels/2 = false
|
||||
glow_levels/3 = true
|
||||
glow_levels/4 = false
|
||||
glow_levels/5 = true
|
||||
glow_levels/6 = false
|
||||
glow_levels/7 = false
|
||||
glow_intensity = 0.8
|
||||
glow_strength = 1.0
|
||||
glow_bloom = 0.0
|
||||
glow_blend_mode = 2
|
||||
glow_hdr_threshold = 1.0
|
||||
glow_hdr_scale = 2.0
|
||||
glow_bicubic_upscale = false
|
||||
adjustment_enabled = false
|
||||
adjustment_brightness = 1.0
|
||||
adjustment_contrast = 1.0
|
||||
adjustment_saturation = 1.0
|
||||
|
||||
241
3d/ik/example_player.gd
Normal file
@@ -0,0 +1,241 @@
|
||||
extends KinematicBody
|
||||
|
||||
# Walking variables.
|
||||
const norm_grav = -38.8
|
||||
var vel = Vector3()
|
||||
const MAX_SPEED = 22
|
||||
const JUMP_SPEED = 26
|
||||
const ACCEL= 8.5
|
||||
|
||||
# A vector for storing the direction the player intends to walk towards.
|
||||
var dir = Vector3()
|
||||
|
||||
# Sprinting variables. Similar to the varibles above, just allowing for quicker movement
|
||||
const MAX_SPRINT_SPEED = 34
|
||||
const SPRINT_ACCEL = 18
|
||||
# A boolean to track whether or not we are sprinting
|
||||
var is_sprinting = false
|
||||
|
||||
# How fast we slow down, and the steepest angle we can climb.
|
||||
const DEACCEL= 28
|
||||
const MAX_SLOPE_ANGLE = 40
|
||||
|
||||
# We need the camera for getting directional vectors. We rotate ourselves on the Y-axis using
|
||||
# the camera_holder to avoid rotating on more than one axis at a time.
|
||||
var camera
|
||||
var camera_holder
|
||||
# You may need to adjust depending on the sensitivity of your mouse
|
||||
var MOUSE_SENSITIVITY = 0.08
|
||||
|
||||
# A boolean for tracking whether the jump button is down
|
||||
var jump_button_down = false
|
||||
|
||||
# The current lean value (our position on the lean track) and the path follow node
|
||||
var lean_value = 0.5
|
||||
var path_follow_node = null
|
||||
|
||||
# A variable for tracking if the right mouse button is down.
|
||||
var right_mouse_down = false
|
||||
# A variable for tracking if we can fire using the left mouse button
|
||||
var left_mouse_timer = 0
|
||||
const LEFT_MOUSE_FIRE_TIME = 0.15
|
||||
# How fast the bullets launch
|
||||
const BULLET_SPEED = 100
|
||||
|
||||
# The animation player for aiming down the sights
|
||||
var anim_player = null
|
||||
# A boolean for tracking whether we can change animations or not
|
||||
var anim_done = true
|
||||
# The current animation name
|
||||
var current_anim = "Starter"
|
||||
|
||||
# The end of the pistol
|
||||
var pistol_end = null
|
||||
# The simple bullet rigidbody
|
||||
var simple_bullet = preload("res://simple_bullet.tscn")
|
||||
|
||||
|
||||
func _ready():
|
||||
|
||||
camera = get_node("CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Camera")
|
||||
camera_holder = get_node("CameraHolder")
|
||||
path_follow_node = get_node("CameraHolder/Lean_Path/PathFollow")
|
||||
|
||||
anim_player = get_node("CameraHolder/AnimationPlayer")
|
||||
anim_player.connect("animation_finished", self, "animation_finished")
|
||||
|
||||
pistol_end = get_node("CameraHolder/Weapon/Pistol/Pistol_end")
|
||||
|
||||
set_physics_process(true)
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
set_process_input(true)
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
process_input(delta)
|
||||
process_movement(delta)
|
||||
|
||||
|
||||
func process_input(delta):
|
||||
|
||||
# Reset dir, so our previous movement does not effect us
|
||||
dir = Vector3()
|
||||
# Get the camera's global transform so we can use its directional vectors
|
||||
var cam_xform = camera.get_global_transform()
|
||||
|
||||
# ----------------------------------
|
||||
# Walking
|
||||
if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_W):
|
||||
dir += -cam_xform.basis[2]
|
||||
if Input.is_key_pressed(KEY_DOWN) or Input.is_key_pressed(KEY_S):
|
||||
dir += cam_xform.basis[2]
|
||||
if Input.is_key_pressed(KEY_LEFT) or Input.is_key_pressed(KEY_A):
|
||||
dir += -cam_xform.basis[0]
|
||||
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
|
||||
dir += cam_xform.basis[0]
|
||||
|
||||
if Input.is_action_just_pressed("ui_cancel"):
|
||||
if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
else:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
|
||||
if Input.is_mouse_button_pressed(2):
|
||||
if right_mouse_down == false:
|
||||
right_mouse_down = true
|
||||
|
||||
if anim_done == true:
|
||||
if current_anim != "Aiming":
|
||||
anim_player.play("Aiming")
|
||||
current_anim = "Aiming"
|
||||
else:
|
||||
anim_player.play("Idle")
|
||||
current_anim = "Idle"
|
||||
|
||||
anim_done = false
|
||||
else:
|
||||
right_mouse_down = false
|
||||
|
||||
if Input.is_mouse_button_pressed(1):
|
||||
if left_mouse_timer <= 0:
|
||||
left_mouse_timer = LEFT_MOUSE_FIRE_TIME
|
||||
|
||||
# Create a bullet
|
||||
var new_bullet = simple_bullet.instance()
|
||||
get_tree().root.add_child(new_bullet)
|
||||
new_bullet.global_transform = pistol_end.global_transform
|
||||
new_bullet.linear_velocity = new_bullet.global_transform.basis.z * BULLET_SPEED
|
||||
if left_mouse_timer > 0:
|
||||
left_mouse_timer -= delta
|
||||
# ----------------------------------
|
||||
|
||||
|
||||
# ----------------------------------
|
||||
# Sprinting
|
||||
if Input.is_key_pressed(KEY_SHIFT):
|
||||
is_sprinting = true
|
||||
else:
|
||||
is_sprinting = false
|
||||
# ----------------------------------
|
||||
|
||||
# ----------------------------------
|
||||
# Jumping
|
||||
if Input.is_key_pressed(KEY_SPACE):
|
||||
if jump_button_down == false:
|
||||
jump_button_down = true
|
||||
if is_on_floor():
|
||||
vel.y = JUMP_SPEED
|
||||
else:
|
||||
jump_button_down = false
|
||||
# ----------------------------------
|
||||
|
||||
|
||||
# ----------------------------------
|
||||
# Leaninng
|
||||
if Input.is_key_pressed(KEY_Q):
|
||||
lean_value += 1.2 * delta
|
||||
elif Input.is_key_pressed(KEY_E):
|
||||
lean_value -= 1.2 * delta
|
||||
else:
|
||||
if lean_value > 0.5:
|
||||
lean_value -= 1 * delta
|
||||
if lean_value < 0.5:
|
||||
lean_value = 0.5
|
||||
elif lean_value < 0.5:
|
||||
lean_value += 1 * delta
|
||||
if lean_value > 0.5:
|
||||
lean_value = 0.5
|
||||
|
||||
lean_value = clamp(lean_value, 0, 1)
|
||||
path_follow_node.unit_offset = lean_value
|
||||
if lean_value < 0.5:
|
||||
var lerp_value = lean_value * 2
|
||||
path_follow_node.rotation_degrees.z = (20 * (1 - lerp_value))
|
||||
else:
|
||||
var lerp_value = (lean_value - 0.5) * 2
|
||||
path_follow_node.rotation_degrees.z = (-20 * lerp_value)
|
||||
# ----------------------------------
|
||||
|
||||
|
||||
func process_movement(delta):
|
||||
|
||||
var grav = norm_grav
|
||||
|
||||
dir.y = 0
|
||||
dir = dir.normalized()
|
||||
|
||||
vel.y += delta*grav
|
||||
|
||||
var hvel = vel
|
||||
hvel.y = 0
|
||||
|
||||
var target = dir
|
||||
if is_sprinting:
|
||||
target *= MAX_SPRINT_SPEED
|
||||
else:
|
||||
target *= MAX_SPEED
|
||||
|
||||
|
||||
var accel
|
||||
if dir.dot(hvel) > 0:
|
||||
if is_sprinting == false:
|
||||
accel = ACCEL
|
||||
else:
|
||||
accel = SPRINT_ACCEL
|
||||
else:
|
||||
accel = DEACCEL
|
||||
|
||||
hvel = hvel.linear_interpolate(target, accel*delta)
|
||||
|
||||
vel.x = hvel.x
|
||||
vel.z = hvel.z
|
||||
|
||||
vel = move_and_slide(vel,Vector3(0,1,0))
|
||||
|
||||
|
||||
# Mouse based camera movement
|
||||
func _input(event):
|
||||
|
||||
if event is InputEventMouseMotion && Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
||||
|
||||
rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
|
||||
camera_holder.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
|
||||
|
||||
# We need to clamp the camera's rotation so we cannot rotate ourselves upside down
|
||||
var camera_rot = camera_holder.rotation_degrees
|
||||
if camera_rot.x < -40:
|
||||
camera_rot.x = -40
|
||||
elif camera_rot.x > 60:
|
||||
camera_rot.x = 60
|
||||
|
||||
camera_holder.rotation_degrees = camera_rot
|
||||
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
func animation_finished(anim):
|
||||
anim_done = true
|
||||
|
||||
|
||||
|
||||
629
3d/ik/fabrik_ik.tscn
Normal file
@@ -0,0 +1,629 @@
|
||||
[gd_scene load_steps=15 format=2]
|
||||
|
||||
[ext_resource path="res://addons/sade/editor_gizmo_texture.png" type="Texture" id=1]
|
||||
[ext_resource path="res://godot_battle_bot.dae" type="PackedScene" id=2]
|
||||
[ext_resource path="res://Target_From_MousePos.gd" type="Script" id=3]
|
||||
[ext_resource path="res://addons/sade/ik_look_at.gd" type="Script" id=4]
|
||||
[ext_resource path="res://addons/sade/ik_look_at.png" type="Texture" id=5]
|
||||
[ext_resource path="res://addons/SADE/IK_FABRIK.gd" type="Script" id=6]
|
||||
[ext_resource path="res://addons/SADE/IK_FABRIK.png" type="Texture" id=7]
|
||||
[ext_resource path="res://Button_Change_Scene.gd" type="Script" id=8]
|
||||
|
||||
[sub_resource type="PlaneMesh" id=1]
|
||||
|
||||
size = Vector2( 40, 40 )
|
||||
subdivide_width = 0
|
||||
subdivide_depth = 0
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=2]
|
||||
|
||||
render_priority = 0
|
||||
flags_transparent = false
|
||||
flags_unshaded = false
|
||||
flags_vertex_lighting = false
|
||||
flags_no_depth_test = false
|
||||
flags_use_point_size = false
|
||||
flags_world_triplanar = false
|
||||
flags_fixed_size = false
|
||||
flags_albedo_tex_force_srgb = false
|
||||
vertex_color_use_as_albedo = false
|
||||
vertex_color_is_srgb = false
|
||||
params_diffuse_mode = 0
|
||||
params_specular_mode = 0
|
||||
params_blend_mode = 0
|
||||
params_cull_mode = 0
|
||||
params_depth_draw_mode = 0
|
||||
params_line_width = 1.0
|
||||
params_point_size = 1.0
|
||||
params_billboard_mode = 0
|
||||
params_grow = false
|
||||
params_use_alpha_scissor = false
|
||||
albedo_color = Color( 1, 1, 1, 1 )
|
||||
albedo_texture = ExtResource( 1 )
|
||||
metallic = 0.0
|
||||
metallic_specular = 0.5
|
||||
metallic_texture_channel = 0
|
||||
roughness = 0.2
|
||||
roughness_texture_channel = 0
|
||||
emission_enabled = false
|
||||
normal_enabled = false
|
||||
rim_enabled = false
|
||||
clearcoat_enabled = false
|
||||
anisotropy_enabled = false
|
||||
ao_enabled = false
|
||||
depth_enabled = false
|
||||
subsurf_scatter_enabled = false
|
||||
transmission_enabled = false
|
||||
refraction_enabled = false
|
||||
detail_enabled = false
|
||||
uv1_scale = Vector3( 0.25, 0.25, 0.25 )
|
||||
uv1_offset = Vector3( 0, 0, 0 )
|
||||
uv1_triplanar = true
|
||||
uv1_triplanar_sharpness = 1.0
|
||||
uv2_scale = Vector3( 1, 1, 1 )
|
||||
uv2_offset = Vector3( 0, 0, 0 )
|
||||
uv2_triplanar = false
|
||||
uv2_triplanar_sharpness = 1.0
|
||||
proximity_fade_enable = false
|
||||
distance_fade_enable = false
|
||||
_sections_unfolded = [ "UV1" ]
|
||||
|
||||
[sub_resource type="ProceduralSky" id=3]
|
||||
|
||||
radiance_size = 4
|
||||
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
|
||||
sky_energy = 1.0
|
||||
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
|
||||
ground_energy = 1.0
|
||||
sun_color = Color( 1, 1, 1, 1 )
|
||||
sun_latitude = 35.0
|
||||
sun_longitude = 0.0
|
||||
sun_angle_min = 1.0
|
||||
sun_angle_max = 100.0
|
||||
sun_curve = 0.05
|
||||
sun_energy = 16.0
|
||||
texture_size = 2
|
||||
|
||||
[sub_resource type="Environment" id=4]
|
||||
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 3 )
|
||||
background_sky_custom_fov = 0.0
|
||||
background_color = Color( 0, 0, 0, 1 )
|
||||
background_energy = 1.0
|
||||
background_canvas_max_layer = 0
|
||||
ambient_light_color = Color( 0, 0, 0, 1 )
|
||||
ambient_light_energy = 1.0
|
||||
ambient_light_sky_contribution = 1.0
|
||||
fog_enabled = false
|
||||
fog_color = Color( 0.5, 0.6, 0.7, 1 )
|
||||
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
|
||||
fog_sun_amount = 0.0
|
||||
fog_depth_enabled = true
|
||||
fog_depth_begin = 10.0
|
||||
fog_depth_curve = 1.0
|
||||
fog_transmit_enabled = false
|
||||
fog_transmit_curve = 1.0
|
||||
fog_height_enabled = false
|
||||
fog_height_min = 0.0
|
||||
fog_height_max = 100.0
|
||||
fog_height_curve = 1.0
|
||||
tonemap_mode = 3
|
||||
tonemap_exposure = 1.0
|
||||
tonemap_white = 1.0
|
||||
auto_exposure_enabled = false
|
||||
auto_exposure_scale = 0.4
|
||||
auto_exposure_min_luma = 0.05
|
||||
auto_exposure_max_luma = 8.0
|
||||
auto_exposure_speed = 0.5
|
||||
ss_reflections_enabled = false
|
||||
ss_reflections_max_steps = 64
|
||||
ss_reflections_fade_in = 0.15
|
||||
ss_reflections_fade_out = 2.0
|
||||
ss_reflections_depth_tolerance = 0.2
|
||||
ss_reflections_roughness = true
|
||||
ssao_enabled = false
|
||||
ssao_radius = 1.0
|
||||
ssao_intensity = 1.0
|
||||
ssao_radius2 = 0.0
|
||||
ssao_intensity2 = 1.0
|
||||
ssao_bias = 0.01
|
||||
ssao_light_affect = 0.0
|
||||
ssao_color = Color( 0, 0, 0, 1 )
|
||||
ssao_quality = 0
|
||||
ssao_blur = 3
|
||||
ssao_edge_sharpness = 4.0
|
||||
dof_blur_far_enabled = false
|
||||
dof_blur_far_distance = 10.0
|
||||
dof_blur_far_transition = 5.0
|
||||
dof_blur_far_amount = 0.1
|
||||
dof_blur_far_quality = 1
|
||||
dof_blur_near_enabled = false
|
||||
dof_blur_near_distance = 2.0
|
||||
dof_blur_near_transition = 1.0
|
||||
dof_blur_near_amount = 0.1
|
||||
dof_blur_near_quality = 1
|
||||
glow_enabled = true
|
||||
glow_levels/1 = true
|
||||
glow_levels/2 = true
|
||||
glow_levels/3 = true
|
||||
glow_levels/4 = false
|
||||
glow_levels/5 = false
|
||||
glow_levels/6 = false
|
||||
glow_levels/7 = false
|
||||
glow_intensity = 0.2
|
||||
glow_strength = 1.0
|
||||
glow_bloom = 0.03
|
||||
glow_blend_mode = 0
|
||||
glow_hdr_threshold = 1.0
|
||||
glow_hdr_scale = 2.0
|
||||
glow_bicubic_upscale = false
|
||||
adjustment_enabled = false
|
||||
adjustment_brightness = 1.0
|
||||
adjustment_contrast = 1.0
|
||||
adjustment_saturation = 1.0
|
||||
_sections_unfolded = [ "Glow", "Glow/levels" ]
|
||||
|
||||
[sub_resource type="CubeMesh" id=5]
|
||||
|
||||
size = Vector3( 1, 1, 1 )
|
||||
subdivide_width = 0
|
||||
subdivide_height = 0
|
||||
subdivide_depth = 0
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=6]
|
||||
|
||||
render_priority = 0
|
||||
flags_transparent = false
|
||||
flags_unshaded = false
|
||||
flags_vertex_lighting = false
|
||||
flags_no_depth_test = false
|
||||
flags_use_point_size = false
|
||||
flags_world_triplanar = false
|
||||
flags_fixed_size = false
|
||||
flags_albedo_tex_force_srgb = false
|
||||
vertex_color_use_as_albedo = false
|
||||
vertex_color_is_srgb = false
|
||||
params_diffuse_mode = 0
|
||||
params_specular_mode = 0
|
||||
params_blend_mode = 0
|
||||
params_cull_mode = 0
|
||||
params_depth_draw_mode = 0
|
||||
params_line_width = 1.0
|
||||
params_point_size = 1.0
|
||||
params_billboard_mode = 0
|
||||
params_grow = false
|
||||
params_use_alpha_scissor = false
|
||||
albedo_color = Color( 0, 0.191406, 0.765625, 1 )
|
||||
metallic = 0.0
|
||||
metallic_specular = 0.5
|
||||
metallic_texture_channel = 0
|
||||
roughness = 0.0
|
||||
roughness_texture_channel = 0
|
||||
emission_enabled = false
|
||||
normal_enabled = false
|
||||
rim_enabled = false
|
||||
clearcoat_enabled = false
|
||||
anisotropy_enabled = false
|
||||
ao_enabled = false
|
||||
depth_enabled = false
|
||||
subsurf_scatter_enabled = false
|
||||
transmission_enabled = false
|
||||
refraction_enabled = false
|
||||
detail_enabled = false
|
||||
uv1_scale = Vector3( 1, 1, 1 )
|
||||
uv1_offset = Vector3( 0, 0, 0 )
|
||||
uv1_triplanar = false
|
||||
uv1_triplanar_sharpness = 1.0
|
||||
uv2_scale = Vector3( 1, 1, 1 )
|
||||
uv2_offset = Vector3( 0, 0, 0 )
|
||||
uv2_triplanar = false
|
||||
uv2_triplanar_sharpness = 1.0
|
||||
proximity_fade_enable = false
|
||||
distance_fade_enable = false
|
||||
_sections_unfolded = [ "Albedo" ]
|
||||
|
||||
[node name="FABRIK_IK" type="Spatial"]
|
||||
|
||||
[node name="Floor_plane" type="MeshInstance" parent="." index="0"]
|
||||
|
||||
layers = 1
|
||||
material_override = null
|
||||
cast_shadow = 1
|
||||
extra_cull_margin = 0.0
|
||||
use_in_baked_light = false
|
||||
lod_min_distance = 0.0
|
||||
lod_min_hysteresis = 0.0
|
||||
lod_max_distance = 0.0
|
||||
lod_max_hysteresis = 0.0
|
||||
mesh = SubResource( 1 )
|
||||
skeleton = NodePath("..")
|
||||
material/0 = SubResource( 2 )
|
||||
_sections_unfolded = [ "material" ]
|
||||
|
||||
[node name="DirectionalLight" type="DirectionalLight" parent="." index="1"]
|
||||
|
||||
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 )
|
||||
layers = 1
|
||||
light_color = Color( 1, 1, 1, 1 )
|
||||
light_energy = 1.0
|
||||
light_indirect_energy = 1.0
|
||||
light_negative = false
|
||||
light_specular = 0.5
|
||||
light_bake_mode = 1
|
||||
light_cull_mask = -1
|
||||
shadow_enabled = false
|
||||
shadow_color = Color( 0, 0, 0, 1 )
|
||||
shadow_bias = 0.1
|
||||
shadow_contact = 0.0
|
||||
shadow_reverse_cull_face = false
|
||||
editor_only = false
|
||||
directional_shadow_mode = 2
|
||||
directional_shadow_split_1 = 0.1
|
||||
directional_shadow_split_2 = 0.2
|
||||
directional_shadow_split_3 = 0.5
|
||||
directional_shadow_blend_splits = false
|
||||
directional_shadow_normal_bias = 0.8
|
||||
directional_shadow_bias_split_scale = 0.25
|
||||
directional_shadow_depth_range = 0
|
||||
directional_shadow_max_distance = 200.0
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." index="2"]
|
||||
|
||||
environment = SubResource( 4 )
|
||||
|
||||
[node name="BattleBot" parent="." index="3" instance=ExtResource( 2 )]
|
||||
|
||||
editor/display_folded = true
|
||||
|
||||
[node name="Camera" type="Camera" parent="." index="4"]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.5014, 8.81922 )
|
||||
keep_aspect = 1
|
||||
cull_mask = 1048575
|
||||
environment = null
|
||||
h_offset = 0.0
|
||||
v_offset = 0.0
|
||||
doppler_tracking = 0
|
||||
projection = 0
|
||||
current = false
|
||||
fov = 70.0
|
||||
size = 1.0
|
||||
near = 0.05
|
||||
far = 100.0
|
||||
script = ExtResource( 3 )
|
||||
MOVEMENT_SPEED = -6.0
|
||||
flip_axis = true
|
||||
|
||||
[node name="targets" type="Spatial" parent="Camera" index="0"]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -5.41814 )
|
||||
|
||||
[node name="IK_LookAt_Head" type="Spatial" parent="Camera/targets" index="0"]
|
||||
|
||||
script = ExtResource( 4 )
|
||||
_sections_unfolded = [ "Transform" ]
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 5 )
|
||||
}
|
||||
skeleton_path = NodePath("../../../BattleBot/Armature/Skeleton")
|
||||
bone_name = "Head"
|
||||
update_mode = 0
|
||||
look_at_axis = 1
|
||||
use_our_rot_x = false
|
||||
use_our_rot_y = false
|
||||
use_our_rot_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" index="1"]
|
||||
|
||||
editor/display_folded = true
|
||||
script = ExtResource( 6 )
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 7 )
|
||||
}
|
||||
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" index="0"]
|
||||
|
||||
editor/display_folded = true
|
||||
transform = Transform( 0.518503, 0, -0.855076, 0, 1, 0, 0.855076, 0, 0.518503, 1.13159, 0, -0.155596 )
|
||||
|
||||
[node name="IK_LookAt_LH" type="Spatial" parent="Camera/targets/IK_FABRIK_Left_Arm/target" index="0"]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.343393, -0.133381, 0.836605 )
|
||||
script = ExtResource( 4 )
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 5 )
|
||||
}
|
||||
skeleton_path = NodePath("../../../../../BattleBot/Armature/Skeleton")
|
||||
bone_name = "Left_Hand"
|
||||
update_mode = 0
|
||||
look_at_axis = 1
|
||||
use_our_rot_x = false
|
||||
use_our_rot_y = false
|
||||
use_our_rot_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_Left_Arm" index="1"]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 7.16849, 0, -5.31922 )
|
||||
|
||||
[node name="Left_UpperArm" type="Spatial" parent="Camera/targets/IK_FABRIK_Left_Arm" index="2"]
|
||||
|
||||
transform = Transform( -0.66477, 0.0771345, -0.743055, -2.23517e-08, 0.994655, 0.103252, 0.747048, 0.0686391, -0.661217, 1.53444, 0.300478, -3.63533 )
|
||||
|
||||
[node name="Left_LowerArm" type="Spatial" parent="Camera/targets/IK_FABRIK_Left_Arm" index="3"]
|
||||
|
||||
transform = Transform( -0.773624, -0.0228999, 0.633231, 2.98023e-08, 0.999347, 0.03614, -0.633645, 0.0279588, -0.773119, 2.94998, 0.10378, -2.37569 )
|
||||
|
||||
[node name="IK_FABRIK_Right_Arm" type="Spatial" parent="Camera/targets" index="2"]
|
||||
|
||||
editor/display_folded = true
|
||||
script = ExtResource( 6 )
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 7 )
|
||||
}
|
||||
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" index="0"]
|
||||
|
||||
editor/display_folded = true
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.229958, 0, 0.929313 )
|
||||
|
||||
[node name="IK_LookAt_RH" type="Spatial" parent="Camera/targets/IK_FABRIK_Right_Arm/target" index="0"]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0544824, -0.133381, 0.332403 )
|
||||
script = ExtResource( 4 )
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 5 )
|
||||
}
|
||||
skeleton_path = NodePath("../../../../../BattleBot/Armature/Skeleton")
|
||||
bone_name = "Right_Hand"
|
||||
update_mode = 0
|
||||
look_at_axis = 1
|
||||
use_our_rot_x = false
|
||||
use_our_rot_y = false
|
||||
use_our_rot_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" index="1"]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -6.34515, 0, -3.7843 )
|
||||
|
||||
[node name="Right_UpperArm" type="Spatial" parent="Camera/targets/IK_FABRIK_Right_Arm" index="2"]
|
||||
|
||||
transform = Transform( -0.694982, -0.0753926, 0.715064, -7.45058e-09, 0.994488, 0.104854, -0.719028, 0.0728714, -0.691151, -1.53339, 0.300478, -3.63533 )
|
||||
|
||||
[node name="Right_LowerArm" type="Spatial" parent="Camera/targets/IK_FABRIK_Right_Arm" index="3"]
|
||||
|
||||
transform = Transform( -0.792024, 0.0165705, -0.610266, 0, 0.999631, 0.0271429, 0.61049, 0.0214978, -0.791732, -2.89561, 0.100753, -2.31866 )
|
||||
|
||||
[node name="Right_Hand" type="Spatial" parent="Camera/targets/IK_FABRIK_Right_Arm" index="4"]
|
||||
|
||||
transform = Transform( -0.678335, 0.00698586, -0.734719, -1.86265e-09, 0.999955, 0.00950778, 0.734753, 0.00644946, -0.678304, -1.07914, 0.0200729, 0.0379109 )
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="Camera/targets" index="3"]
|
||||
|
||||
layers = 1
|
||||
material_override = null
|
||||
cast_shadow = 1
|
||||
extra_cull_margin = 0.0
|
||||
use_in_baked_light = false
|
||||
lod_min_distance = 0.0
|
||||
lod_min_hysteresis = 0.0
|
||||
lod_max_distance = 0.0
|
||||
lod_max_hysteresis = 0.0
|
||||
mesh = SubResource( 5 )
|
||||
skeleton = NodePath("..")
|
||||
material/0 = SubResource( 6 )
|
||||
_sections_unfolded = [ "material" ]
|
||||
|
||||
[node name="Control" type="Control" parent="." index="5"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
|
||||
[node name="Panel" type="Panel" parent="Control" index="0"]
|
||||
|
||||
modulate = Color( 1, 1, 1, 0.784314 )
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = -2.0
|
||||
margin_top = 530.0
|
||||
margin_right = 1028.0
|
||||
margin_bottom = 600.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
_sections_unfolded = [ "Visibility" ]
|
||||
|
||||
[node name="Label" type="Label" parent="Control/Panel" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 12.0
|
||||
margin_top = 10.0
|
||||
margin_right = 1012.0
|
||||
margin_bottom = 41.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 4
|
||||
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)"
|
||||
align = 1
|
||||
valign = 1
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="Label_extra" type="Label" parent="Control/Panel" index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 12.0
|
||||
margin_top = 80.0
|
||||
margin_right = 1012.0
|
||||
margin_bottom = 128.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 4
|
||||
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
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="Label_left" type="Label" parent="Control/Panel" index="2"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 782.0
|
||||
margin_top = 4.0
|
||||
margin_right = 895.0
|
||||
margin_bottom = 18.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 4
|
||||
text = "Left Hand"
|
||||
align = 1
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="Label_right" type="Label" parent="Control/Panel" index="3"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 136.0
|
||||
margin_top = 5.0
|
||||
margin_right = 249.0
|
||||
margin_bottom = 19.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 4
|
||||
text = "Right Hand"
|
||||
align = 1
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="Button_Next" type="Button" parent="Control" index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 900.0
|
||||
margin_top = 540.0
|
||||
margin_right = 1019.0
|
||||
margin_bottom = 590.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
toggle_mode = false
|
||||
enabled_focus_mode = 2
|
||||
shortcut = null
|
||||
group = null
|
||||
text = "Next scene"
|
||||
flat = false
|
||||
align = 1
|
||||
script = ExtResource( 8 )
|
||||
scene_to_change_to = "res://fps_example.tscn"
|
||||
|
||||
[node name="Button_Previous" type="Button" parent="Control" index="2"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 10.0
|
||||
margin_top = 540.0
|
||||
margin_right = 129.0
|
||||
margin_bottom = 590.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
toggle_mode = false
|
||||
enabled_focus_mode = 2
|
||||
shortcut = null
|
||||
group = null
|
||||
text = "Previous scene"
|
||||
flat = false
|
||||
align = 1
|
||||
script = ExtResource( 8 )
|
||||
scene_to_change_to = "res://look_at_ik.tscn"
|
||||
|
||||
|
||||
[editable path="BattleBot"]
|
||||
1599
3d/ik/fps_example.tscn
Normal file
313
3d/ik/godot_battle_bot.dae
Normal file
1065
3d/ik/godot_battle_bot.dae.import
Normal file
BIN
3d/ik/godot_battle_bot_colors.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
33
3d/ik/godot_battle_bot_colors.png.import
Normal file
@@ -0,0 +1,33 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path.s3tc="res://.import/godot_battle_bot_colors.png-e31963bb1727b598c8ab928a0383fa54.s3tc.stex"
|
||||
path.etc2="res://.import/godot_battle_bot_colors.png-e31963bb1727b598c8ab928a0383fa54.etc2.stex"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_battle_bot_colors.png"
|
||||
source_md5="12a4d2c319a38483b2aa8d504f39b777"
|
||||
|
||||
dest_files=[ "res://.import/godot_battle_bot_colors.png-e31963bb1727b598c8ab928a0383fa54.s3tc.stex", "res://.import/godot_battle_bot_colors.png-e31963bb1727b598c8ab928a0383fa54.etc2.stex" ]
|
||||
dest_md5="8fcf2a1031ed729de0ec7489bbbfff50"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=true
|
||||
flags/filter=true
|
||||
flags/mipmaps=true
|
||||
flags/anisotropic=false
|
||||
flags/srgb=1
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=false
|
||||
svg/scale=1.0
|
||||
BIN
3d/ik/godot_battle_bot_emission.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
33
3d/ik/godot_battle_bot_emission.png.import
Normal file
@@ -0,0 +1,33 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path.s3tc="res://.import/godot_battle_bot_emission.png-c363ccbe8ada8fe822cd5528b54fc924.s3tc.stex"
|
||||
path.etc2="res://.import/godot_battle_bot_emission.png-c363ccbe8ada8fe822cd5528b54fc924.etc2.stex"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_battle_bot_emission.png"
|
||||
source_md5="a9187c4786e7b546dee3dc4fd41f08b2"
|
||||
|
||||
dest_files=[ "res://.import/godot_battle_bot_emission.png-c363ccbe8ada8fe822cd5528b54fc924.s3tc.stex", "res://.import/godot_battle_bot_emission.png-c363ccbe8ada8fe822cd5528b54fc924.etc2.stex" ]
|
||||
dest_md5="34ef476c1425bc7191891768528bbdce"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=true
|
||||
flags/filter=true
|
||||
flags/mipmaps=true
|
||||
flags/anisotropic=false
|
||||
flags/srgb=1
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=false
|
||||
svg/scale=1.0
|
||||
BIN
3d/ik/gun_color.material
Normal file
BIN
3d/ik/gun_emission.material
Normal file
BIN
3d/ik/gun_textures.png
Normal file
|
After Width: | Height: | Size: 760 B |
33
3d/ik/gun_textures.png.import
Normal file
@@ -0,0 +1,33 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path.s3tc="res://.import/gun_textures.png-d86dd13f7bab751a3c0100e83b6188ac.s3tc.stex"
|
||||
path.etc2="res://.import/gun_textures.png-d86dd13f7bab751a3c0100e83b6188ac.etc2.stex"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://gun_textures.png"
|
||||
source_md5="9e2cc48fd22430732940901b58005fef"
|
||||
|
||||
dest_files=[ "res://.import/gun_textures.png-d86dd13f7bab751a3c0100e83b6188ac.s3tc.stex", "res://.import/gun_textures.png-d86dd13f7bab751a3c0100e83b6188ac.etc2.stex" ]
|
||||
dest_md5="7a556ab1eb4119f7a6a81568409d7291"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=true
|
||||
flags/filter=true
|
||||
flags/mipmaps=true
|
||||
flags/anisotropic=false
|
||||
flags/srgb=1
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=false
|
||||
svg/scale=1.0
|
||||
BIN
3d/ik/icon.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
32
3d/ik/icon.png.import
Normal file
@@ -0,0 +1,32 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
source_md5="654257205f0755621b814b013fac6039"
|
||||
|
||||
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
|
||||
dest_md5="09cf0e9e88dbe274951c3d78af897ef4"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
383
3d/ik/look_at_ik.tscn
Normal file
@@ -0,0 +1,383 @@
|
||||
[gd_scene load_steps=11 format=2]
|
||||
|
||||
[ext_resource path="res://addons/sade/editor_gizmo_texture.png" type="Texture" id=1]
|
||||
[ext_resource path="res://godot_battle_bot.dae" type="PackedScene" id=2]
|
||||
[ext_resource path="res://Target_From_MousePos.gd" type="Script" id=3]
|
||||
[ext_resource path="res://addons/sade/ik_look_at.gd" type="Script" id=4]
|
||||
[ext_resource path="res://addons/sade/ik_look_at.png" type="Texture" id=5]
|
||||
[ext_resource path="res://Button_Change_Scene.gd" type="Script" id=6]
|
||||
|
||||
[sub_resource type="PlaneMesh" id=1]
|
||||
|
||||
size = Vector2( 40, 40 )
|
||||
subdivide_width = 0
|
||||
subdivide_depth = 0
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=2]
|
||||
|
||||
render_priority = 0
|
||||
flags_transparent = false
|
||||
flags_unshaded = false
|
||||
flags_vertex_lighting = false
|
||||
flags_no_depth_test = false
|
||||
flags_use_point_size = false
|
||||
flags_world_triplanar = false
|
||||
flags_fixed_size = false
|
||||
flags_albedo_tex_force_srgb = false
|
||||
vertex_color_use_as_albedo = false
|
||||
vertex_color_is_srgb = false
|
||||
params_diffuse_mode = 0
|
||||
params_specular_mode = 0
|
||||
params_blend_mode = 0
|
||||
params_cull_mode = 0
|
||||
params_depth_draw_mode = 0
|
||||
params_line_width = 1.0
|
||||
params_point_size = 1.0
|
||||
params_billboard_mode = 0
|
||||
params_grow = false
|
||||
params_use_alpha_scissor = false
|
||||
albedo_color = Color( 1, 1, 1, 1 )
|
||||
albedo_texture = ExtResource( 1 )
|
||||
metallic = 0.0
|
||||
metallic_specular = 0.5
|
||||
metallic_texture_channel = 0
|
||||
roughness = 0.2
|
||||
roughness_texture_channel = 0
|
||||
emission_enabled = false
|
||||
normal_enabled = false
|
||||
rim_enabled = false
|
||||
clearcoat_enabled = false
|
||||
anisotropy_enabled = false
|
||||
ao_enabled = false
|
||||
depth_enabled = false
|
||||
subsurf_scatter_enabled = false
|
||||
transmission_enabled = false
|
||||
refraction_enabled = false
|
||||
detail_enabled = false
|
||||
uv1_scale = Vector3( 0.25, 0.25, 0.25 )
|
||||
uv1_offset = Vector3( 0, 0, 0 )
|
||||
uv1_triplanar = true
|
||||
uv1_triplanar_sharpness = 1.0
|
||||
uv2_scale = Vector3( 1, 1, 1 )
|
||||
uv2_offset = Vector3( 0, 0, 0 )
|
||||
uv2_triplanar = false
|
||||
uv2_triplanar_sharpness = 1.0
|
||||
proximity_fade_enable = false
|
||||
distance_fade_enable = false
|
||||
_sections_unfolded = [ "UV1" ]
|
||||
|
||||
[sub_resource type="ProceduralSky" id=3]
|
||||
|
||||
radiance_size = 4
|
||||
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
|
||||
sky_energy = 1.0
|
||||
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
|
||||
ground_energy = 1.0
|
||||
sun_color = Color( 1, 1, 1, 1 )
|
||||
sun_latitude = 35.0
|
||||
sun_longitude = 0.0
|
||||
sun_angle_min = 1.0
|
||||
sun_angle_max = 100.0
|
||||
sun_curve = 0.05
|
||||
sun_energy = 16.0
|
||||
texture_size = 2
|
||||
|
||||
[sub_resource type="Environment" id=4]
|
||||
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 3 )
|
||||
background_sky_custom_fov = 0.0
|
||||
background_color = Color( 0, 0, 0, 1 )
|
||||
background_energy = 1.0
|
||||
background_canvas_max_layer = 0
|
||||
ambient_light_color = Color( 0, 0, 0, 1 )
|
||||
ambient_light_energy = 1.0
|
||||
ambient_light_sky_contribution = 1.0
|
||||
fog_enabled = false
|
||||
fog_color = Color( 0.5, 0.6, 0.7, 1 )
|
||||
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
|
||||
fog_sun_amount = 0.0
|
||||
fog_depth_enabled = true
|
||||
fog_depth_begin = 10.0
|
||||
fog_depth_curve = 1.0
|
||||
fog_transmit_enabled = false
|
||||
fog_transmit_curve = 1.0
|
||||
fog_height_enabled = false
|
||||
fog_height_min = 0.0
|
||||
fog_height_max = 100.0
|
||||
fog_height_curve = 1.0
|
||||
tonemap_mode = 3
|
||||
tonemap_exposure = 1.0
|
||||
tonemap_white = 1.0
|
||||
auto_exposure_enabled = false
|
||||
auto_exposure_scale = 0.4
|
||||
auto_exposure_min_luma = 0.05
|
||||
auto_exposure_max_luma = 8.0
|
||||
auto_exposure_speed = 0.5
|
||||
ss_reflections_enabled = false
|
||||
ss_reflections_max_steps = 64
|
||||
ss_reflections_fade_in = 0.15
|
||||
ss_reflections_fade_out = 2.0
|
||||
ss_reflections_depth_tolerance = 0.2
|
||||
ss_reflections_roughness = true
|
||||
ssao_enabled = false
|
||||
ssao_radius = 1.0
|
||||
ssao_intensity = 1.0
|
||||
ssao_radius2 = 0.0
|
||||
ssao_intensity2 = 1.0
|
||||
ssao_bias = 0.01
|
||||
ssao_light_affect = 0.0
|
||||
ssao_color = Color( 0, 0, 0, 1 )
|
||||
ssao_quality = 0
|
||||
ssao_blur = 3
|
||||
ssao_edge_sharpness = 4.0
|
||||
dof_blur_far_enabled = false
|
||||
dof_blur_far_distance = 10.0
|
||||
dof_blur_far_transition = 5.0
|
||||
dof_blur_far_amount = 0.1
|
||||
dof_blur_far_quality = 1
|
||||
dof_blur_near_enabled = false
|
||||
dof_blur_near_distance = 2.0
|
||||
dof_blur_near_transition = 1.0
|
||||
dof_blur_near_amount = 0.1
|
||||
dof_blur_near_quality = 1
|
||||
glow_enabled = true
|
||||
glow_levels/1 = true
|
||||
glow_levels/2 = true
|
||||
glow_levels/3 = true
|
||||
glow_levels/4 = false
|
||||
glow_levels/5 = false
|
||||
glow_levels/6 = false
|
||||
glow_levels/7 = false
|
||||
glow_intensity = 0.2
|
||||
glow_strength = 1.0
|
||||
glow_bloom = 0.03
|
||||
glow_blend_mode = 0
|
||||
glow_hdr_threshold = 1.0
|
||||
glow_hdr_scale = 2.0
|
||||
glow_bicubic_upscale = false
|
||||
adjustment_enabled = false
|
||||
adjustment_brightness = 1.0
|
||||
adjustment_contrast = 1.0
|
||||
adjustment_saturation = 1.0
|
||||
_sections_unfolded = [ "Glow", "Glow/levels" ]
|
||||
|
||||
[node name="LookAt_IK" type="Spatial"]
|
||||
|
||||
[node name="Floor_plane" type="MeshInstance" parent="." index="0"]
|
||||
|
||||
layers = 1
|
||||
material_override = null
|
||||
cast_shadow = 1
|
||||
extra_cull_margin = 0.0
|
||||
use_in_baked_light = false
|
||||
lod_min_distance = 0.0
|
||||
lod_min_hysteresis = 0.0
|
||||
lod_max_distance = 0.0
|
||||
lod_max_hysteresis = 0.0
|
||||
mesh = SubResource( 1 )
|
||||
skeleton = NodePath("..")
|
||||
material/0 = SubResource( 2 )
|
||||
_sections_unfolded = [ "material" ]
|
||||
|
||||
[node name="DirectionalLight" type="DirectionalLight" parent="." index="1"]
|
||||
|
||||
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 )
|
||||
layers = 1
|
||||
light_color = Color( 1, 1, 1, 1 )
|
||||
light_energy = 1.0
|
||||
light_indirect_energy = 1.0
|
||||
light_negative = false
|
||||
light_specular = 0.5
|
||||
light_bake_mode = 1
|
||||
light_cull_mask = -1
|
||||
shadow_enabled = false
|
||||
shadow_color = Color( 0, 0, 0, 1 )
|
||||
shadow_bias = 0.1
|
||||
shadow_contact = 0.0
|
||||
shadow_reverse_cull_face = false
|
||||
editor_only = false
|
||||
directional_shadow_mode = 2
|
||||
directional_shadow_split_1 = 0.1
|
||||
directional_shadow_split_2 = 0.2
|
||||
directional_shadow_split_3 = 0.5
|
||||
directional_shadow_blend_splits = false
|
||||
directional_shadow_normal_bias = 0.8
|
||||
directional_shadow_bias_split_scale = 0.25
|
||||
directional_shadow_depth_range = 0
|
||||
directional_shadow_max_distance = 200.0
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." index="2"]
|
||||
|
||||
environment = SubResource( 4 )
|
||||
|
||||
[node name="BattleBot" parent="." index="3" instance=ExtResource( 2 )]
|
||||
|
||||
editor/display_folded = true
|
||||
|
||||
[node name="Camera" type="Camera" parent="." index="4"]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.5014, 8.81922 )
|
||||
keep_aspect = 1
|
||||
cull_mask = 1048575
|
||||
environment = null
|
||||
h_offset = 0.0
|
||||
v_offset = 0.0
|
||||
doppler_tracking = 0
|
||||
projection = 0
|
||||
current = false
|
||||
fov = 70.0
|
||||
size = 1.0
|
||||
near = 0.05
|
||||
far = 100.0
|
||||
script = ExtResource( 3 )
|
||||
MOVEMENT_SPEED = -2.0
|
||||
flip_axis = true
|
||||
|
||||
[node name="targets" type="Spatial" parent="Camera" index="0"]
|
||||
|
||||
[node name="IK_LookAt_Head" type="Spatial" parent="Camera/targets" index="0"]
|
||||
|
||||
script = ExtResource( 4 )
|
||||
_sections_unfolded = [ "Transform" ]
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 5 )
|
||||
}
|
||||
skeleton_path = NodePath("../../../BattleBot/Armature/Skeleton")
|
||||
bone_name = "Head"
|
||||
update_mode = 0
|
||||
look_at_axis = 1
|
||||
use_our_rot_x = false
|
||||
use_our_rot_y = false
|
||||
use_our_rot_z = false
|
||||
use_negative_our_rot = false
|
||||
additional_rotation = Vector3( 90, 0, 0 )
|
||||
debug_messages = false
|
||||
|
||||
[node name="IK_LookAt_LeftArm" type="Spatial" parent="Camera/targets" index="1"]
|
||||
|
||||
script = ExtResource( 4 )
|
||||
_sections_unfolded = [ "Transform" ]
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 5 )
|
||||
}
|
||||
skeleton_path = NodePath("../../../BattleBot/Armature/Skeleton")
|
||||
bone_name = "Left_UpperArm"
|
||||
update_mode = 0
|
||||
look_at_axis = 1
|
||||
use_our_rot_x = false
|
||||
use_our_rot_y = false
|
||||
use_our_rot_z = false
|
||||
use_negative_our_rot = false
|
||||
additional_rotation = Vector3( 0, 0, 0 )
|
||||
debug_messages = false
|
||||
|
||||
[node name="IK_LookAt_RightArm" type="Spatial" parent="Camera/targets" index="2"]
|
||||
|
||||
script = ExtResource( 4 )
|
||||
_sections_unfolded = [ "Transform" ]
|
||||
__meta__ = {
|
||||
"_editor_icon": ExtResource( 5 )
|
||||
}
|
||||
skeleton_path = NodePath("../../../BattleBot/Armature/Skeleton")
|
||||
bone_name = "Right_UpperArm"
|
||||
update_mode = 0
|
||||
look_at_axis = 1
|
||||
use_our_rot_x = false
|
||||
use_our_rot_y = false
|
||||
use_our_rot_z = false
|
||||
use_negative_our_rot = false
|
||||
additional_rotation = Vector3( 0, 0, 180 )
|
||||
debug_messages = false
|
||||
|
||||
[node name="Control" type="Control" parent="." index="5"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
|
||||
[node name="Panel" type="Panel" parent="Control" index="0"]
|
||||
|
||||
modulate = Color( 1, 1, 1, 0.784314 )
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = -2.0
|
||||
margin_top = 530.0
|
||||
margin_right = 1028.0
|
||||
margin_bottom = 600.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
_sections_unfolded = [ "Visibility" ]
|
||||
|
||||
[node name="Label" type="Label" parent="Control/Panel" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 12.0
|
||||
margin_top = 10.0
|
||||
margin_right = 1012.0
|
||||
margin_bottom = 41.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 4
|
||||
text = "LookAt IK
|
||||
Move mouse to move IK targets"
|
||||
align = 1
|
||||
valign = 1
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="Button_Next" type="Button" parent="Control" index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 900.0
|
||||
margin_top = 540.0
|
||||
margin_right = 1019.0
|
||||
margin_bottom = 590.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
toggle_mode = false
|
||||
enabled_focus_mode = 2
|
||||
shortcut = null
|
||||
group = null
|
||||
text = "Next scene"
|
||||
flat = false
|
||||
align = 1
|
||||
script = ExtResource( 6 )
|
||||
scene_to_change_to = "res://fabrik_ik.tscn"
|
||||
|
||||
|
||||
[editable path="BattleBot"]
|
||||
28
3d/ik/project.godot
Normal file
@@ -0,0 +1,28 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=3
|
||||
|
||||
[application]
|
||||
|
||||
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" )
|
||||
|
||||
[rendering]
|
||||
|
||||
environment/default_environment="res://default_env.tres"
|
||||
13
3d/ik/simple_bullet.gd
Normal file
@@ -0,0 +1,13 @@
|
||||
extends RigidBody
|
||||
|
||||
const KILL_TIME = 5
|
||||
var timer = 0
|
||||
|
||||
func _ready():
|
||||
set_physics_process(true);
|
||||
|
||||
func _physics_process(delta):
|
||||
timer += delta
|
||||
if timer > KILL_TIME:
|
||||
queue_free()
|
||||
timer = 0 # Make sure we are destroyed before we call this again!
|
||||
123
3d/ik/simple_bullet.tscn
Normal file
@@ -0,0 +1,123 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://simple_bullet.gd" type="Script" id=1]
|
||||
|
||||
[sub_resource type="SphereMesh" id=1]
|
||||
|
||||
radius = 1.0
|
||||
height = 2.0
|
||||
radial_segments = 64
|
||||
rings = 32
|
||||
is_hemisphere = false
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=2]
|
||||
|
||||
render_priority = 0
|
||||
flags_transparent = false
|
||||
flags_unshaded = false
|
||||
flags_vertex_lighting = false
|
||||
flags_no_depth_test = false
|
||||
flags_use_point_size = false
|
||||
flags_world_triplanar = false
|
||||
flags_fixed_size = false
|
||||
flags_albedo_tex_force_srgb = false
|
||||
vertex_color_use_as_albedo = false
|
||||
vertex_color_is_srgb = false
|
||||
params_diffuse_mode = 0
|
||||
params_specular_mode = 0
|
||||
params_blend_mode = 0
|
||||
params_cull_mode = 0
|
||||
params_depth_draw_mode = 0
|
||||
params_line_width = 1.0
|
||||
params_point_size = 1.0
|
||||
params_billboard_mode = 0
|
||||
params_grow = false
|
||||
params_use_alpha_scissor = false
|
||||
albedo_color = Color( 0.769531, 0.486969, 0, 1 )
|
||||
metallic = 0.0
|
||||
metallic_specular = 0.5
|
||||
metallic_texture_channel = 0
|
||||
roughness = 1.0
|
||||
roughness_texture_channel = 0
|
||||
emission_enabled = true
|
||||
emission = Color( 1, 0.445313, 0, 1 )
|
||||
emission_energy = 1.8
|
||||
emission_operator = 0
|
||||
emission_on_uv2 = false
|
||||
normal_enabled = false
|
||||
rim_enabled = false
|
||||
clearcoat_enabled = false
|
||||
anisotropy_enabled = false
|
||||
ao_enabled = false
|
||||
depth_enabled = false
|
||||
subsurf_scatter_enabled = false
|
||||
transmission_enabled = false
|
||||
refraction_enabled = false
|
||||
detail_enabled = false
|
||||
uv1_scale = Vector3( 1, 1, 1 )
|
||||
uv1_offset = Vector3( 0, 0, 0 )
|
||||
uv1_triplanar = false
|
||||
uv1_triplanar_sharpness = 1.0
|
||||
uv2_scale = Vector3( 1, 1, 1 )
|
||||
uv2_offset = Vector3( 0, 0, 0 )
|
||||
uv2_triplanar = false
|
||||
uv2_triplanar_sharpness = 1.0
|
||||
proximity_fade_enable = false
|
||||
distance_fade_enable = false
|
||||
|
||||
[sub_resource type="SphereShape" id=3]
|
||||
|
||||
radius = 0.4
|
||||
|
||||
[node name="SimpleBullet" type="RigidBody"]
|
||||
|
||||
input_ray_pickable = true
|
||||
input_capture_on_drag = false
|
||||
collision_layer = 1
|
||||
collision_mask = 1
|
||||
mode = 0
|
||||
mass = 2.0
|
||||
friction = 1.0
|
||||
bounce = 0.5
|
||||
gravity_scale = 3.0
|
||||
custom_integrator = false
|
||||
continuous_cd = true
|
||||
contacts_reported = 0
|
||||
contact_monitor = false
|
||||
sleeping = false
|
||||
can_sleep = false
|
||||
axis_lock_linear_x = false
|
||||
axis_lock_linear_y = false
|
||||
axis_lock_linear_z = false
|
||||
axis_lock_angular_x = false
|
||||
axis_lock_angular_y = false
|
||||
axis_lock_angular_z = false
|
||||
linear_velocity = Vector3( 0, 0, 0 )
|
||||
linear_damp = 0.4
|
||||
angular_velocity = Vector3( 0, 0, 0 )
|
||||
angular_damp = -1.0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="." index="0"]
|
||||
|
||||
transform = Transform( 0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0 )
|
||||
layers = 1
|
||||
material_override = null
|
||||
cast_shadow = 0
|
||||
extra_cull_margin = 0.0
|
||||
use_in_baked_light = false
|
||||
lod_min_distance = 0.0
|
||||
lod_min_hysteresis = 0.0
|
||||
lod_max_distance = 0.0
|
||||
lod_max_hysteresis = 0.0
|
||||
mesh = SubResource( 1 )
|
||||
skeleton = NodePath("..")
|
||||
material/0 = SubResource( 2 )
|
||||
_sections_unfolded = [ "Geometry", "Transform", "material" ]
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="." index="1"]
|
||||
|
||||
shape = SubResource( 3 )
|
||||
disabled = false
|
||||
|
||||
|
||||
20
3d/ik/target_from_mousepos.gd
Normal file
@@ -0,0 +1,20 @@
|
||||
extends Camera
|
||||
|
||||
var targets = null
|
||||
|
||||
export (float) var MOVEMENT_SPEED = 10
|
||||
export (bool) var flip_axis = false
|
||||
|
||||
|
||||
func _ready():
|
||||
targets = get_node("targets")
|
||||
|
||||
func _process(delta):
|
||||
var mouse_to_world = project_local_ray_normal(get_viewport().get_mouse_position()) * MOVEMENT_SPEED
|
||||
|
||||
if flip_axis == false:
|
||||
mouse_to_world.z *= -1
|
||||
else:
|
||||
mouse_to_world = -mouse_to_world
|
||||
|
||||
targets.transform.origin = mouse_to_world
|
||||