Compare commits

...

22 Commits

Author SHA1 Message Date
fa5375534b Work on fixing the ik demo. 2024-09-30 18:35:21 +02:00
f5d91b4e6e Fix ik_look_at.gd. 2024-09-30 18:01:23 +02:00
dfd8abe5fe Small tweaks. 2024-09-26 21:48:14 +02:00
b97ecfb7de Decrease the player's collision capsule's size. 2024-09-26 21:47:07 +02:00
8f3a81c124 the_tower_gles3 pandemonium port pt4. 2024-09-26 21:41:48 +02:00
dbdd19436e the_tower_gles3 pandemonium port pt3. 2024-09-26 21:40:17 +02:00
5ae367996d the_tower_gles3 pandemonium port pt2. 2024-09-26 21:35:54 +02:00
88f3abf978 the_tower_gles3 pandemonium port pt1. 2024-09-26 21:34:26 +02:00
f75b6a4515 Added https://github.com/Relintai/the_tower as an another voxelman demo. 2024-09-26 21:27:15 +02:00
e68f280f54 Added https://github.com/Relintai/the_tower_pandemonium as a new voxelman demo. 2024-09-26 21:25:23 +02:00
eb7fa528dc Updated the wfc demo for pandemonium 4.5. 2024-09-26 21:06:47 +02:00
f92a58b08d Added the demo / test project from https://github.com/Relintai/wfc_module_samples 2024-09-26 21:00:58 +02:00
f2d25ec2ec Small tweak. 2024-09-26 13:17:47 +02:00
21a8a0a702 Rework steering ai's readme. 2024-09-26 13:16:26 +02:00
aeff6f56e4 Opened the steering ai demo in 4.5.0. 2024-09-26 13:09:09 +02:00
2cbc3ea3af Fix variable shadowing a native class. 2024-09-26 13:08:42 +02:00
8295671644 Added the steering ai module's demos from https://github.com/Relintai/godot-steering-ai-framework 2024-09-26 13:04:06 +02:00
13c31ac83f Procedural trees demo. 2024-09-08 17:24:10 +02:00
1cdfe1836e Added 2 new web demos. 2024-05-04 17:34:47 +02:00
5fe963de8f Prepared statements demo. 2024-04-27 21:07:30 +02:00
124ab95723 New simple database demo project. 2024-04-27 20:01:18 +02:00
1d8a77ea51 Added a markdown renderer demo project. 2024-04-26 18:22:04 +02:00
637 changed files with 21378 additions and 46 deletions

View File

@ -1,4 +1,3 @@
tool
extends Spatial
# A FABRIK IK chain with a middle joint helper.
@ -14,9 +13,10 @@ 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: Spatial = null
var target : Spatial = null
var skeleton: Skeleton
var skeleton : Skeleton
var skeleton_up : Vector3
# A dictionary holding all of the bone IDs (from the skeleton) and a dictionary holding
# all of the bone helper nodes
@ -151,7 +151,7 @@ func update_skeleton():
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.UP)
bone_nodes[i].look_at(get_bone_transform(i+1).origin + skeleton.global_transform.origin, skeleton_up)
i += 1
@ -293,7 +293,7 @@ func chain_apply_rotation():
else:
var b_target = target.global_transform
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
bone_trans = bone_trans.looking_at(b_target.origin, Vector3.UP)
bone_trans = bone_trans.looking_at(b_target.origin, skeleton_up)
# A bit of a hack. Because we only have two bones, we have to use the previous
# bone to position the last bone in the chain.
@ -319,7 +319,7 @@ func chain_apply_rotation():
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.UP)
bone_trans = bone_trans.looking_at(b_target.origin + dir, skeleton_up)
# Set the position of the bone to the bone target.
# Prior to Godot 3.2, this was not necessary, but because we can now completely
@ -332,7 +332,7 @@ func chain_apply_rotation():
func get_bone_transform(bone, convert_to_world_space = true):
# Get the global transform of the bone
var ret: Transform = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]])
var ret: Transform = skeleton.get_bone_global_pose_no_override(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).
@ -413,6 +413,7 @@ func _set_skeleton_path(new_value):
# If it has the method "get_bone_global_pose" it is likely a Skeleton
if temp.has_method("get_bone_global_pose"):
skeleton = temp
skeleton_up = skeleton.global_transform.xform_inv(Vector3.UP)
bone_IDs = {}
# (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain

View File

@ -1,4 +1,3 @@
tool
extends Spatial
export(NodePath) var skeleton_path setget _set_skeleton_path
@ -78,23 +77,22 @@ func update_skeleton():
return
# get the bone's global transform pose.
var rest = skeleton_to_use.get_bone_global_pose(bone)
var rest : Transform = skeleton_to_use.get_bone_global_pose_no_override(bone)
# Convert our position relative to the skeleton's transform.
var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin)
var target_pos : Vector3 = 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.RIGHT)
rest = rest.looking_at(target_pos, skeleton_to_use.global_transform.xform_inv(Vector3.RIGHT))
elif look_at_axis == 1:
rest = rest.looking_at(target_pos, Vector3.UP)
rest = rest.looking_at(target_pos, skeleton_to_use.global_transform.xform_inv(Vector3.UP))
elif look_at_axis == 2:
rest = rest.looking_at(target_pos, Vector3.FORWARD)
rest = rest.looking_at(target_pos, skeleton_to_use.global_transform.xform_inv(Vector3.FORWARD))
else:
rest = rest.looking_at(target_pos, Vector3.UP)
rest = rest.looking_at(target_pos, skeleton_to_use.global_transform.xform_inv(Vector3.UP))
if debug_messages:
print(name, " - IK_LookAt: Unknown look_at_axis value!")
# Get the rotation euler of the bone and of this node.
var rest_euler = rest.basis.get_euler()
var self_euler = global_transform.basis.orthonormalized().get_euler()

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=13 format=2]
[gd_scene load_steps=13 format=3]
[ext_resource path="res://addons/sade/editor_gizmo_texture.png" type="Texture" id=1]
[ext_resource path="res://model/godot_battle_bot.gltf" type="PackedScene" id=2]
@ -37,6 +37,109 @@ transform = Transform( 0.56827, 0.673454, -0.472789, 0, 0.574581, 0.818448, 0.82
[node name="GodotBattleBot" parent="." instance=ExtResource( 2 )]
[node name="Skeleton" parent="GodotBattleBot/Z_UP/Armature" index="0"]
bones/0/position = Vector3( 0, 0.273024, 7.74588 )
bones/0/rotation = Quaternion( 0.759715, 7.75166e-08, 9.06254e-08, 0.650256 )
bones/1/position = Vector3( -0.858803, 0.0572646, 0.105923 )
bones/1/rotation = Quaternion( 0.662256, -0.013691, 0.740854, 0.111198 )
bones/1/scale = Vector3( 0.999998, 1, 0.999999 )
bones/2/position = Vector3( -2.98023e-08, 3.3419, -3.20375e-07 )
bones/2/rotation = Quaternion( 0.0400348, -0.0480878, -0.010588, 0.997984 )
bones/2/scale = Vector3( 1, 1, 1 )
bones/3/position = Vector3( -2.80359e-08, 3.53825, 1.61034e-08 )
bones/3/rotation = Quaternion( 0.513193, 0.52962, -0.484649, 0.470374 )
bones/3/scale = Vector3( 1, 1, 1 )
bones/4/position = Vector3( 0.863247, 0.0572646, 0.105923 )
bones/4/rotation = Quaternion( 0.671069, 0.109276, 0.732881, -0.0247196 )
bones/4/scale = Vector3( 0.999997, 1, 0.999998 )
bones/5/position = Vector3( -1.49012e-08, 3.3419, 1.99303e-07 )
bones/5/rotation = Quaternion( -0.0387784, -0.051742, -0.0145302, 0.997802 )
bones/6/position = Vector3( 4.21492e-09, 3.53825, -2.17745e-08 )
bones/6/rotation = Quaternion( 0.484649, 0.470374, -0.513194, 0.529619 )
bones/6/scale = Vector3( 1, 1, 1 )
bones/7/position = Vector3( -9.64506e-15, 1.7917, 5.65778e-08 )
bones/7/rotation = Quaternion( -0.15185, -3.93786e-11, -3.62496e-08, 0.988404 )
bones/7/scale = Vector3( 1, 1, 1 )
bones/8/position = Vector3( -1.5334, 2.29565, 0.106341 )
bones/8/rotation = Quaternion( 0.694368, -0.212646, 0.677236, 0.118263 )
bones/8/scale = Vector3( 0.999999, 1, 1 )
bones/9/position = Vector3( 9.31323e-09, 1.90503, 1.91387e-07 )
bones/9/rotation = Quaternion( 0.0430889, -0.00651108, 0.00492581, 0.999038 )
bones/9/scale = Vector3( 1, 1, 1 )
bones/10/position = Vector3( -1.54338e-08, 2.97659, 1.80687e-07 )
bones/10/rotation = Quaternion( 0.0254076, 0.0314977, -0.0425505, 0.998274 )
bones/10/scale = Vector3( 1, 1, 1 )
bones/11/position = Vector3( -0.251191, 0.961984, 0.0683811 )
bones/11/rotation = Quaternion( 0.0734265, -0.0198738, 0.116597, 0.990262 )
bones/11/scale = Vector3( 1, 1, 1 )
bones/12/position = Vector3( -4.47035e-08, 0.221738, 1.02445e-08 )
bones/12/rotation = Quaternion( 0.161002, 0.714417, 0.150246, 0.664163 )
bones/12/scale = Vector3( 1, 1, 1 )
bones/13/position = Vector3( -0.0779908, 1.04339, 0.000736893 )
bones/13/rotation = Quaternion( 0.122292, 0.00257627, 0.104377, 0.986987 )
bones/13/scale = Vector3( 1, 1, 1 )
bones/14/position = Vector3( -2.98023e-08, 0.267715, -8.27014e-07 )
bones/14/rotation = Quaternion( 0.147368, 0.694839, 0.0466993, 0.702353 )
bones/14/scale = Vector3( 1, 1, 1 )
bones/15/position = Vector3( 0.0960594, 1.04882, 0.0192584 )
bones/15/rotation = Quaternion( 0.0901164, 0.0392194, 0.00840297, 0.995123 )
bones/16/position = Vector3( 1.86265e-08, 0.277596, -4.6991e-07 )
bones/16/rotation = Quaternion( 0.115872, 0.681565, 0.114615, 0.713377 )
bones/16/scale = Vector3( 1, 1, 1 )
bones/17/position = Vector3( 0.26401, 0.982311, 0.0351903 )
bones/17/rotation = Quaternion( 0.0915952, 0.0987206, -0.130385, 0.982275 )
bones/17/scale = Vector3( 1, 1, 1 )
bones/18/position = Vector3( -2.23517e-07, 0.27682, 1.3411e-07 )
bones/18/rotation = Quaternion( 0.111001, 0.648784, 0.123964, 0.742557 )
bones/18/scale = Vector3( 1, 1, 1 )
bones/19/position = Vector3( 0.408326, 0.607306, 0.0419031 )
bones/19/rotation = Quaternion( 0.104368, 0.154824, -0.245653, 0.951205 )
bones/19/scale = Vector3( 1, 1, 1 )
bones/20/position = Vector3( -2.98023e-08, 0.301735, 4.47035e-08 )
bones/20/rotation = Quaternion( -0.0481356, 0.617453, 0.0348587, 0.784359 )
bones/20/scale = Vector3( 1, 1, 1 )
bones/21/position = Vector3( 1.53444, 2.29565, 0.106341 )
bones/21/rotation = Quaternion( 0.625464, 0.10264, 0.741343, -0.220612 )
bones/21/scale = Vector3( 1, 1, 1 )
bones/22/position = Vector3( 2.98023e-08, 1.90503, 1.08033e-07 )
bones/22/rotation = Quaternion( -0.0433319, -0.0654617, 0.00180953, 0.996912 )
bones/22/scale = Vector3( 1, 1, 1 )
bones/23/position = Vector3( 1.22048e-08, 2.97659, -6.07568e-07 )
bones/23/rotation = Quaternion( -0.0240965, -0.00100487, -0.0433063, 0.998771 )
bones/24/position = Vector3( -0.246549, 0.961984, -0.083585 )
bones/24/rotation = Quaternion( -0.0826772, 0.0401178, 0.11023, 0.989649 )
bones/24/scale = Vector3( 1, 1, 1 )
bones/25/position = Vector3( -1.49012e-07, 0.221738, -1.13621e-07 )
bones/25/rotation = Quaternion( -0.119531, 0.715918, -0.184954, 0.662544 )
bones/25/scale = Vector3( 1, 1, 1 )
bones/26/position = Vector3( -0.0778003, 1.04339, -0.00549548 )
bones/26/rotation = Quaternion( -0.132841, 0.0438432, 0.0905715, 0.986016 )
bones/26/scale = Vector3( 1, 1, 1 )
bones/27/position = Vector3( 1.04308e-07, 0.267716, -1.37836e-07 )
bones/27/rotation = Quaternion( -0.0236808, 0.700911, -0.152766, 0.696294 )
bones/27/scale = Vector3( 1, 1, 1 )
bones/28/position = Vector3( 0.0970556, 1.04882, -0.01336 )
bones/28/rotation = Quaternion( -0.0904035, 0.0402447, -0.00433424, 0.995082 )
bones/28/scale = Vector3( 1, 1, 1 )
bones/29/position = Vector3( 7.68341e-09, 0.277596, -5.1083e-07 )
bones/29/rotation = Quaternion( -0.0926483, 0.681722, -0.134087, 0.713227 )
bones/29/scale = Vector3( 1, 1, 1 )
bones/30/position = Vector3( 0.265665, 0.982311, -0.019011 )
bones/30/rotation = Quaternion( -0.0656662, 0.0260568, -0.145182, 0.98688 )
bones/30/scale = Vector3( 1, 1, 1 )
bones/31/position = Vector3( 3.12924e-07, 0.276819, -7.82311e-08 )
bones/31/rotation = Quaternion( -0.102156, 0.648696, -0.131348, 0.742634 )
bones/31/scale = Vector3( 1, 1, 1 )
bones/32/position = Vector3( 0.410121, 0.607306, -0.0169033 )
bones/32/rotation = Quaternion( -0.0424852, 0.0187641, -0.263502, 0.96354 )
bones/32/scale = Vector3( 1, 1, 1 )
bones/33/position = Vector3( 1.19209e-07, 0.301735, 1.56462e-07 )
bones/33/rotation = Quaternion( -0.0440545, 0.63492, 0.039892, 0.770289 )
bones/33/scale = Vector3( 1, 1, 1 )
bones/34/position = Vector3( 1.17961e-15, 2.97461, 2.98023e-08 )
bones/34/rotation = Quaternion( -1.13845e-08, 0.997388, 0.0722371, 7.53007e-08 )
bones/34/scale = Vector3( 1, 1, 1 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.5, 11 )
fov = 74.0
@ -54,7 +157,6 @@ __meta__ = {
}
skeleton_path = NodePath("../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bone_name = "Head"
additional_rotation = Vector3( 90, 0, 0 )
additional_bone_length = 1
[node name="IK_FABRIK_Left_Arm" type="Spatial" parent="Camera/Targets"]
@ -65,7 +167,6 @@ __meta__ = {
skeleton_path = NodePath("../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bones_in_chain = PoolStringArray( "Left_UpperArm", "Left_LowerArm" )
bones_in_chain_lengths = PoolRealArray( 1.97, 3 )
chain_iterations = 10
limit_chain_iterations = false
use_middle_joint_target = true
@ -80,8 +181,6 @@ __meta__ = {
}
skeleton_path = NodePath("../../../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bone_name = "Left_Hand"
additional_rotation = Vector3( 0, 0, 90 )
position_using_additional_bone = true
additional_bone_name = "Left_LowerArm"
additional_bone_length = 3.0
@ -89,10 +188,10 @@ additional_bone_length = 3.0
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"]
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 )
transform = Transform( 0.138269, 0.566654, -0.812271, 0, 0.820149, 0.57215, 0.990395, -0.0791108, 0.113401, 1.53444, 0.30189, -3.23425 )
[node name="Left_LowerArm" type="Spatial" parent="Camera/Targets/IK_FABRIK_Left_Arm"]
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 )
transform = Transform( -0.986259, -0.122992, 0.110302, 3.72529e-09, 0.667656, 0.74447, -0.165208, 0.73424, -0.658481, 3.13461, -11.9576, -13.6748 )
[node name="IK_FABRIK_Right_Arm" type="Spatial" parent="Camera/Targets"]
script = ExtResource( 8 )
@ -102,35 +201,34 @@ __meta__ = {
skeleton_path = NodePath("../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bones_in_chain = PoolStringArray( "Right_UpperArm", "Right_LowerArm", "Right_Hand" )
bones_in_chain_lengths = PoolRealArray( 1.97, 3, 1.2 )
chain_iterations = 10
limit_chain_iterations = false
use_middle_joint_target = true
[node name="Target" type="Spatial" parent="Camera/Targets/IK_FABRIK_Right_Arm"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.229958, 0, 0.929313 )
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.902034, 0, -0.046618 )
[node name="IK_LookAt_RH" type="Spatial" parent="Camera/Targets/IK_FABRIK_Right_Arm/Target"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0544824, -0.133381, 0.332403 )
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.251035, -0.133381, 0.332403 )
script = ExtResource( 6 )
__meta__ = {
"_editor_icon": ExtResource( 7 )
}
skeleton_path = NodePath("../../../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bone_name = "Right_Hand"
additional_rotation = Vector3( 0, 0, 90 )
additional_rotation = Vector3( 0, 180, 0 )
additional_bone_length = 1
[node name="MiddleJoint" type="Spatial" parent="Camera/Targets/IK_FABRIK_Right_Arm"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -6.34515, 0, -3.7843 )
[node name="Right_UpperArm" type="Spatial" parent="Camera/Targets/IK_FABRIK_Right_Arm"]
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 )
transform = Transform( -0.13677, -0.793967, 0.592377, 2.98023e-08, 0.597996, 0.801499, -0.990603, 0.109621, -0.0817881, -1.5334, 0.30189, -3.23425 )
[node name="Right_LowerArm" type="Spatial" parent="Camera/Targets/IK_FABRIK_Right_Arm"]
transform = Transform( -0.792023, 0.0165711, -0.610266, -1.49012e-08, 0.999631, 0.0271438, 0.610491, 0.0214986, -0.791732, -2.89561, 0.100755, -2.31866 )
transform = Transform( -0.258068, 0.758367, -0.598565, 2.98023e-08, 0.619551, 0.784956, 0.966127, 0.202572, -0.159886, -2.70038, 0.463014, -1.6553 )
[node name="Right_Hand" type="Spatial" parent="Camera/Targets/IK_FABRIK_Right_Arm"]
transform = Transform( -0.678336, 0.00698721, -0.734719, -2.32831e-09, 0.999955, 0.00950961, 0.734752, 0.00645071, -0.678305, -1.07914, 0.020072, 0.03791 )
transform = Transform( 0.933847, -0.293386, -0.204584, 0, 0.571985, -0.820264, 0.357673, 0.766001, 0.534147, -0.946222, 0.944532, 0.730302 )
[node name="1MeterCube" type="MeshInstance" parent="Camera/Targets"]
mesh = SubResource( 3 )

View File

@ -20,10 +20,13 @@ nodes/use_legacy_names=false
materials/location=0
materials/storage=0
materials/keep_on_reimport=true
meshes/octahedral_compression=true
meshes/compress=true
meshes/ensure_tangents=true
meshes/octahedral_compression=true
meshes/vertex_cache_optimization=true
meshes/storage=0
meshes/light_baking=0
meshes/lightmap_texel_size=0.1
skins/use_named_skins=true
external_files/store_in_subdir=false
animation/import=false

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=9 format=2]
[gd_scene load_steps=9 format=3]
[ext_resource path="res://addons/sade/editor_gizmo_texture.png" type="Texture" id=1]
[ext_resource path="res://model/godot_battle_bot.gltf" type="PackedScene" id=2]
@ -28,6 +28,109 @@ transform = Transform( 0.56827, 0.673454, -0.472789, 0, 0.574581, 0.818448, 0.82
[node name="GodotBattleBot" parent="." instance=ExtResource( 2 )]
[node name="Skeleton" parent="GodotBattleBot/Z_UP/Armature" index="0"]
bones/0/position = Vector3( 0, 0.273024, 7.74588 )
bones/0/rotation = Quaternion( 0.759715, 7.75166e-08, 9.06254e-08, 0.650256 )
bones/1/position = Vector3( -0.858803, 0.0572646, 0.105923 )
bones/1/rotation = Quaternion( 0.662256, -0.013691, 0.740854, 0.111198 )
bones/1/scale = Vector3( 0.999998, 1, 0.999999 )
bones/2/position = Vector3( -2.98023e-08, 3.3419, -3.20375e-07 )
bones/2/rotation = Quaternion( 0.0400348, -0.0480878, -0.010588, 0.997984 )
bones/2/scale = Vector3( 1, 1, 1 )
bones/3/position = Vector3( -2.80359e-08, 3.53825, 1.61034e-08 )
bones/3/rotation = Quaternion( 0.513193, 0.52962, -0.484649, 0.470374 )
bones/3/scale = Vector3( 1, 1, 1 )
bones/4/position = Vector3( 0.863247, 0.0572646, 0.105923 )
bones/4/rotation = Quaternion( 0.671069, 0.109276, 0.732881, -0.0247196 )
bones/4/scale = Vector3( 0.999997, 1, 0.999998 )
bones/5/position = Vector3( -1.49012e-08, 3.3419, 1.99303e-07 )
bones/5/rotation = Quaternion( -0.0387784, -0.051742, -0.0145302, 0.997802 )
bones/6/position = Vector3( 4.21492e-09, 3.53825, -2.17745e-08 )
bones/6/rotation = Quaternion( 0.484649, 0.470374, -0.513194, 0.529619 )
bones/6/scale = Vector3( 1, 1, 1 )
bones/7/position = Vector3( -9.64506e-15, 1.7917, 5.65778e-08 )
bones/7/rotation = Quaternion( -0.15185, -3.93786e-11, -3.62496e-08, 0.988404 )
bones/7/scale = Vector3( 1, 1, 1 )
bones/8/position = Vector3( -1.5334, 2.29565, 0.106341 )
bones/8/rotation = Quaternion( 0.694368, -0.212646, 0.677236, 0.118263 )
bones/8/scale = Vector3( 0.999999, 1, 1 )
bones/9/position = Vector3( 9.31323e-09, 1.90503, 1.91387e-07 )
bones/9/rotation = Quaternion( 0.0430889, -0.00651108, 0.00492581, 0.999038 )
bones/9/scale = Vector3( 1, 1, 1 )
bones/10/position = Vector3( -1.54338e-08, 2.97659, 1.80687e-07 )
bones/10/rotation = Quaternion( 0.0254076, 0.0314977, -0.0425505, 0.998274 )
bones/10/scale = Vector3( 1, 1, 1 )
bones/11/position = Vector3( -0.251191, 0.961984, 0.0683811 )
bones/11/rotation = Quaternion( 0.0734265, -0.0198738, 0.116597, 0.990262 )
bones/11/scale = Vector3( 1, 1, 1 )
bones/12/position = Vector3( -4.47035e-08, 0.221738, 1.02445e-08 )
bones/12/rotation = Quaternion( 0.161002, 0.714417, 0.150246, 0.664163 )
bones/12/scale = Vector3( 1, 1, 1 )
bones/13/position = Vector3( -0.0779908, 1.04339, 0.000736893 )
bones/13/rotation = Quaternion( 0.122292, 0.00257627, 0.104377, 0.986987 )
bones/13/scale = Vector3( 1, 1, 1 )
bones/14/position = Vector3( -2.98023e-08, 0.267715, -8.27014e-07 )
bones/14/rotation = Quaternion( 0.147368, 0.694839, 0.0466993, 0.702353 )
bones/14/scale = Vector3( 1, 1, 1 )
bones/15/position = Vector3( 0.0960594, 1.04882, 0.0192584 )
bones/15/rotation = Quaternion( 0.0901164, 0.0392194, 0.00840297, 0.995123 )
bones/16/position = Vector3( 1.86265e-08, 0.277596, -4.6991e-07 )
bones/16/rotation = Quaternion( 0.115872, 0.681565, 0.114615, 0.713377 )
bones/16/scale = Vector3( 1, 1, 1 )
bones/17/position = Vector3( 0.26401, 0.982311, 0.0351903 )
bones/17/rotation = Quaternion( 0.0915952, 0.0987206, -0.130385, 0.982275 )
bones/17/scale = Vector3( 1, 1, 1 )
bones/18/position = Vector3( -2.23517e-07, 0.27682, 1.3411e-07 )
bones/18/rotation = Quaternion( 0.111001, 0.648784, 0.123964, 0.742557 )
bones/18/scale = Vector3( 1, 1, 1 )
bones/19/position = Vector3( 0.408326, 0.607306, 0.0419031 )
bones/19/rotation = Quaternion( 0.104368, 0.154824, -0.245653, 0.951205 )
bones/19/scale = Vector3( 1, 1, 1 )
bones/20/position = Vector3( -2.98023e-08, 0.301735, 4.47035e-08 )
bones/20/rotation = Quaternion( -0.0481356, 0.617453, 0.0348587, 0.784359 )
bones/20/scale = Vector3( 1, 1, 1 )
bones/21/position = Vector3( 1.53444, 2.29565, 0.106341 )
bones/21/rotation = Quaternion( 0.625464, 0.10264, 0.741343, -0.220612 )
bones/21/scale = Vector3( 1, 1, 1 )
bones/22/position = Vector3( 2.98023e-08, 1.90503, 1.08033e-07 )
bones/22/rotation = Quaternion( -0.0433319, -0.0654617, 0.00180953, 0.996912 )
bones/22/scale = Vector3( 1, 1, 1 )
bones/23/position = Vector3( 1.22048e-08, 2.97659, -6.07568e-07 )
bones/23/rotation = Quaternion( -0.0240965, -0.00100487, -0.0433063, 0.998771 )
bones/24/position = Vector3( -0.246549, 0.961984, -0.083585 )
bones/24/rotation = Quaternion( -0.0826772, 0.0401178, 0.11023, 0.989649 )
bones/24/scale = Vector3( 1, 1, 1 )
bones/25/position = Vector3( -1.49012e-07, 0.221738, -1.13621e-07 )
bones/25/rotation = Quaternion( -0.119531, 0.715918, -0.184954, 0.662544 )
bones/25/scale = Vector3( 1, 1, 1 )
bones/26/position = Vector3( -0.0778003, 1.04339, -0.00549548 )
bones/26/rotation = Quaternion( -0.132841, 0.0438432, 0.0905715, 0.986016 )
bones/26/scale = Vector3( 1, 1, 1 )
bones/27/position = Vector3( 1.04308e-07, 0.267716, -1.37836e-07 )
bones/27/rotation = Quaternion( -0.0236808, 0.700911, -0.152766, 0.696294 )
bones/27/scale = Vector3( 1, 1, 1 )
bones/28/position = Vector3( 0.0970556, 1.04882, -0.01336 )
bones/28/rotation = Quaternion( -0.0904035, 0.0402447, -0.00433424, 0.995082 )
bones/28/scale = Vector3( 1, 1, 1 )
bones/29/position = Vector3( 7.68341e-09, 0.277596, -5.1083e-07 )
bones/29/rotation = Quaternion( -0.0926483, 0.681722, -0.134087, 0.713227 )
bones/29/scale = Vector3( 1, 1, 1 )
bones/30/position = Vector3( 0.265665, 0.982311, -0.019011 )
bones/30/rotation = Quaternion( -0.0656662, 0.0260568, -0.145182, 0.98688 )
bones/30/scale = Vector3( 1, 1, 1 )
bones/31/position = Vector3( 3.12924e-07, 0.276819, -7.82311e-08 )
bones/31/rotation = Quaternion( -0.102156, 0.648696, -0.131348, 0.742634 )
bones/31/scale = Vector3( 1, 1, 1 )
bones/32/position = Vector3( 0.410121, 0.607306, -0.0169033 )
bones/32/rotation = Quaternion( -0.0424852, 0.0187641, -0.263502, 0.96354 )
bones/32/scale = Vector3( 1, 1, 1 )
bones/33/position = Vector3( 1.19209e-07, 0.301735, 1.56462e-07 )
bones/33/rotation = Quaternion( -0.0440545, 0.63492, 0.039892, 0.770289 )
bones/33/scale = Vector3( 1, 1, 1 )
bones/34/position = Vector3( 1.17961e-15, 2.97461, 2.98023e-08 )
bones/34/rotation = Quaternion( -1.13845e-08, 0.997388, 0.0722371, 7.53007e-08 )
bones/34/scale = Vector3( 1, 1, 1 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 11.501, 11 )
fov = 74.0
@ -44,7 +147,6 @@ __meta__ = {
}
skeleton_path = NodePath("../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bone_name = "Head"
additional_rotation = Vector3( 90, 0, 0 )
additional_bone_length = 1
[node name="IK_LookAt_LeftArm" type="Spatial" parent="Camera/Targets"]
@ -54,6 +156,8 @@ __meta__ = {
}
skeleton_path = NodePath("../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bone_name = "Left_UpperArm"
look_at_axis = 0
additional_rotation = Vector3( -90, 0, 0 )
additional_bone_length = 1
[node name="IK_LookAt_RightArm" type="Spatial" parent="Camera/Targets"]
@ -63,7 +167,8 @@ __meta__ = {
}
skeleton_path = NodePath("../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bone_name = "Right_UpperArm"
additional_rotation = Vector3( 0, 0, 180 )
look_at_axis = 0
additional_rotation = Vector3( -90, 0, 0 )
additional_bone_length = 1
[node name="Control" type="Control" parent="."]

View File

@ -18,12 +18,15 @@ nodes/custom_script=""
nodes/storage=0
nodes/use_legacy_names=false
materials/location=0
materials/storage=0
materials/storage=1
materials/keep_on_reimport=true
meshes/octahedral_compression=true
meshes/compress=true
meshes/ensure_tangents=true
meshes/storage=0
meshes/octahedral_compression=true
meshes/vertex_cache_optimization=true
meshes/storage=1
meshes/light_baking=0
meshes/lightmap_texel_size=0.1
skins/use_named_skins=true
external_files/store_in_subdir=false
animation/import=true

Binary file not shown.

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=12 format=2]
[gd_scene load_steps=12 format=3]
[ext_resource path="res://skeleton_ik_runner.gd" type="Script" id=1]
[ext_resource path="res://addons/sade/ik_look_at.png" type="Texture" id=2]
@ -69,7 +69,6 @@ __meta__ = {
}
skeleton_path = NodePath("../../../GodotBattleBot/Z_UP/Armature/Skeleton")
bone_name = "Head"
additional_rotation = Vector3( 90, 0, 0 )
additional_bone_length = 1
[node name="1MeterCube" type="MeshInstance" parent="Camera/Targets"]
@ -84,6 +83,109 @@ transform = Transform( -0.0217688, 0.998559, -0.0490576, 0.992503, 0.0274873, 0.
[node name="GodotBattleBot" parent="." instance=ExtResource( 4 )]
[node name="Skeleton" parent="GodotBattleBot/Z_UP/Armature" index="0"]
bones/0/position = Vector3( 0, 0.273024, 7.74588 )
bones/0/rotation = Quaternion( 0.759715, 7.75166e-08, 9.06254e-08, 0.650256 )
bones/1/position = Vector3( -0.858803, 0.0572646, 0.105923 )
bones/1/rotation = Quaternion( 0.662256, -0.013691, 0.740854, 0.111198 )
bones/1/scale = Vector3( 0.999998, 1, 0.999999 )
bones/2/position = Vector3( -2.98023e-08, 3.3419, -3.20375e-07 )
bones/2/rotation = Quaternion( 0.0400348, -0.0480878, -0.010588, 0.997984 )
bones/2/scale = Vector3( 1, 1, 1 )
bones/3/position = Vector3( -2.80359e-08, 3.53825, 1.61034e-08 )
bones/3/rotation = Quaternion( 0.513193, 0.52962, -0.484649, 0.470374 )
bones/3/scale = Vector3( 1, 1, 1 )
bones/4/position = Vector3( 0.863247, 0.0572646, 0.105923 )
bones/4/rotation = Quaternion( 0.671069, 0.109276, 0.732881, -0.0247196 )
bones/4/scale = Vector3( 0.999997, 1, 0.999998 )
bones/5/position = Vector3( -1.49012e-08, 3.3419, 1.99303e-07 )
bones/5/rotation = Quaternion( -0.0387784, -0.051742, -0.0145302, 0.997802 )
bones/6/position = Vector3( 4.21492e-09, 3.53825, -2.17745e-08 )
bones/6/rotation = Quaternion( 0.484649, 0.470374, -0.513194, 0.529619 )
bones/6/scale = Vector3( 1, 1, 1 )
bones/7/position = Vector3( -9.64506e-15, 1.7917, 5.65778e-08 )
bones/7/rotation = Quaternion( -0.15185, -3.93786e-11, -3.62496e-08, 0.988404 )
bones/7/scale = Vector3( 1, 1, 1 )
bones/8/position = Vector3( -1.5334, 2.29565, 0.106341 )
bones/8/rotation = Quaternion( 0.694368, -0.212646, 0.677236, 0.118263 )
bones/8/scale = Vector3( 0.999999, 1, 1 )
bones/9/position = Vector3( 9.31323e-09, 1.90503, 1.91387e-07 )
bones/9/rotation = Quaternion( 0.0430889, -0.00651108, 0.00492581, 0.999038 )
bones/9/scale = Vector3( 1, 1, 1 )
bones/10/position = Vector3( -1.54338e-08, 2.97659, 1.80687e-07 )
bones/10/rotation = Quaternion( 0.0254076, 0.0314977, -0.0425505, 0.998274 )
bones/10/scale = Vector3( 1, 1, 1 )
bones/11/position = Vector3( -0.251191, 0.961984, 0.0683811 )
bones/11/rotation = Quaternion( 0.0734265, -0.0198738, 0.116597, 0.990262 )
bones/11/scale = Vector3( 1, 1, 1 )
bones/12/position = Vector3( -4.47035e-08, 0.221738, 1.02445e-08 )
bones/12/rotation = Quaternion( 0.161002, 0.714417, 0.150246, 0.664163 )
bones/12/scale = Vector3( 1, 1, 1 )
bones/13/position = Vector3( -0.0779908, 1.04339, 0.000736893 )
bones/13/rotation = Quaternion( 0.122292, 0.00257627, 0.104377, 0.986987 )
bones/13/scale = Vector3( 1, 1, 1 )
bones/14/position = Vector3( -2.98023e-08, 0.267715, -8.27014e-07 )
bones/14/rotation = Quaternion( 0.147368, 0.694839, 0.0466993, 0.702353 )
bones/14/scale = Vector3( 1, 1, 1 )
bones/15/position = Vector3( 0.0960594, 1.04882, 0.0192584 )
bones/15/rotation = Quaternion( 0.0901164, 0.0392194, 0.00840297, 0.995123 )
bones/16/position = Vector3( 1.86265e-08, 0.277596, -4.6991e-07 )
bones/16/rotation = Quaternion( 0.115872, 0.681565, 0.114615, 0.713377 )
bones/16/scale = Vector3( 1, 1, 1 )
bones/17/position = Vector3( 0.26401, 0.982311, 0.0351903 )
bones/17/rotation = Quaternion( 0.0915952, 0.0987206, -0.130385, 0.982275 )
bones/17/scale = Vector3( 1, 1, 1 )
bones/18/position = Vector3( -2.23517e-07, 0.27682, 1.3411e-07 )
bones/18/rotation = Quaternion( 0.111001, 0.648784, 0.123964, 0.742557 )
bones/18/scale = Vector3( 1, 1, 1 )
bones/19/position = Vector3( 0.408326, 0.607306, 0.0419031 )
bones/19/rotation = Quaternion( 0.104368, 0.154824, -0.245653, 0.951205 )
bones/19/scale = Vector3( 1, 1, 1 )
bones/20/position = Vector3( -2.98023e-08, 0.301735, 4.47035e-08 )
bones/20/rotation = Quaternion( -0.0481356, 0.617453, 0.0348587, 0.784359 )
bones/20/scale = Vector3( 1, 1, 1 )
bones/21/position = Vector3( 1.53444, 2.29565, 0.106341 )
bones/21/rotation = Quaternion( 0.625464, 0.10264, 0.741343, -0.220612 )
bones/21/scale = Vector3( 1, 1, 1 )
bones/22/position = Vector3( 2.98023e-08, 1.90503, 1.08033e-07 )
bones/22/rotation = Quaternion( -0.0433319, -0.0654617, 0.00180953, 0.996912 )
bones/22/scale = Vector3( 1, 1, 1 )
bones/23/position = Vector3( 1.22048e-08, 2.97659, -6.07568e-07 )
bones/23/rotation = Quaternion( -0.0240965, -0.00100487, -0.0433063, 0.998771 )
bones/24/position = Vector3( -0.246549, 0.961984, -0.083585 )
bones/24/rotation = Quaternion( -0.0826772, 0.0401178, 0.11023, 0.989649 )
bones/24/scale = Vector3( 1, 1, 1 )
bones/25/position = Vector3( -1.49012e-07, 0.221738, -1.13621e-07 )
bones/25/rotation = Quaternion( -0.119531, 0.715918, -0.184954, 0.662544 )
bones/25/scale = Vector3( 1, 1, 1 )
bones/26/position = Vector3( -0.0778003, 1.04339, -0.00549548 )
bones/26/rotation = Quaternion( -0.132841, 0.0438432, 0.0905715, 0.986016 )
bones/26/scale = Vector3( 1, 1, 1 )
bones/27/position = Vector3( 1.04308e-07, 0.267716, -1.37836e-07 )
bones/27/rotation = Quaternion( -0.0236808, 0.700911, -0.152766, 0.696294 )
bones/27/scale = Vector3( 1, 1, 1 )
bones/28/position = Vector3( 0.0970556, 1.04882, -0.01336 )
bones/28/rotation = Quaternion( -0.0904035, 0.0402447, -0.00433424, 0.995082 )
bones/28/scale = Vector3( 1, 1, 1 )
bones/29/position = Vector3( 7.68341e-09, 0.277596, -5.1083e-07 )
bones/29/rotation = Quaternion( -0.0926483, 0.681722, -0.134087, 0.713227 )
bones/29/scale = Vector3( 1, 1, 1 )
bones/30/position = Vector3( 0.265665, 0.982311, -0.019011 )
bones/30/rotation = Quaternion( -0.0656662, 0.0260568, -0.145182, 0.98688 )
bones/30/scale = Vector3( 1, 1, 1 )
bones/31/position = Vector3( 3.12924e-07, 0.276819, -7.82311e-08 )
bones/31/rotation = Quaternion( -0.102156, 0.648696, -0.131348, 0.742634 )
bones/31/scale = Vector3( 1, 1, 1 )
bones/32/position = Vector3( 0.410121, 0.607306, -0.0169033 )
bones/32/rotation = Quaternion( -0.0424852, 0.0187641, -0.263502, 0.96354 )
bones/32/scale = Vector3( 1, 1, 1 )
bones/33/position = Vector3( 1.19209e-07, 0.301735, 1.56462e-07 )
bones/33/rotation = Quaternion( -0.0440545, 0.63492, 0.039892, 0.770289 )
bones/33/scale = Vector3( 1, 1, 1 )
bones/34/position = Vector3( 1.17961e-15, 2.97461, 2.98023e-08 )
bones/34/rotation = Quaternion( -1.13845e-08, 0.997388, 0.0722371, 7.53007e-08 )
bones/34/scale = Vector3( 1, 1, 1 )
[node name="Control" type="Control" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0

View File

@ -0,0 +1,39 @@
[gd_scene load_steps=9 format=3]
[ext_resource path="res://floor.png" type="Texture" id=1]
[ext_resource path="res://twig.png" type="Texture" id=2]
[ext_resource path="res://bark.jpg" type="Texture" id=3]
[sub_resource type="PlaneMesh" id=1]
size = Vector2( 100, 100 )
[sub_resource type="SpatialMaterial" id=2]
albedo_texture = ExtResource( 1 )
uv1_scale = Vector3( 5, 5, 5 )
[sub_resource type="SpatialMaterial" id=5]
albedo_texture = ExtResource( 3 )
[sub_resource type="SpatialMaterial" id=4]
flags_transparent = true
albedo_texture = ExtResource( 2 )
[sub_resource type="ProceduralTreeMesh" id=3]
twig_material = SubResource( 4 )
trunk_material = SubResource( 5 )
[node name="Main" type="Spatial"]
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 0.995856, 0.0909454, 0, -0.0909454, 0.995856, 0, 3.24964, 6.08982 )
[node name="Floor" type="MeshInstance" parent="."]
mesh = SubResource( 1 )
material/0 = SubResource( 2 )
[node name="Tree" type="MeshInstance" parent="."]
mesh = SubResource( 3 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 0.999979, -0.00633815, 0.00104455, 0.0021793, 0.487706, 0.873005, -0.00604267, -0.872985, 0.487709, 0, 12.7518, 7.74885 )
light_energy = 0.413

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/bark.jpg-db1925684069186df966c2d6a5bd27d7.s3tc.stex"
path.etc="res://.import/bark.jpg-db1925684069186df966c2d6a5bd27d7.etc.stex"
metadata={
"imported_formats": [ "s3tc", "etc" ],
"vram_texture": true
}
[deps]
source_file="res://bark.jpg"
dest_files=[ "res://.import/bark.jpg-db1925684069186df966c2d6a5bd27d7.s3tc.stex", "res://.import/bark.jpg-db1925684069186df966c2d6a5bd27d7.etc.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@ -0,0 +1,7 @@
[gd_resource type="Environment3D" load_steps=2 format=3]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/floor.png-d43f03cb7a8f42941311ed90ed2021b9.s3tc.stex"
path.etc="res://.import/floor.png-d43f03cb7a8f42941311ed90ed2021b9.etc.stex"
metadata={
"imported_formats": [ "s3tc", "etc" ],
"vram_texture": true
}
[deps]
source_file="res://floor.png"
dest_files=[ "res://.import/floor.png-d43f03cb7a8f42941311ed90ed2021b9.s3tc.stex", "res://.import/floor.png-d43f03cb7a8f42941311ed90ed2021b9.etc.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=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
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -0,0 +1,25 @@
; 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=4
[application]
config/name="Procedural Trees"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
[physics]
common/enable_pause_aware_picking=true
[rendering]
vram_compression/import_etc=true
vram_compression/import_etc2=false
environment/default_environment="res://default_env.tres"

View File

@ -0,0 +1,12 @@
The textures are from the https://github.com/jarikomppa/proctree repository.
From the original readme:
All of the textures are CC0 / public domain material (primarily, if not completely, by nobiax.deviantart.com). The additional textures do let you make more varieties of trees though; the base package only comes with one trunk and twig texture.
Additional (not mandatory) 400 megs of trunk / twig textures
http://iki.fi/sol/zip/happytree_20150118_tex.zip
If you opt to download the additional textures, just unzip both zips in the same place. HappyTree will work without the additional textures (it'll actually be faster), so if you're just trying it out, I recommend NOT downloading the additional stuff.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/twig.png-dfe3c857b25e019a9891469879fedf6a.s3tc.stex"
path.etc="res://.import/twig.png-dfe3c857b25e019a9891469879fedf6a.etc.stex"
metadata={
"imported_formats": [ "s3tc", "etc" ],
"vram_texture": true
}
[deps]
source_file="res://twig.png"
dest_files=[ "res://.import/twig.png-dfe3c857b25e019a9891469879fedf6a.s3tc.stex", "res://.import/twig.png-dfe3c857b25e019a9891469879fedf6a.etc.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@ -0,0 +1,88 @@
extends Node
export(String) var database_location : String = "user://database.sqlite"
func _ready() -> void:
DatabaseManager.connect("initialized", self, "on_databases_initialized", [], CONNECT_ONESHOT)
var d : Directory = Directory.new()
var bd : String = database_location.get_base_dir()
var loc : String = d.get_filesystem_abspath_for(bd).append_path(database_location.get_file())
PLogger.log_message("Database file location: " + loc)
PLogger.log_message("(Editor->Project->Open User Data Folder)")
var file : File = File.new()
if !file.file_exists(loc):
PLogger.log_message("Database file doesn't exists, will run migrations!")
PLogger.log_message("(Editor->Project->Open User Data Folder)")
call_deferred("migrate")
else:
DatabaseManager.call_deferred("initialized")
var db : SQLite3Database = SQLite3Database.new()
db.connection_string = loc
DatabaseManager.add_database(db)
func migrate() -> void:
PLogger.log_message("Running migrations!")
DatabaseManager.connect("migration", self, "_migration")
DatabaseManager.migrate(true, false, 0)
DatabaseManager.call_deferred("initialized")
func on_databases_initialized() -> void:
# Load sessions after the databases are initialized
# This happens on the Main node.
call_deferred("load_data")
func _migration(clear: bool, should_seed: bool, pseed: int) -> void:
randomize()
var tb : TableBuilder = DatabaseManager.ddb.get_connection().get_table_builder()
tb.create_table("data_table");
tb.integer("id").auto_increment().next_row();
tb.varchar("data_varchar", 60).not_null().next_row();
tb.text("data_text").not_null().next_row();
tb.integer("data_int").not_null().next_row();
tb.real_double("data_double").not_null().next_row();
tb.primary_key("id");
tb.ccreate_table();
tb.run_query();
print("Running:")
print(tb.result)
var qb : QueryBuilder = DatabaseManager.ddb.get_connection().get_query_builder()
for i in range(10):
qb.reset()
qb.insert("data_table", "data_varchar,data_text,data_int,data_double").values()
qb.vals("vc" + str(randi()))
qb.vals("text" + str(randi()))
qb.vali(randi())
qb.vald(randf() * 100000)
qb.cvalues()
qb.end_command()
qb.run_query()
print("Running:")
print(qb.result)
func load_data() -> void:
print("Querying data from table:")
var qb : QueryBuilder = DatabaseManager.ddb.get_connection().get_query_builder()
var qr : QueryResult = qb.select("id,data_varchar,data_text,data_int,data_double").from("data_table").run()
while qr.next_row():
print("ROW:")
print("id: " + str(qr.get_cell_int(0)))
print("data_varchar: " + str(qr.get_cell(1)))
print("data_text: " + str(qr.get_cell(2)))
print("data_int: " + str(qr.get_cell_int(3)))
print("data_double: " + str(qr.get_cell_double(4)))

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource path="res://Main.gd" type="Script" id=4]
[node name="Main" type="Node"]
script = ExtResource( 4 )

View File

@ -0,0 +1,7 @@
[gd_resource type="Environment3D" load_steps=2 format=3]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=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
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -0,0 +1,25 @@
; 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=4
[application]
config/name="Database Simple"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
[physics]
common/enable_pause_aware_picking=true
[rendering]
vram_compression/import_etc=true
vram_compression/import_etc2=false
environment/default_environment="res://default_env.tres"

View File

@ -0,0 +1,122 @@
extends Node
export(String) var database_location : String = "user://database.sqlite"
func _ready() -> void:
DatabaseManager.connect("initialized", self, "on_databases_initialized", [], CONNECT_ONESHOT)
var d : Directory = Directory.new()
var bd : String = database_location.get_base_dir()
var loc : String = d.get_filesystem_abspath_for(bd).append_path(database_location.get_file())
PLogger.log_message("Database file location: " + loc)
PLogger.log_message("(Editor->Project->Open User Data Folder)")
var file : File = File.new()
if !file.file_exists(loc):
PLogger.log_message("Database file doesn't exists, will run migrations!")
PLogger.log_message("(Editor->Project->Open User Data Folder)")
call_deferred("migrate")
else:
DatabaseManager.call_deferred("initialized")
var db : SQLite3Database = SQLite3Database.new()
db.connection_string = loc
DatabaseManager.add_database(db)
func migrate() -> void:
PLogger.log_message("Running migrations!")
DatabaseManager.connect("migration", self, "_migration")
DatabaseManager.migrate(true, false, 0)
DatabaseManager.call_deferred("initialized")
func on_databases_initialized() -> void:
# Load sessions after the databases are initialized
# This happens on the Main node.
call_deferred("load_data")
func _migration(clear: bool, should_seed: bool, pseed: int) -> void:
randomize()
var tb : TableBuilder = DatabaseManager.ddb.get_connection().get_table_builder()
tb.create_table("data_table");
tb.integer("id").auto_increment().next_row();
tb.varchar("data_varchar", 60).not_null().next_row();
tb.text("data_text").not_null().next_row();
tb.integer("data_int").not_null().next_row();
tb.real_double("data_double").not_null().next_row();
tb.primary_key("id");
tb.ccreate_table();
tb.run_query();
print("Running:")
print(tb.result)
var qb : QueryBuilder = DatabaseManager.ddb.get_connection().get_query_builder()
qb.insert("data_table", "data_varchar,data_text,data_int,data_double").values()
qb.valph().valph().valph().valph()
qb.cvalues()
qb.end_command()
print("Prepared statement:")
print(qb.result)
var ps : PreparedStatement = qb.create_prepared_statement()
ps.prepare()
print("Inserting 10 values!")
for i in range(10):
ps.reset()
ps.bind_text(1, "vc" + str(randi()))
ps.bind_text(2, "text" + str(randi()))
ps.bind_int(3, randi())
ps.bind_double(4, randf() * 100000)
ps.step()
func load_data() -> void:
print("Querying data from table using prepared statements:")
var qb : QueryBuilder = DatabaseManager.ddb.get_connection().get_query_builder()
var qr : QueryResult = qb.select("id").from("data_table").run()
var ids : PoolIntArray = PoolIntArray()
while qr.next_row():
ids.push_back(qr.get_cell_int(0))
qb.reset()
qb.select("id,data_varchar,data_text,data_int,data_double").from("data_table")
qb.where().wph("id")
qb.end_command()
print("Query prepared statement:")
print(qb.result)
var ps : PreparedStatement = qb.create_prepared_statement()
ps.prepare()
print("Querying rows one by one:")
for index in ids:
ps.reset()
ps.bind_int(1, index)
ps.step()
print("ps.column_count(): " + str(ps.column_count()))
print("id: " + str(ps.column_int(0)))
print("data_varchar: " + str(ps.column_text(1)))
print("data_text: " + str(ps.column_text(2)))
print("data_int: " + str(ps.column_int(3)))
print("data_double: " + str(ps.column_double(4)))

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource path="res://Main.gd" type="Script" id=4]
[node name="Main" type="Node"]
script = ExtResource( 4 )

View File

@ -0,0 +1,7 @@
[gd_resource type="Environment3D" load_steps=2 format=3]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=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
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -0,0 +1,25 @@
; 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=4
[application]
config/name="Database Prepared Statements"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
[physics]
common/enable_pause_aware_picking=true
[rendering]
vram_compression/import_etc=true
vram_compression/import_etc2=false
environment/default_environment="res://default_env.tres"

View File

@ -0,0 +1,23 @@
extends MarkdownRenderer
class_name CustomMarkdownRenderer
var count : int = 0
func _renderer_callback(data: MarkdownRendererCustomRendererCallback) -> void:
data.result = str(count) + "\n"
data.result += "callback_type:" + str(data.callback_type) + "\n"
data.result += "text:" + data.text + "\n"
data.result += "content:" + data.content + "\n"
data.result += "level:" + str(data.level) + "\n"
data.result += "list_flags:" + str(data.list_flags) + "\n"
data.result += "table_flags:" + str(data.table_flags) + "\n"
data.result += "link:" + data.link + "\n"
data.result += "auto_link_type:" + str(data.auto_link_type) + "\n"
data.result += "title:" + data.title + "\n"
data.result += "alt:" + data.alt + "\n"
data.result += "num:" + str(data.num) + "\n"
data.result += "display_mode:" + str(data.display_mode) + "\n"
data.result += "inline_render:" + str(data.inline_render) + "\n"
data.result += "\n\n"
count += 1

View File

@ -0,0 +1,14 @@
extends TextEdit
func _ready():
var f : File = File.new()
var mdr : CustomMarkdownRenderer = CustomMarkdownRenderer.new()
mdr.render_type = MarkdownRenderer.RENDERER_TYPE_CUSTOM
f.open("res://TEST.md", File.READ)
text = mdr.render(f.get_as_text())
f.close()

View File

@ -0,0 +1,31 @@
[gd_scene load_steps=3 format=3]
[ext_resource path="res://CustomRenderer.gd" type="Script" id=1]
[ext_resource path="res://NormalRenderer.gd" type="Script" id=2]
[node name="PanelContainer" type="PanelContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Main" type="HBoxContainer" parent="."]
margin_left = 7.0
margin_top = 7.0
margin_right = 1017.0
margin_bottom = 593.0
[node name="NormalRenderer" type="TextEdit" parent="Main"]
margin_right = 503.0
margin_bottom = 586.0
size_flags_horizontal = 3
size_flags_vertical = 3
wrap_enabled = true
script = ExtResource( 2 )
[node name="CustomRenderer" type="TextEdit" parent="Main"]
margin_left = 507.0
margin_right = 1010.0
margin_bottom = 586.0
size_flags_horizontal = 3
size_flags_vertical = 3
wrap_enabled = true
script = ExtResource( 1 )

View File

@ -0,0 +1,13 @@
extends TextEdit
func _ready():
var f : File = File.new()
var mdr : MarkdownRenderer = MarkdownRenderer.new()
f.open("res://TEST.md", File.READ)
text = mdr.render(f.get_as_text())
f.close()

View File

@ -0,0 +1,336 @@
# File
This is a test file from https://github.com/mxstbr/markdown-test-file/blob/master/TEST.md
MIT License
Copyright (c) 2017 Max Stoiber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# Markdown: Syntax
* [Overview](#overview)
* [Philosophy](#philosophy)
* [Inline HTML](#html)
* [Automatic Escaping for Special Characters](#autoescape)
* [Block Elements](#block)
* [Paragraphs and Line Breaks](#p)
* [Headers](#header)
* [Blockquotes](#blockquote)
* [Lists](#list)
* [Code Blocks](#precode)
* [Horizontal Rules](#hr)
* [Span Elements](#span)
* [Links](#link)
* [Emphasis](#em)
* [Code](#code)
* [Images](#img)
* [Miscellaneous](#misc)
* [Backslash Escapes](#backslash)
* [Automatic Links](#autolink)
**Note:** This document is itself written using Markdown; you
can [see the source for it by adding '.text' to the URL](/projects/markdown/syntax.text).
----
## Overview
### Philosophy
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
Readability, however, is emphasized above all else. A Markdown-formatted
document should be publishable as-is, as plain text, without looking
like it's been marked up with tags or formatting instructions. While
Markdown's syntax has been influenced by several existing text-to-HTML
filters -- including [Setext](http://docutils.sourceforge.net/mirror/setext.html), [atx](http://www.aaronsw.com/2002/atx/), [Textile](http://textism.com/tools/textile/), [reStructuredText](http://docutils.sourceforge.net/rst.html),
[Grutatext](http://www.triptico.com/software/grutatxt.html), and [EtText](http://ettext.taint.org/doc/) -- the single biggest source of
inspiration for Markdown's syntax is the format of plain text email.
## Block Elements
### Paragraphs and Line Breaks
A paragraph is simply one or more consecutive lines of text, separated
by one or more blank lines. (A blank line is any line that looks like a
blank line -- a line containing nothing but spaces or tabs is considered
blank.) Normal paragraphs should not be indented with spaces or tabs.
The implication of the "one or more consecutive lines of text" rule is
that Markdown supports "hard-wrapped" text paragraphs. This differs
significantly from most other text-to-HTML formatters (including Movable
Type's "Convert Line Breaks" option) which translate every line break
character in a paragraph into a `<br />` tag.
When you *do* want to insert a `<br />` break tag using Markdown, you
end a line with two or more spaces, then type return.
### Headers
Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
Optionally, you may "close" atx-style headers. This is purely
cosmetic -- you can use this if you think it looks better. The
closing hashes don't even need to match the number of hashes
used to open the header. (The number of opening hashes
determines the header level.)
### Blockquotes
Markdown uses email-style `>` characters for blockquoting. If you're
familiar with quoting passages of text in an email message, then you
know how to create a blockquote in Markdown. It looks best if you hard
wrap the text and put a `>` before every line:
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
>
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
> id sem consectetuer libero luctus adipiscing.
Markdown allows you to be lazy and only put the `>` before the first
line of a hard-wrapped paragraph:
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.
Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
adding additional levels of `>`:
> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.
Blockquotes can contain other Markdown elements, including headers, lists,
and code blocks:
> ## This is a header.
>
> 1. This is the first list item.
> 2. This is the second list item.
>
> Here's some example code:
>
> return shell_exec("echo $input | $markdown_script");
Any decent text editor should make email-style quoting easy. For
example, with BBEdit, you can make a selection and choose Increase
Quote Level from the Text menu.
### Lists
Markdown supports ordered (numbered) and unordered (bulleted) lists.
Unordered lists use asterisks, pluses, and hyphens -- interchangably
-- as list markers:
* Red
* Green
* Blue
is equivalent to:
+ Red
+ Green
+ Blue
and:
- Red
- Green
- Blue
Ordered lists use numbers followed by periods:
1. Bird
2. McHale
3. Parish
It's important to note that the actual numbers you use to mark the
list have no effect on the HTML output Markdown produces. The HTML
Markdown produces from the above list is:
If you instead wrote the list in Markdown like this:
1. Bird
1. McHale
1. Parish
or even:
3. Bird
1. McHale
8. Parish
you'd get the exact same HTML output. The point is, if you want to,
you can use ordinal numbers in your ordered Markdown lists, so that
the numbers in your source match the numbers in your published HTML.
But if you want to be lazy, you don't have to.
To make lists look nice, you can wrap items with hanging indents:
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
But if you want to be lazy, you don't have to:
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
List items may consist of multiple paragraphs. Each subsequent
paragraph in a list item must be indented by either 4 spaces
or one tab:
1. This is a list item with two paragraphs. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
sit amet velit.
2. Suspendisse id sem consectetuer libero luctus adipiscing.
It looks nice if you indent every line of the subsequent
paragraphs, but here again, Markdown will allow you to be
lazy:
* This is a list item with two paragraphs.
This is the second paragraph in the list item. You're
only required to indent the first line. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.
* Another item in the same list.
To put a blockquote within a list item, the blockquote's `>`
delimiters need to be indented:
* A list item with a blockquote:
> This is a blockquote
> inside a list item.
To put a code block within a list item, the code block needs
to be indented *twice* -- 8 spaces or two tabs:
* A list item with a code block:
<code goes here>
### Code Blocks
Pre-formatted code blocks are used for writing about programming or
markup source code. Rather than forming normal paragraphs, the lines
of a code block are interpreted literally. Markdown wraps a code block
in both `<pre>` and `<code>` tags.
To produce a code block in Markdown, simply indent every line of the
block by at least 4 spaces or 1 tab.
This is a normal paragraph:
This is a code block.
Here is an example of AppleScript:
tell application "Foo"
beep
end tell
A code block continues until it reaches a line that is not indented
(or the end of the article).
Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
are automatically converted into HTML entities. This makes it very
easy to include example HTML source code using Markdown -- just paste
it and indent it, and Markdown will handle the hassle of encoding the
ampersands and angle brackets. For example, this:
<div class="footer">
&copy; 2004 Foo Corporation
</div>
Regular Markdown syntax is not processed within code blocks. E.g.,
asterisks are just literal asterisks within a code block. This means
it's also easy to use Markdown to write about Markdown's own syntax.
```
tell application "Foo"
beep
end tell
```
## Span Elements
### Links
Markdown supports two style of links: *inline* and *reference*.
In both styles, the link text is delimited by [square brackets].
To create an inline link, use a set of regular parentheses immediately
after the link text's closing square bracket. Inside the parentheses,
put the URL where you want the link to point, along with an *optional*
title for the link, surrounded in quotes. For example:
This is [an example](http://example.com/) inline link.
[This link](http://example.net/) has no title attribute.
### Emphasis
Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
emphasis. Text wrapped with one `*` or `_` will be wrapped with an
HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
`<strong>` tag. E.g., this input:
*single asterisks*
_single underscores_
**double asterisks**
__double underscores__
### Code
To indicate a span of code, wrap it with backtick quotes (`` ` ``).
Unlike a pre-formatted code block, a code span indicates code within a
normal paragraph. For example:
Use the `printf()` function.

View File

@ -0,0 +1,7 @@
[gd_resource type="Environment3D" load_steps=2 format=3]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=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
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -0,0 +1,35 @@
; 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=4
_global_script_classes=[ {
"base": "MarkdownRenderer",
"class": @"CustomMarkdownRenderer",
"language": @"GDScript",
"path": "res://CustomMarkdownRenderer.gd"
} ]
_global_script_class_icons={
@"CustomMarkdownRenderer": ""
}
[application]
config/name="Markdown Renderer Test"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
[physics]
common/enable_pause_aware_picking=true
[rendering]
vram_compression/import_etc=true
vram_compression/import_etc2=false
environment/default_environment="res://default_env.tres"

View File

@ -0,0 +1,51 @@
extends Node
export (float, 0, 3200, 100) var linear_speed_max := 800.0 setget set_linear_speed_max
export (float, 0, 10000, 100) var linear_acceleration_max := 80.0 setget set_linear_acceleration_max
export (float, 0, 100, 0.1) var arrival_tolerance := 25.0 setget set_arrival_tolerance
export (float, 0, 500, 10) var deceleration_radius := 125.0 setget set_deceleration_radius
onready var arriver := $Arriver
onready var target_drawer := $TargetDrawer
func _ready() -> void:
arriver.setup(linear_speed_max, linear_acceleration_max, arrival_tolerance, deceleration_radius)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.is_pressed():
arriver.target.position = Vector3(event.position.x, event.position.y, 0)
target_drawer.update()
func set_arrival_tolerance(value: float) -> void:
arrival_tolerance = value
if not is_inside_tree():
return
arriver.arrive.arrival_tolerance = value
func set_deceleration_radius(value: float) -> void:
deceleration_radius = value
if not is_inside_tree():
return
arriver.arrive.deceleration_radius = value
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
arriver.agent.linear_speed_max = value
func set_linear_acceleration_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
arriver.agent.linear_acceleration_max = value

View File

@ -0,0 +1,39 @@
[gd_scene load_steps=8 format=3]
[ext_resource path="res://Demos/Arrive/Arriver.gd" type="Script" id=1]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=2]
[ext_resource path="res://Demos/Arrive/ArriveDemo.gd" type="Script" id=3]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=4]
[ext_resource path="res://Demos/Arrive/TargetDrawer.gd" type="Script" id=5]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=6]
[sub_resource type="CircleShape2D" id=1]
radius = 23.2163
[node name="ArriveDemo" type="Node"]
script = ExtResource( 3 )
linear_speed_max = 1600.0
linear_acceleration_max = 5000.0
arrival_tolerance = 35.0
deceleration_radius = 180.0
[node name="BackgroudLayer" parent="." instance=ExtResource( 4 )]
[node name="TargetDrawer" type="Node2D" parent="."]
script = ExtResource( 5 )
[node name="Arriver" type="KinematicBody2D" parent="."]
show_behind_parent = true
position = Vector2( 960, 540 )
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Arriver"]
shape = SubResource( 1 )
script = ExtResource( 6 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 6.0
[node name="DemoInterface" parent="." instance=ExtResource( 2 )]
text_bbcode = "Arrive Demo
Mouse click to make the [color=lime]green \"Player\"[/color] move to the [color=fuchsia]purple target[/color]"

View File

@ -0,0 +1,32 @@
extends KinematicBody2D
var agent := GSAIKinematicBody2DAgent.new()
var target := GSAIAgentLocation.new()
var arrive := GSAIArrive.new()
var _accel := GSAITargetAcceleration.new()
var _velocity := Vector2()
var _drag := 0.1
func _init() -> void:
agent.body = self
arrive.agent = agent
arrive.target = target
func _physics_process(delta: float) -> void:
arrive.calculate_steering(_accel)
agent.apply_steering(_accel, delta)
func setup(
linear_speed_max: float,
linear_acceleration_max: float,
arrival_tolerance: float,
deceleration_radius: float
) -> void:
agent.linear_speed_max = linear_speed_max
agent.linear_acceleration_max = linear_acceleration_max
agent.linear_drag_percentage = _drag
arrive.deceleration_radius = deceleration_radius
arrive.arrival_tolerance = arrival_tolerance
target.position = agent.position

View File

@ -0,0 +1,17 @@
extends Node2D
var deceleration_radius_color : Color = Color(1.0, 0.419, 0.592, 0.5)
var arrival_tolerance_color : Color = Color(0.278, 0.231, 0.47, 0.3)
var arriver: Node2D
func _ready() -> void:
yield(owner, "ready")
arriver = owner.arriver
func _draw():
var target_position := GSAIUtils.to_vector2(arriver.target.position)
draw_circle(target_position, owner.deceleration_radius, deceleration_radius_color)
draw_circle(target_position, owner.arrival_tolerance, arrival_tolerance_color)

View File

@ -0,0 +1,95 @@
[gd_scene load_steps=14 format=3]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=1]
[ext_resource path="res://Demos/Arrive3d/Camera.gd" type="Script" id=2]
[ext_resource path="res://Demos/Arrive3d/Seek3dDemo.gd" type="Script" id=3]
[ext_resource path="res://Demos/Arrive3d/Seeker.gd" type="Script" id=4]
[ext_resource path="res://Demos/Arrive3d/SeekerMat.tres" type="Material" id=5]
[sub_resource type="CapsuleShape" id=1]
[sub_resource type="CapsuleMesh" id=2]
[sub_resource type="CubeMesh" id=3]
material = ExtResource( 5 )
size = Vector3( 0.5, 0.5, 1 )
[sub_resource type="CylinderMesh" id=4]
top_radius = 2.0
bottom_radius = 2.0
height = 0.1
[sub_resource type="SpatialMaterial" id=5]
albedo_color = Color( 0.945098, 0.85098, 0.0745098, 1 )
[sub_resource type="BoxShape" id=6]
extents = Vector3( 1000, 0.1, 1000 )
[sub_resource type="PlaneMesh" id=7]
size = Vector2( 250, 250 )
[sub_resource type="SpatialMaterial" id=8]
albedo_color = Color( 0.0941176, 0.235294, 0.486275, 1 )
[node name="Arrive3dDemo" type="Node"]
script = ExtResource( 3 )
linear_speed_max = 50.0
linear_acceleration_max = 53.2
deceleration_radius = 10.8
angular_speed_max = 550
angular_accel_max = 910
[node name="Arriver" type="KinematicBody" parent="."]
script = ExtResource( 4 )
[node name="CollisionShape" type="CollisionShape" parent="Arriver"]
transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1.5, 0 )
shape = SubResource( 1 )
[node name="Capsule" type="MeshInstance" parent="Arriver"]
transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1.5, 0 )
mesh = SubResource( 2 )
material/0 = ExtResource( 5 )
[node name="Nose" type="MeshInstance" parent="Arriver"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 1.25 )
mesh = SubResource( 3 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 0.989952, 0.0720094, -0.121693, 0.0339305, 0.714503, 0.69881, 0.137271, -0.695917, 0.70488, -7.68317, 14.1265, 25.616 )
current = true
script = ExtResource( 2 )
[node name="RayCast" type="RayCast" parent="Camera"]
enabled = true
cast_to = Vector3( -627, 200, -777 )
collision_mask = 2
[node name="MouseTarget" type="Spatial" parent="."]
transform = Transform( 1, 0, 7.45058e-09, 0, 1, 0, 7.45058e-09, 0, 1, -4.76837e-07, 9.53674e-07, 1.90735e-06 )
[node name="MeshInstance" type="MeshInstance" parent="MouseTarget"]
mesh = SubResource( 4 )
material/0 = SubResource( 5 )
[node name="StaticBody" type="StaticBody" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0 )
collision_layer = 2
collision_mask = 2
[node name="CollisionShape" type="CollisionShape" parent="StaticBody"]
shape = SubResource( 6 )
[node name="Ground" type="MeshInstance" parent="."]
mesh = SubResource( 7 )
material/0 = SubResource( 8 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( -0.588165, 0.462179, -0.663666, -0.804031, -0.245728, 0.541436, 0.087159, 0.852061, 0.516134, -17.6076, 12.1748, 0 )
light_energy = 0.5
shadow_enabled = true
[node name="DemoInterface" parent="." instance=ExtResource( 1 )]
mouse_filter = 2
text_bbcode = "3D Arrive Demo
Move the mouse about the field to have the agent turn towards and smoothly arrive at the target marker."

View File

@ -0,0 +1,24 @@
extends Camera
var target: Spatial
onready var ray := $RayCast
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
_set_target_position(event.position)
func setup(_target: Spatial) -> void:
self.target = _target
_set_target_position(get_viewport().get_mouse_position())
func _set_target_position(position: Vector2) -> void:
var to = project_local_ray_normal(position) * 10000
ray.cast_to = to
ray.force_raycast_update()
if ray.is_colliding():
var point = ray.get_collision_point()
target.transform.origin = point

View File

@ -0,0 +1,92 @@
extends Node
export (float, 0, 100, 5) var linear_speed_max := 10.0 setget set_linear_speed_max
export (float, 0, 100, 0.1) var linear_acceleration_max := 1.0 setget set_linear_acceleration_max
export (float, 0, 50, 0.1) var arrival_tolerance := 0.5 setget set_arrival_tolerance
export (float, 0, 50, 0.1) var deceleration_radius := 5.0 setget set_deceleration_radius
export (int, 0, 1080, 10) var angular_speed_max := 270 setget set_angular_speed_max
export (int, 0, 2048, 10) var angular_accel_max := 45 setget set_angular_accel_max
export (int, 0, 178, 2) var align_tolerance := 5 setget set_align_tolerance
export (int, 0, 180, 2) var angular_deceleration_radius := 45 setget set_angular_deceleration_radius
onready var target := $MouseTarget
onready var arriver := $Arriver
func _ready() -> void:
arriver.setup(
deg2rad(align_tolerance),
deg2rad(angular_deceleration_radius),
deg2rad(angular_accel_max),
deg2rad(angular_speed_max),
deceleration_radius,
arrival_tolerance,
linear_acceleration_max,
linear_speed_max,
target
)
$Camera.setup(target)
func set_align_tolerance(value: int) -> void:
align_tolerance = value
if not is_inside_tree():
return
arriver.face.alignment_tolerance = deg2rad(value)
func set_angular_deceleration_radius(value: int) -> void:
deceleration_radius = value
if not is_inside_tree():
return
arriver.face.deceleration_radius = deg2rad(value)
func set_angular_accel_max(value: int) -> void:
angular_accel_max = value
if not is_inside_tree():
return
arriver.agent.angular_acceleration_max = deg2rad(value)
func set_angular_speed_max(value: int) -> void:
angular_speed_max = value
if not is_inside_tree():
return
arriver.agent.angular_speed_max = deg2rad(value)
func set_arrival_tolerance(value: float) -> void:
arrival_tolerance = value
if not is_inside_tree():
return
arriver.arrive.arrival_tolerance = value
func set_deceleration_radius(value: float) -> void:
deceleration_radius = value
if not is_inside_tree():
return
arriver.arrive.deceleration_radius = value
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
arriver.agent.linear_speed_max = value
func set_linear_acceleration_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
arriver.agent.linear_acceleration_max = value

View File

@ -0,0 +1,64 @@
extends KinematicBody
var target_node: Spatial
var agent : GSAIKinematicBody3DAgent = null
var target : GSAIAgentLocation = null
var accel : GSAITargetAcceleration = null
var blend : GSAIBlend = null
var face : GSAIFace = null
var arrive : GSAIArrive = null
func _init() -> void:
agent = GSAIKinematicBody3DAgent.new()
agent.body = self
target = GSAIAgentLocation.new()
accel = GSAITargetAcceleration.new()
blend = GSAIBlend.new()
blend.agent = agent
face = GSAIFace.new()
face.agent = agent
face.target = target
face.use_z = true
arrive = GSAIArrive.new()
arrive.agent = agent
arrive.target = target
func _physics_process(delta: float) -> void:
target.position = target_node.transform.origin
target.position.y = transform.origin.y
blend.calculate_steering(accel)
agent.apply_steering(accel, delta)
func setup(
align_tolerance: float,
angular_deceleration_radius: float,
angular_accel_max: float,
angular_speed_max: float,
deceleration_radius: float,
arrival_tolerance: float,
linear_acceleration_max: float,
linear_speed_max: float,
_target: Spatial
) -> void:
agent.linear_speed_max = linear_speed_max
agent.linear_acceleration_max = linear_acceleration_max
agent.linear_drag_percentage = 0.05
agent.angular_acceleration_max = angular_accel_max
agent.angular_speed_max = angular_speed_max
agent.angular_drag_percentage = 0.1
arrive.arrival_tolerance = arrival_tolerance
arrive.deceleration_radius = deceleration_radius
face.alignment_tolerance = align_tolerance
face.deceleration_radius = angular_deceleration_radius
target_node = _target
self.target.position = target_node.transform.origin
blend.add_behavior(arrive, 1)
blend.add_behavior(face, 1)

View File

@ -0,0 +1,4 @@
[gd_resource type="SpatialMaterial" format=2]
[resource]
albedo_color = Color( 0.152941, 0.764706, 0.247059, 1 )

View File

@ -0,0 +1,40 @@
extends Node
export (float, 0, 1000, 40) var linear_speed_max := 350.0 setget set_linear_speed_max
export (float, 0, 4000, 2) var linear_acceleration_max := 40.0 setget set_linear_accel_max
export (float, 0, 500, 10) var proximity_radius := 140.0 setget set_proximity_radius
export var draw_proximity := true setget set_draw_proximity
onready var spawner := $Spawner
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
spawner.set_linear_speed_max(value)
func set_linear_accel_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
spawner.set_linear_accel_max(value)
func set_proximity_radius(value: float) -> void:
proximity_radius = value
if not is_inside_tree():
return
spawner.set_proximity_radius(value)
func set_draw_proximity(value: bool) -> void:
draw_proximity = value
if not is_inside_tree():
return
spawner.set_draw_proximity(value)

View File

@ -0,0 +1,26 @@
[gd_scene load_steps=6 format=3]
[ext_resource path="res://Demos/AvoidCollisions/Spawner.gd" type="Script" id=1]
[ext_resource path="res://Demos/AvoidCollisions/AvoidCollisionsDemo.gd" type="Script" id=2]
[ext_resource path="res://Demos/AvoidCollisions/Avoider.tscn" type="PackedScene" id=3]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=4]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[node name="AvoidCollisionsDemo" type="Node"]
script = ExtResource( 2 )
linear_speed_max = 520.0
linear_acceleration_max = 2250.0
proximity_radius = 100.0
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Spawner" type="Node2D" parent="."]
script = ExtResource( 1 )
avoider_template = ExtResource( 3 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
agent_count = 80
[node name="DemoInterface" parent="." instance=ExtResource( 4 )]
text_bbcode = "Avoid Collisions Demo
Watch each agent try to keep traveling in a particular direction, but prioritize avoiding collisions with other agents."

View File

@ -0,0 +1,112 @@
extends KinematicBody2D
var draw_proximity: bool
var _boundary_right: float
var _boundary_bottom: float
var _radius: float
var _accel := GSAITargetAcceleration.new()
var _velocity := Vector2.ZERO
var _direction := Vector2()
var _drag := 0.1
var _color := Color(0.4, 1.0, 0.89, 0.3)
onready var collision := $CollisionShape2D
var agent :GSAIKinematicBody2DAgent= null
var proximity :GSAIRadiusProximity= null
var avoid :GSAIAvoidCollisions= null
var target :GSAIAgentLocation= null
var seek :GSAISeek= null
var priority :GSAIPriority= null
func _ready() -> void:
agent = GSAIKinematicBody2DAgent.new()
agent.body = self
proximity = GSAIRadiusProximity.new()
proximity.agent = agent
proximity.radius = 140
avoid = GSAIAvoidCollisions.new()
avoid.agent = agent
avoid.proximity = proximity
target = GSAIAgentLocation.new()
seek = GSAISeek.new()
seek.agent = agent
seek.target = target
priority = GSAIPriority.new()
priority.agent = agent
priority.zero_threshold = 0.0001
func _draw() -> void:
if draw_proximity:
draw_circle(Vector2.ZERO, proximity.radius, _color)
func _physics_process(delta: float) -> void:
target.position.x = agent.position.x + _direction.x * _radius
target.position.y = agent.position.y + _direction.y * _radius
priority.calculate_steering(_accel)
agent.apply_steering(_accel, delta)
func setup(
linear_speed_max: float,
linear_accel_max: float,
proximity_radius: float,
boundary_right: float,
boundary_bottom: float,
_draw_proximity: bool,
rng: RandomNumberGenerator
) -> void:
rng.randomize()
_direction = Vector2(rng.randf_range(-1, 1), rng.randf_range(-1, 1)).normalized()
agent.linear_speed_max = linear_speed_max
agent.linear_acceleration_max = linear_accel_max
proximity.radius = proximity_radius
_boundary_bottom = boundary_bottom
_boundary_right = boundary_right
_radius = collision.shape.radius
agent.bounding_radius = _radius
agent.linear_drag_percentage = _drag
self.draw_proximity = _draw_proximity
priority.add_behavior(avoid)
priority.add_behavior(seek)
func set_proximity_agents(agents: Array) -> void:
proximity.agents = agents
func set_random_nonoverlapping_position(others: Array, distance_from_boundary_min: float) -> void:
var rng := RandomNumberGenerator.new()
rng.randomize()
var tries_max := max(100, others.size() * others.size())
while tries_max > 0:
tries_max -= 1
global_position.x = rng.randf_range(
distance_from_boundary_min, _boundary_right - distance_from_boundary_min
)
global_position.y = rng.randf_range(
distance_from_boundary_min, _boundary_bottom - distance_from_boundary_min
)
var done := true
for i in range(others.size()):
var other: Node2D = others[i]
if (
other.global_position.distance_to(position)
<= _radius * 2 + distance_from_boundary_min
):
done = false
if done:
break

View File

@ -0,0 +1,17 @@
[gd_scene load_steps=4 format=3]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=1]
[ext_resource path="res://Demos/AvoidCollisions/Avoider.gd" type="Script" id=2]
[sub_resource type="CircleShape2D" id=1]
radius = 21.3503
[node name="Avoider" type="KinematicBody2D"]
script = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )
script = ExtResource( 1 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
outer_color = Color( 1, 0.709804, 0.439216, 1 )
stroke = 5.0

View File

@ -0,0 +1,66 @@
extends Node2D
export var avoider_template: PackedScene
export var inner_color := Color()
export var outer_color := Color()
export var agent_count := 60
var boundaries: Vector2
func _ready() -> void:
boundaries = Vector2(
ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"]
)
var rng := RandomNumberGenerator.new()
var avoiders := []
var avoider_agents := []
for i in range(agent_count):
var avoider := avoider_template.instance()
add_child(avoider)
avoider.setup(
owner.linear_speed_max,
owner.linear_acceleration_max,
owner.proximity_radius,
boundaries.x,
boundaries.y,
true if i == 0 and owner.draw_proximity else false,
rng
)
avoider_agents.append(avoider.agent)
avoider.set_random_nonoverlapping_position(avoiders, 16)
if i == 0:
avoider.collision.inner_color = inner_color
avoider.collision.outer_color = outer_color
avoiders.append(avoider)
if i % 10 == 0:
yield(get_tree(), "idle_frame")
for child in get_children():
child.set_proximity_agents(avoider_agents)
func _physics_process(_delta: float) -> void:
for child in get_children():
child.global_position = child.global_position.posmodv(boundaries)
func set_linear_speed_max(value: float) -> void:
for child in get_children():
child.agent.linear_speed_max = value
func set_linear_accel_max(value: float) -> void:
for child in get_children():
child.agent.linear_acceleration_max = value
func set_proximity_radius(value: float) -> void:
for child in get_children():
child.proximity.radius = value
get_child(0).update()
func set_draw_proximity(value: bool) -> void:
var child := get_child(0)
child.draw_proximity = value
child.update()

View File

@ -0,0 +1,28 @@
class_name DemoPickerUI
extends Control
# warning-ignore:unused_signal
signal demo_requested
var demo_path := "" setget set_demo_path
onready var list: ItemList = $VBoxContainer/ItemList
onready var button: Button = $VBoxContainer/Button
func _ready() -> void:
# warning-ignore:return_value_discarded
list.connect("demo_selected", self, "set_demo_path")
# warning-ignore:return_value_discarded
list.connect("item_activated", self, "_on_ItemList_item_activated")
# warning-ignore:return_value_discarded
button.connect("pressed", self, "emit_signal", ["demo_requested"])
demo_path = list.file_paths[0]
func set_demo_path(value: String) -> void:
demo_path = value
func _on_ItemList_item_activated(_index: int) -> void:
emit_signal("demo_requested")

View File

@ -0,0 +1,16 @@
extends Node2D
func load_demo(scene_path: String) -> void:
if not scene_path:
return
var demo = load(scene_path)
if demo:
add_child(demo.instance())
func unload() -> void:
for node in get_children():
call_deferred("remove_child", node)
node.queue_free()

View File

@ -0,0 +1,81 @@
[gd_scene load_steps=7 format=3]
[ext_resource path="res://Demos/PopulateItemList.gd" type="Script" id=1]
[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=2]
[ext_resource path="res://assets/sprites/background.png" type="Texture" id=3]
[ext_resource path="res://Demos/DemoPickerUI.gd" type="Script" id=4]
[ext_resource path="res://Demos/DemoPlayer.gd" type="Script" id=5]
[ext_resource path="res://Demos/Demos.gd" type="Script" id=6]
[node name="Demos" type="Node"]
script = ExtResource( 6 )
[node name="DemoPlayer" type="Node2D" parent="."]
script = ExtResource( 5 )
[node name="DemoPickerUI" type="Control" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 2 )
script = ExtResource( 4 )
[node name="TextureRect" type="TextureRect" parent="DemoPickerUI"]
anchor_right = 1.0
anchor_bottom = 1.0
rect_min_size = Vector2( 1024, 600 )
size_flags_horizontal = 3
size_flags_vertical = 3
texture = ExtResource( 3 )
expand = true
stretch_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="DemoPickerUI"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -341.0
margin_top = -290.0
margin_right = 341.0
margin_bottom = 290.0
rect_min_size = Vector2( 682, 0 )
size_flags_horizontal = 3
size_flags_vertical = 3
alignment = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ItemList" type="ItemList" parent="DemoPickerUI/VBoxContainer"]
margin_top = 231.0
margin_right = 682.0
margin_bottom = 240.0
auto_height = true
script = ExtResource( 1 )
[node name="Button" type="Button" parent="DemoPickerUI/VBoxContainer"]
margin_left = 201.0
margin_top = 248.0
margin_right = 481.0
margin_bottom = 348.0
rect_min_size = Vector2( 280, 100 )
size_flags_horizontal = 4
size_flags_vertical = 13
text = "Load scene"
[node name="ButtonGoBack" type="Button" parent="."]
visible = false
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 48.0
margin_top = -156.0
margin_right = 328.0
margin_bottom = -56.0
rect_min_size = Vector2( 280, 100 )
size_flags_horizontal = 4
size_flags_vertical = 13
theme = ExtResource( 2 )
text = "Go back"
__meta__ = {
"_edit_use_anchors_": false
}

View File

@ -0,0 +1,30 @@
extends Node
onready var demo_picker: DemoPickerUI = $DemoPickerUI
onready var demo_player := $DemoPlayer
onready var button_go_back: Button = $ButtonGoBack
func _ready() -> void:
# warning-ignore:return_value_discarded
demo_picker.connect("demo_requested", self, "_on_DemoPickerUI_demo_requested")
# warning-ignore:return_value_discarded
button_go_back.connect("pressed", self, "_on_ButtonGoBack_pressed")
func _input(event: InputEvent) -> void:
if event.is_action_pressed("toggle_fullscreen"):
OS.window_fullscreen = not OS.window_fullscreen
get_tree().set_input_as_handled()
func _on_DemoPickerUI_demo_requested() -> void:
demo_player.load_demo(demo_picker.demo_path)
demo_picker.hide()
button_go_back.show()
func _on_ButtonGoBack_pressed() -> void:
demo_player.unload()
button_go_back.hide()
demo_picker.show()

View File

@ -0,0 +1,61 @@
extends Node
export (int, 0, 1080, 2) var angular_speed_max := 120 setget set_angular_speed_max
export (int, 0, 2048, 2) var angular_accel_max := 10 setget set_angular_accel_max
export (int, 0, 180, 2) var align_tolerance := 5 setget set_align_tolerance
export (int, 0, 359, 2) var deceleration_radius := 45 setget set_deceleration_radius
export (float, 0, 1000, 40) var player_speed := 600.0 setget set_player_speed
onready var player := $Player
onready var turret := $Turret
func _ready() -> void:
player.speed = player_speed
turret.setup(
player.agent,
deg2rad(align_tolerance),
deg2rad(deceleration_radius),
deg2rad(angular_accel_max),
deg2rad(angular_speed_max)
)
func set_align_tolerance(value: int) -> void:
align_tolerance = value
if not is_inside_tree():
return
turret.face.alignment_tolerance = deg2rad(value)
func set_deceleration_radius(value: int) -> void:
deceleration_radius = value
if not is_inside_tree():
return
turret.face.deceleration_radius = deg2rad(value)
func set_angular_accel_max(value: int) -> void:
angular_accel_max = value
if not is_inside_tree():
return
turret.agent.angular_acceleration_max = deg2rad(value)
func set_angular_speed_max(value: int) -> void:
angular_speed_max = value
if not is_inside_tree():
return
turret.agent.angular_speed_max = deg2rad(value)
func set_player_speed(value: float) -> void:
player_speed = value
if not is_inside_tree():
return
player.speed = player_speed

View File

@ -0,0 +1,48 @@
[gd_scene load_steps=9 format=3]
[ext_resource path="res://Demos/Face/Turret.gd" type="Script" id=1]
[ext_resource path="res://Demos/Face/FaceDemo.gd" type="Script" id=2]
[ext_resource path="res://Demos/Face/Player.gd" type="Script" id=3]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=4]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=8]
[sub_resource type="CircleShape2D" id=1]
radius = 20.2633
[sub_resource type="CircleShape2D" id=2]
radius = 37.1052
[node name="FaceDemo" type="Node"]
script = ExtResource( 2 )
angular_speed_max = 662
angular_accel_max = 924
deceleration_radius = 136
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Player" type="KinematicBody2D" parent="."]
position = Vector2( 687.363, 351.005 )
script = ExtResource( 3 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"]
shape = SubResource( 1 )
script = ExtResource( 8 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 6.0
[node name="Turret" type="KinematicBody2D" parent="."]
position = Vector2( 984.348, 571.959 )
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Turret"]
shape = SubResource( 2 )
script = ExtResource( 8 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
outer_color = Color( 1, 0.709804, 0.439216, 1 )
stroke = 8.0
[node name="DemoInterface" parent="." instance=ExtResource( 4 )]
text_bbcode = "Face Demo
Move the [color=lime]green player[/color] around with WASD and notice the [color=#ffb570]orange turret[/color] orient itself"

View File

@ -0,0 +1,18 @@
extends KinematicBody2D
var speed: float
onready var agent := GSAIAgentLocation.new()
func _physics_process(_delta: float) -> void:
var movement := _get_movement()
move_and_slide(movement * speed)
agent.position = Vector3(global_position.x, global_position.y, 0)
func _get_movement() -> Vector2:
return Vector2(
Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"),
Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")
)

View File

@ -0,0 +1,47 @@
extends KinematicBody2D
var face: GSAIFace
var agent := GSAIKinematicBody2DAgent.new()
var _accel := GSAITargetAcceleration.new()
var _angular_drag := 0.1
var _cannon: Rect2
var _color: Color
onready var collision_shape := $CollisionShape2D
func _ready() -> void:
agent.body = self
var radius = collision_shape.shape.radius
_cannon = Rect2(Vector2(-5, 0), Vector2(10, -radius * 2))
_color = collision_shape.outer_color
func _physics_process(delta: float) -> void:
face.calculate_steering(_accel)
agent.apply_steering(_accel, delta)
func _draw() -> void:
draw_rect(_cannon, _color)
func setup(
player_agent: GSAIAgentLocation,
align_tolerance: float,
deceleration_radius: float,
angular_accel_max: float,
angular_speed_max: float
) -> void:
face = GSAIFace.new()
face.agent = agent
face.target = player_agent
face.alignment_tolerance = align_tolerance
face.deceleration_radius = deceleration_radius
agent.angular_acceleration_max = angular_accel_max
agent.angular_speed_max = angular_speed_max
agent.angular_drag_percentage = _angular_drag

View File

@ -0,0 +1,53 @@
extends Node2D
signal path_established(points)
var active_points := []
var is_drawing := false
var distance_threshold := 100.0
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
if is_drawing:
active_points.append(event.position)
update()
elif event is InputEventMouseButton:
if event.pressed and event.button_index == BUTTON_LEFT:
active_points.clear()
active_points.append(event.position)
is_drawing = true
update()
elif not event.pressed:
is_drawing = false
if active_points.size() >= 2:
_simplify()
func _draw() -> void:
if is_drawing:
for point in active_points:
draw_circle(point, 2, Color.red)
else:
if active_points.size() > 0:
draw_circle(active_points.front(), 2, Color.red)
draw_circle(active_points.back(), 2, Color.yellow)
draw_polyline(active_points, Color.skyblue, 1.0)
func _simplify() -> void:
var first: Vector2 = active_points.front()
var last: Vector2 = active_points.back()
var key := first
var simplified_path := [first]
for i in range(1, active_points.size()):
var point: Vector2 = active_points[i]
var distance := point.distance_to(key)
if distance > distance_threshold:
key = point
simplified_path.append(key)
active_points = simplified_path
if active_points.back() != last:
active_points.append(last)
update()
emit_signal("path_established", active_points)

View File

@ -0,0 +1,70 @@
extends Node
export (float, 0, 2000, 40) var linear_speed_max := 600.0 setget set_linear_speed_max
export (float, 0, 9000, 10.0) var linear_acceleration_max := 40.0 setget set_linear_acceleration_max
export (float, 0, 100, 0.1) var arrival_tolerance := 10.0 setget set_arrival_tolerance
export (float, 0, 500, 10) var deceleration_radius := 100.0 setget set_deceleration_radius
export (float, 0, 5, 0.1) var predict_time := 0.3 setget set_predict_time
export (float, 0, 200, 10.0) var path_offset := 20.0 setget set_path_offset
onready var drawer := $Drawer
onready var follower := $PathFollower
func _ready() -> void:
follower.setup(
path_offset,
predict_time,
linear_acceleration_max,
linear_speed_max,
deceleration_radius,
arrival_tolerance
)
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
follower.agent.linear_speed_max = value
func set_linear_acceleration_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
follower.agent.linear_acceleration_max = value
func set_arrival_tolerance(value: float) -> void:
arrival_tolerance = value
if not is_inside_tree():
return
follower.follow.arrival_tolerance = value
func set_deceleration_radius(value: float) -> void:
deceleration_radius = value
if not is_inside_tree():
return
follower.follow.deceleration_radius = value
func set_predict_time(value: float) -> void:
predict_time = value
if not is_inside_tree():
return
follower.follow.prediction_time = value
func set_path_offset(value: float) -> void:
path_offset = value
if not is_inside_tree():
return
follower.follow.path_offset = value

View File

@ -0,0 +1,37 @@
[gd_scene load_steps=8 format=3]
[ext_resource path="res://Demos/FollowPath/Drawer.gd" type="Script" id=1]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=2]
[ext_resource path="res://Demos/FollowPath/PathFollower.gd" type="Script" id=3]
[ext_resource path="res://Demos/FollowPath/FollowPathDemo.gd" type="Script" id=4]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=6]
[sub_resource type="CircleShape2D" id=1]
radius = 24.1954
[node name="FollowPathDemo" type="Node"]
script = ExtResource( 4 )
linear_speed_max = 920.0
linear_acceleration_max = 3740.0
deceleration_radius = 200.0
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Drawer" type="Node2D" parent="."]
script = ExtResource( 1 )
[node name="PathFollower" type="KinematicBody2D" parent="."]
position = Vector2( 960, 540 )
script = ExtResource( 3 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="PathFollower"]
shape = SubResource( 1 )
script = ExtResource( 6 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 6.0
[node name="DemoInterface" parent="." instance=ExtResource( 2 )]
text_bbcode = "Follow Path Demo
Use the mouse to draw a path on screen and watch the [color=lime]green \"Agent\"[/color] follow it to the end."

View File

@ -0,0 +1,58 @@
extends KinematicBody2D
var _velocity := Vector2.ZERO
var _accel := GSAITargetAcceleration.new()
var _valid := false
var _drag := 0.1
var agent := GSAIKinematicBody2DAgent.new()
var path := GSAIPath.new()
var follow := GSAIFollowPath.new()
func _ready() -> void:
agent.body = self
path.initialize(
[
Vector3(global_position.x, global_position.y, 0),
Vector3(global_position.x, global_position.y, 0)
],
true
)
follow.agent = agent
follow.path = path
follow.agent = agent
func setup(
path_offset: float,
predict_time: float,
accel_max: float,
speed_max: float,
decel_radius: float,
arrival_tolerance: float
) -> void:
owner.drawer.connect("path_established", self, "_on_Drawer_path_established")
follow.path_offset = path_offset
follow.prediction_time = predict_time
follow.deceleration_radius = decel_radius
follow.arrival_tolerance = arrival_tolerance
agent.linear_acceleration_max = accel_max
agent.linear_speed_max = speed_max
agent.linear_drag_percentage = _drag
func _physics_process(delta: float) -> void:
if _valid:
follow.calculate_steering(_accel)
agent.apply_steering(_accel, delta)
func _on_Drawer_path_established(points: Array) -> void:
var positions : PoolVector3Array = PoolVector3Array()
for p in points:
positions.append(Vector3(p.x, p.y, 0))
path.create_path(positions)
_valid = true

View File

@ -0,0 +1,79 @@
extends Node
onready var spawner := $Spawner
export (float, 0, 2000, 40.0) var linear_speed_max := 600.0 setget set_linear_speed_max
export (float, 0, 9000, 2.0) var linear_accel_max := 40.0 setget set_linear_accel_max
export (float, 0, 300, 2.0) var proximity_radius := 140.0 setget set_proximity_radius
export (float, 0, 200000, 250) var separation_decay_coefficient := 2000.0 setget set_separation_decay_coef
export (float, 0, 2, 0.1) var cohesion_strength := 0.1 setget set_cohesion_strength
export (float, 0, 10, 0.2) var separation_strength := 1.5 setget set_separation_strength
export var show_proximity_radius := true setget set_show_proximity_radius
func _ready() -> void:
spawner.setup(
linear_speed_max,
linear_accel_max,
proximity_radius,
separation_decay_coefficient,
cohesion_strength,
separation_strength,
show_proximity_radius
)
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
spawner.set_linear_speed_max(value)
func set_linear_accel_max(value: float) -> void:
linear_accel_max = value
if not is_inside_tree():
return
spawner.set_linear_accel_max(value)
func set_proximity_radius(value: float) -> void:
proximity_radius = value
if not is_inside_tree():
return
spawner.set_proximity_radius(value)
func set_show_proximity_radius(value: bool) -> void:
show_proximity_radius = value
if not is_inside_tree():
return
spawner.set_show_proximity_radius(value)
func set_separation_decay_coef(value: float) -> void:
separation_decay_coefficient = value
if not is_inside_tree():
return
spawner.set_separation_decay_coef(value)
func set_cohesion_strength(value: float) -> void:
cohesion_strength = value
if not is_inside_tree():
return
spawner.set_cohesion_strength(value)
func set_separation_strength(value: float) -> void:
separation_strength = value
if not is_inside_tree():
return
spawner.set_separation_strength(value)

View File

@ -0,0 +1,28 @@
[gd_scene load_steps=6 format=3]
[ext_resource path="res://Demos/GroupBehaviors/Member.tscn" type="PackedScene" id=1]
[ext_resource path="res://Demos/GroupBehaviors/Spawner.gd" type="Script" id=2]
[ext_resource path="res://Demos/GroupBehaviors/GroupBehaviorsDemo.gd" type="Script" id=3]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=4]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[node name="GroupBehaviorsDemo" type="Node"]
script = ExtResource( 3 )
linear_accel_max = 4234.0
proximity_radius = 158.0
separation_decay_coefficient = 121500.0
cohesion_strength = 0.2
separation_strength = 8.8
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Spawner" type="Node2D" parent="."]
position = Vector2( 973.261, 528.829 )
script = ExtResource( 2 )
member = ExtResource( 1 )
[node name="DemoInterface" parent="." instance=ExtResource( 4 )]
mouse_filter = 2
text_bbcode = "Group Behavior Demo
Each of the \"Agents\" are both attempting to stay separated from each other but within reach of their nearest group's center of mass.
Click on agent to see it's proximity."

View File

@ -0,0 +1,69 @@
extends KinematicBody2D
var separation: GSAISeparation
var cohesion: GSAICohesion
var proximity: GSAIRadiusProximity
var agent :GSAIKinematicBody2DAgent = null
var blend : GSAIBlend = null
var acceleration : GSAITargetAcceleration = null
var draw_proximity := false
var _color := Color.red
var _velocity := Vector2()
onready var collision_shape := $CollisionShape2D
func _init() -> void:
agent = GSAIKinematicBody2DAgent.new()
agent.body = self
blend = GSAIBlend.new()
blend.agent = agent
acceleration = GSAITargetAcceleration.new()
func setup(
linear_speed_max: float,
linear_accel_max: float,
proximity_radius: float,
separation_decay_coefficient: float,
cohesion_strength: float,
separation_strength: float
) -> void:
_color = Color(rand_range(0.5, 1), rand_range(0.25, 1), rand_range(0, 1))
collision_shape.inner_color = _color
agent.linear_acceleration_max = linear_accel_max
agent.linear_speed_max = linear_speed_max
agent.linear_drag_percentage = 0.1
proximity = GSAIRadiusProximity.new()
proximity.agent = agent
proximity.radius = proximity_radius
separation = GSAISeparation.new()
separation.agent = agent
separation.proximity = proximity
separation.decay_coefficient = separation_decay_coefficient
cohesion = GSAICohesion.new()
cohesion.agent = agent
cohesion.proximity = proximity
blend.add_behavior(separation, separation_strength)
blend.add_behavior(cohesion, cohesion_strength)
func _draw() -> void:
if draw_proximity:
draw_circle(Vector2.ZERO, proximity.radius, Color(0.4, 1.0, 0.89, 0.3))
func _physics_process(delta: float) -> void:
if blend:
blend.calculate_steering(acceleration)
agent.apply_steering(acceleration, delta)
func set_neighbors(neighbor: Array) -> void:
proximity.agents = neighbor

View File

@ -0,0 +1,17 @@
[gd_scene load_steps=4 format=3]
[ext_resource path="res://Demos/GroupBehaviors/Member.gd" type="Script" id=1]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=3]
[sub_resource type="CircleShape2D" id=1]
radius = 16.0
[node name="Member" type="KinematicBody2D"]
input_pickable = true
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )
script = ExtResource( 3 )
outer_color = Color( 0.301961, 0.65098, 1, 1 )
stroke = 4.0

View File

@ -0,0 +1,92 @@
extends Node2D
export var member: PackedScene
func follower_input_event(
viewport: Node,
event: InputEvent,
shape_idx: int,
follower: KinematicBody2D
) -> void:
if event.is_action_pressed("click"):
for other in get_children():
if other.draw_proximity:
other.draw_proximity = false
other.update()
follower.draw_proximity = true
follower.update()
move_child(follower, get_child_count())
func setup(
linear_speed_max: float,
linear_accel_max: float,
proximity_radius: float,
separation_decay_coefficient: float,
cohesion_strength: float,
separation_strength: float,
show_proximity_radius: bool
) -> void:
var followers := []
for i in range(19):
var follower : KinematicBody2D = member.instance()
add_child(follower)
follower.position += Vector2(rand_range(-60, 60), rand_range(-60, 60))
followers.append(follower)
follower.setup(
linear_speed_max,
linear_accel_max,
proximity_radius,
separation_decay_coefficient,
cohesion_strength,
separation_strength
)
if i == 0 and show_proximity_radius:
follower.draw_proximity = true
follower.update()
follower.connect("input_event", self, "follower_input_event", [follower])
var agents := []
for i in followers:
agents.append(i.agent)
for i in followers:
i.proximity.agents = agents
func set_linear_speed_max(value: float) -> void:
for child in get_children():
child.agent.linear_speed_max = value
func set_linear_accel_max(value: float) -> void:
for child in get_children():
child.agent.linear_acceleration_max = value
func set_proximity_radius(value: float) -> void:
for child in get_children():
child.proximity.radius = value
if child == get_child(0):
child.update()
func set_show_proximity_radius(value: bool) -> void:
get_child(0).draw_proximity = value
get_child(0).update()
func set_separation_decay_coef(value: float) -> void:
for child in get_children():
child.separation.decay_coefficient = value
func set_cohesion_strength(value: float) -> void:
for child in get_children():
child.blend.get_behavior(1).weight = value
func set_separation_strength(value: float) -> void:
for child in get_children():
child.blend.get_behavior(0).weight = value

View File

@ -0,0 +1,68 @@
extends ItemList
signal demo_selected(scene_path)
var file_paths := PoolStringArray()
func _ready() -> void:
# warning-ignore:return_value_discarded
self.connect("item_selected", self, "_on_item_selected")
var this_directory: String = get_tree().current_scene.filename.rsplit("/", false, 1)[0]
file_paths = _find_files(this_directory, ["*Demo.tscn"], true)
populate(file_paths)
select(0)
func populate(demos: PoolStringArray) -> void:
for path in demos:
var demo_name: String = path.rsplit("/", true, 1)[-1]
demo_name = demo_name.rsplit("Demo", true, 1)[0]
demo_name = sentencify(demo_name)
add_item(demo_name)
func sentencify(line: String) -> String:
var regex := RegEx.new()
# warning-ignore:return_value_discarded
regex.compile("[A-Z]")
line = line.split(".", true, 1)[0]
line = regex.sub(line, " $0", true)
return line
func _find_files(
dirpath := "", patterns := PoolStringArray(), is_recursive := false, do_skip_hidden := true
) -> PoolStringArray:
var paths := PoolStringArray()
var directory := Directory.new()
if not directory.dir_exists(dirpath):
printerr("The directory does not exist: %s" % dirpath)
return paths
if not directory.open(dirpath) == OK:
printerr("Could not open the following dirpath: %s" % dirpath)
return paths
# warning-ignore:return_value_discarded
directory.list_dir_begin(true, do_skip_hidden)
var file_name := directory.get_next()
while file_name != "":
if directory.current_is_dir() and is_recursive:
var subdirectory := dirpath.plus_file(file_name)
paths.append_array(_find_files(subdirectory, patterns, is_recursive))
else:
for pattern in patterns:
if file_name.match(pattern):
paths.append(dirpath.plus_file(file_name))
file_name = directory.get_next()
directory.list_dir_end()
return paths
func _on_item_selected(index: int) -> void:
var demo_path := file_paths[index]
emit_signal("demo_selected", demo_path)

View File

@ -0,0 +1,15 @@
extends Node2D
# Wraps the ships' positions around the world border.
var _world_bounds: Vector2
func _ready() -> void:
_world_bounds = Vector2(
ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"]
)
func _physics_process(_delta: float) -> void:
for ship in get_children():
ship.position = ship.position.posmodv(_world_bounds)

View File

@ -0,0 +1,96 @@
extends KinematicBody2D
# Controls the player ship's movements based on player input.
export var thruster_strength := 175.0
export var side_thruster_strength := 10.0
export var velocity_max := 300.0
export var angular_velocity_max := 2.0
export var angular_drag := 0.025
export var linear_drag := 0.025
var _linear_velocity := Vector2()
var _angular_velocity := 0.0
onready var agent := GSAISteeringAgent.new()
func _physics_process(delta: float) -> void:
var movement := _get_movement()
_angular_velocity = _calculate_angular_velocity(
movement.x,
_angular_velocity,
side_thruster_strength,
angular_velocity_max,
angular_drag,
delta
)
rotation += _angular_velocity * delta
_linear_velocity = _calculate_linear_velocity(
movement.y,
_linear_velocity,
Vector2.UP.rotated(rotation),
linear_drag,
thruster_strength,
velocity_max,
delta
)
_linear_velocity = move_and_slide(_linear_velocity)
_update_agent()
func _calculate_angular_velocity(
horizontal_movement: float,
current_velocity: float,
_thruster_strength: float,
_velocity_max: float,
ship_drag: float,
delta: float
) -> float:
var velocity := clamp(
current_velocity + _thruster_strength * horizontal_movement * delta,
-_velocity_max,
_velocity_max
)
velocity = lerp(velocity, 0, ship_drag)
return velocity
func _calculate_linear_velocity(
vertical_movement: float,
current_velocity: Vector2,
facing_direction: Vector2,
ship_drag_coefficient: float,
strength: float,
speed_max: float,
delta: float
) -> Vector2:
var actual_strength := 0.0
if vertical_movement > 0:
actual_strength = strength
elif vertical_movement < 0:
actual_strength = -strength / 1.5
var velocity := current_velocity + facing_direction * actual_strength * delta
velocity = velocity.linear_interpolate(Vector2.ZERO, ship_drag_coefficient)
return velocity.limit_length(speed_max)
func _get_movement() -> Vector2:
return Vector2(
Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"),
Input.get_action_strength("sf_up") - Input.get_action_strength("sf_down")
)
func _update_agent() -> void:
agent.position.x = global_position.x
agent.position.y = global_position.y
agent.linear_velocity.x = _linear_velocity.x
agent.linear_velocity.y = _linear_velocity.y
agent.angular_velocity = _angular_velocity
agent.orientation = rotation

View File

@ -0,0 +1,39 @@
extends Node
export (float, 0, 2000, 40) var linear_speed_max := 120.0 setget set_linear_speed_max
export (float, 0, 2000, 20) var linear_accel_max := 10.0 setget set_linear_accel_max
export (float, 0, 5, 0.1) var predict_time := 1.0 setget set_predict_time
onready var pursuer := $BoundaryManager/Pursuer
onready var seeker := $BoundaryManager/Seeker
func _ready() -> void:
pursuer.setup(predict_time, linear_speed_max, linear_accel_max)
seeker.setup(predict_time, linear_speed_max, linear_accel_max)
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
pursuer.agent.linear_speed_max = value
seeker.agent.linear_speed_max = value
func set_linear_accel_max(value: float) -> void:
linear_accel_max = value
if not is_inside_tree():
return
pursuer.agent.linear_acceleration_max = value
seeker.agent.linear_acceleration_max = value
func set_predict_time(value: float) -> void:
predict_time = value
if not is_inside_tree():
return
pursuer._behavior.predict_time_max = value

View File

@ -0,0 +1,92 @@
[gd_scene load_steps=8 format=3]
[ext_resource path="res://Demos/PursueSeek/Pursuer.gd" type="Script" id=1]
[ext_resource path="res://Demos/PursueSeek/Player.gd" type="Script" id=2]
[ext_resource path="res://Demos/PursueSeek/BoundaryManager.gd" type="Script" id=3]
[ext_resource path="res://Demos/PursueSeek/PursueAndSeekDemo.gd" type="Script" id=4]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=5]
[ext_resource path="res://Demos/Utils/Line2DDraw.gd" type="Script" id=6]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=7]
[node name="PursueVSSeekDemo" type="Node"]
script = ExtResource( 4 )
linear_speed_max = 1280.0
linear_accel_max = 1040.0
predict_time = 1.1
[node name="BackgroudLayer" parent="." instance=ExtResource( 7 )]
[node name="BoundaryManager" type="Node2D" parent="."]
script = ExtResource( 3 )
[node name="Player" type="KinematicBody2D" parent="BoundaryManager"]
position = Vector2( 307.552, 555.999 )
rotation = 1.5708
collision_mask = 2
script = ExtResource( 2 )
__meta__ = {
"_edit_group_": true
}
thruster_strength = 1000.0
side_thruster_strength = 40.0
velocity_max = 450.0
angular_velocity_max = 3.0
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Player"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="BoundaryManager/Player"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 0.560784, 0.870588, 0.364706, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 6 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
[node name="Pursuer" type="KinematicBody2D" parent="BoundaryManager"]
position = Vector2( 1240.22, 866.784 )
collision_layer = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_group_": true
}
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Pursuer"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="BoundaryManager/Pursuer"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 1, 0.709804, 0.439216, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 6 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
[node name="Seeker" type="KinematicBody2D" parent="BoundaryManager"]
position = Vector2( 1240.22, 280.108 )
rotation = 3.14159
collision_layer = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_group_": true
}
use_seek = true
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Seeker"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="BoundaryManager/Seeker"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 0.301961, 0.65098, 1, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 6 )
inner_color = Color( 0.294118, 0.356863, 0.670588, 1 )
[node name="DemoInterface" parent="." instance=ExtResource( 5 )]
text_bbcode = "Pursue vs. Seek Demo
Move the player around with WASD and notice the [color=#ffb570]orange Pursuer[/color] and the [color=aqua]blue Seeker[/color] follow
the [color=lime]green \"Ship\"[/color] around"

View File

@ -0,0 +1,80 @@
extends KinematicBody2D
# Represents a ship that chases after the player.
export var use_seek: bool = false
var _blend: GSAIBlend
var _linear_drag_coefficient := 0.025
var _angular_drag := 0.1
var _direction_face := GSAIAgentLocation.new()
var agent : GSAIKinematicBody2DAgent= null
var accel : GSAITargetAcceleration = null
var player_agent : GSAISteeringAgent = null
func _ready() -> void:
agent = GSAIKinematicBody2DAgent.new()
agent.body = self
accel = GSAITargetAcceleration.new()
player_agent = owner.find_node("Player", true, false).agent
agent.calculate_velocities = false
set_physics_process(false)
func _physics_process(delta: float) -> void:
_direction_face.position = agent.position + accel.linear.normalized()
_blend.calculate_steering(accel)
agent.angular_velocity = clamp(
agent.angular_velocity + accel.angular * delta, -agent.angular_speed_max, agent.angular_speed_max
)
agent.angular_velocity = lerp(agent.angular_velocity, 0, _angular_drag)
rotation += agent.angular_velocity * delta
var linear_velocity := (
GSAIUtils.to_vector2(agent.linear_velocity)
+ (GSAIUtils.angle_to_vector2(rotation) * -agent.linear_acceleration_max * delta)
)
linear_velocity = linear_velocity.limit_length(agent.linear_speed_max)
linear_velocity = linear_velocity.linear_interpolate(Vector2.ZERO, _linear_drag_coefficient)
linear_velocity = move_and_slide(linear_velocity)
agent.linear_velocity = GSAIUtils.to_vector3(linear_velocity)
func setup(predict_time: float, linear_speed_max: float, linear_accel_max: float) -> void:
var behavior: GSAISteeringBehavior
if use_seek:
behavior = GSAISeek.new()
behavior.agent = agent
behavior.target = player_agent
else:
behavior = GSAIPursue.new()
behavior.agent = agent
behavior.target = player_agent
behavior.predict_time_max = predict_time
var orient_behavior : GSAIFace = GSAIFace.new()
orient_behavior.agent = agent
orient_behavior.target = _direction_face
orient_behavior.alignment_tolerance = deg2rad(5)
orient_behavior.deceleration_radius = deg2rad(30)
_blend = GSAIBlend.new()
_blend.agent = agent
_blend.add_behavior(behavior, 1)
_blend.add_behavior(orient_behavior, 1)
agent.angular_acceleration_max = deg2rad(1080)
agent.angular_speed_max = deg2rad(360)
agent.linear_acceleration_max = linear_accel_max
agent.linear_speed_max = linear_speed_max
set_physics_process(true)

View File

@ -0,0 +1,195 @@
extends KinematicBody2D
# Maximum possible linear velocity
export var speed_max := 450.0
# Maximum change in linear velocity
export var acceleration_max := 50.0
# Maximum rotation velocity represented in degrees
export var angular_speed_max := 240
# Maximum change in rotation velocity represented in degrees
export var angular_acceleration_max := 40
export var health_max := 100
export var flee_health_threshold := 20
var velocity := Vector2.ZERO
var angular_velocity := 0.0
var linear_drag := 0.1
var angular_drag := 0.1
# Holds the linear and angular components calculated by our steering behaviors.
var acceleration : GSAITargetAcceleration = null
onready var current_health := health_max
# GSAISteeringAgent holds our agent's position, orientation, maximum speed and acceleration.
var agent : GSAISteeringAgent = null
var player: Node = null
# This assumes that our player class will keep its own agent updated.
var player_agent : GSAISteeringAgent = null
# Proximities represent an area with which an agent can identify where neighbors in its relevant
# group are. In our case, the group will feature the player, which will be used to avoid a
# collision with them. We use a radius proximity so the player is only relevant inside 100 pixels.
var proximity : GSAIRadiusProximity = null
# GSAIBlend combines behaviors together, calculating all of their acceleration together and adding
# them together, multiplied by a strength. We will have one for fleeing, and one for pursuing,
# toggling them depending on the agent's health. Since we want the agent to rotate AND move, then
# we aim to blend them together.
var flee_blend : GSAIBlend = null
var pursue_blend : GSAIBlend = null
# GSAIPriority will be the main steering behavior we use. It holds sub-behaviors and will pick the
# first one that returns non-zero acceleration, ignoring any afterwards.
var priority : GSAIPriority = null
func _ready() -> void:
acceleration = GSAITargetAcceleration.new()
agent = GSAISteeringAgent.new()
player = get_tree().get_nodes_in_group("Player")[0]
player_agent = player.agent
proximity = GSAIRadiusProximity.new()
proximity.agent = agent
proximity.agents = [ player_agent ]
proximity.radius = 100
flee_blend = GSAIBlend.new()
flee_blend.agent = agent
pursue_blend = GSAIBlend.new()
pursue_blend.agent = agent
priority = GSAIPriority.new()
priority.agent = agent
# ---------- Configuration for our agent ----------
agent.linear_speed_max = speed_max
agent.linear_acceleration_max = acceleration_max
agent.angular_speed_max = deg2rad(angular_speed_max)
agent.angular_acceleration_max = deg2rad(angular_acceleration_max)
agent.bounding_radius = calculate_radius($CollisionPolygon2D.polygon)
update_agent()
# ---------- Configuration for our behaviors ----------
# Pursue will happen while the agent is in good health. It produces acceleration that takes
# the agent on an intercept course with the target, predicting its position in the future.
var pursue : GSAIPursue = GSAIPursue.new()
pursue.agent = agent
pursue.target = player_agent
pursue.predict_time_max = 1.5
# Flee will happen while the agent is in bad health, so will start disabled. It produces
# acceleration that takes the agent directly away from the target with no prediction.
var flee : GSAIFlee = GSAIFlee.new()
flee.agent = agent
flee.target = player_agent
# AvoidCollision tries to keep the agent from running into any of the neighbors found in its
# proximity group. In our case, this will be the player, if they are close enough.
var avoid : GSAIAvoidCollisions = GSAIAvoidCollisions.new()
avoid.agent = agent
avoid.proximity = proximity
# Face turns the agent to keep looking towards its target. It will be enabled while the agent
# is not fleeing due to low health. It tries to arrive 'on alignment' with 0 remaining velocity.
var face : GSAIFace = GSAIFace.new()
face.agent = agent
face.target = player_agent
# We use deg2rad because the math in the toolkit assumes radians.
# How close for the agent to be 'aligned', if not exact.
face.alignment_tolerance = deg2rad(5)
# When to start slowing down
face.deceleration_radius = deg2rad(60)
# LookWhereYouGo turns the agent to keep looking towards its direction of travel. It will only
# be enabled while the agent is at low health.
var look : GSAILookWhereYouGo = GSAILookWhereYouGo.new()
look.agent = agent
# How close for the agent to be 'aligned', if not exact
look.alignment_tolerance = deg2rad(5)
# When to start slowing down.
look.deceleration_radius = deg2rad(60)
# Behaviors that are not enabled produce 0 acceleration.
# Adding our fleeing behaviors to a blend. The order does not matter.
flee_blend.is_enabled = false
flee_blend.add_behavior(look, 1)
flee_blend.add_behavior(flee, 1)
# Adding our pursuit behaviors to a blend. The order does not matter.
pursue_blend.add_behavior(face, 1)
pursue_blend.add_behavior(pursue, 1)
# Adding our final behaviors to the main priority behavior. The order does matter here.
# We want to avoid collision with the player first, flee from the player second when enabled,
# and pursue the player last when enabled.
priority.add_behavior(avoid)
priority.add_behavior(flee_blend)
priority.add_behavior(pursue_blend)
func _physics_process(delta: float) -> void:
# Make sure any change in position and speed has been recorded.
update_agent()
if current_health <= flee_health_threshold:
pursue_blend.is_enabled = false
flee_blend.is_enabled = true
# Calculate the desired acceleration.
priority.calculate_steering(acceleration)
# We add the discovered acceleration to our linear velocity. The toolkit does not limit
# velocity, just acceleration, so we clamp the result ourselves here.
velocity = (velocity + Vector2(acceleration.linear.x, acceleration.linear.y) * delta).limit_length(
agent.linear_speed_max
)
# This applies drag on the agent's motion, helping it to slow down naturally.
velocity = velocity.linear_interpolate(Vector2.ZERO, linear_drag)
# And since we're using a KinematicBody2D, we use Godot's excellent move_and_slide to actually
# apply the final movement, and record any change in velocity the physics engine discovered.
velocity = move_and_slide(velocity)
# We then do something similar to apply our agent's rotational speed.
angular_velocity = clamp(
angular_velocity + acceleration.angular * delta, -agent.angular_speed_max, agent.angular_speed_max
)
# This applies drag on the agent's rotation, helping it slow down naturally.
angular_velocity = lerp(angular_velocity, 0, angular_drag)
rotation += angular_velocity * delta
# In order to support both 2D and 3D, the toolkit uses Vector3, so the conversion is required
# when using 2D nodes. The Z component can be left to 0 safely.
func update_agent() -> void:
agent.position.x = global_position.x
agent.position.y = global_position.y
agent.orientation = rotation
agent.linear_velocity.x = velocity.x
agent.linear_velocity.y = velocity.y
agent.angular_velocity = angular_velocity
# We calculate the radius from the collision shape - this will approximate the agent's size in the
# game world, to avoid collisions with the player.
func calculate_radius(polygon: PoolVector2Array) -> float:
var furthest_point := Vector2(-INF, -INF)
for p in polygon:
if abs(p.x) > furthest_point.x:
furthest_point.x = p.x
if abs(p.y) > furthest_point.y:
furthest_point.y = p.y
return furthest_point.length()
func damage(amount: int) -> void:
current_health -= amount
if current_health <= 0:
queue_free()

View File

@ -0,0 +1,33 @@
extends KinematicBody2D
export var speed := 1500.0
var velocity := Vector2.ZERO
var player: Node
onready var timer := $Lifetime
func _ready() -> void:
timer.connect("timeout", self, "_on_Lifetime_timeout")
timer.start()
func _physics_process(delta: float) -> void:
var collision := move_and_collide(velocity * delta)
if collision:
timer.stop()
clear()
collision.collider.damage(10)
func start(direction: Vector2) -> void:
velocity = direction * speed
func clear() -> void:
queue_free()
func _on_Lifetime_timeout() -> void:
clear()

View File

@ -0,0 +1,23 @@
[gd_scene load_steps=4 format=3]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=1]
[ext_resource path="res://Demos/Quickstart/Bullet.gd" type="Script" id=2]
[sub_resource type="CircleShape2D" id=1]
radius = 4.0
[node name="Bullet" type="KinematicBody2D"]
collision_layer = 4
collision_mask = 2
script = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )
script = ExtResource( 1 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 2.0
[node name="Lifetime" type="Timer" parent="."]
process_mode = 0
wait_time = 3.0

View File

@ -0,0 +1,99 @@
extends KinematicBody2D
export var speed_max := 650.0
export var acceleration_max := 70.0
export var rotation_speed_max := 240
export var rotation_accel_max := 40
export var bullet: PackedScene
var velocity := Vector2.ZERO
var angular_velocity := 0.0
var direction := Vector2.RIGHT
var agent : GSAISteeringAgent = null
var proxy_target : GSAIAgentLocation = null
var face : GSAIFace = null
onready var accel := GSAITargetAcceleration.new()
onready var bullets := owner.get_node("Bullets")
func _ready() -> void:
agent = GSAISteeringAgent.new()
proxy_target = GSAIAgentLocation.new()
face = GSAIFace.new()
face.agent = agent
face.target = proxy_target
agent.linear_speed_max = speed_max
agent.linear_acceleration_max = acceleration_max
agent.angular_speed_max = deg2rad(rotation_speed_max)
agent.angular_acceleration_max = deg2rad(rotation_accel_max)
agent.bounding_radius = calculate_radius($CollisionPolygon2D.polygon)
update_agent()
var mouse_pos := get_global_mouse_position()
proxy_target.position.x = mouse_pos.x
proxy_target.position.y = mouse_pos.y
face.alignment_tolerance = deg2rad(5)
face.deceleration_radius = deg2rad(45)
func _physics_process(delta: float) -> void:
update_agent()
var movement := get_movement()
direction = GSAIUtils.angle_to_vector2(rotation)
velocity += direction * acceleration_max * movement * delta
velocity = velocity.limit_length(speed_max)
velocity = velocity.linear_interpolate(Vector2.ZERO, 0.1)
velocity = move_and_slide(velocity)
face.calculate_steering(accel)
angular_velocity += accel.angular * delta
angular_velocity = clamp(angular_velocity, -agent.angular_speed_max, agent.angular_speed_max)
angular_velocity = lerp(angular_velocity, 0, 0.1)
rotation += angular_velocity * delta
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
var mouse_pos: Vector2 = event.position
proxy_target.position.x = mouse_pos.x
proxy_target.position.y = mouse_pos.y
elif event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.pressed:
var next_bullet := bullet.instance()
next_bullet.global_position = (
global_position
- direction * (agent.bounding_radius - 5)
)
next_bullet.player = self
next_bullet.start(-direction)
bullets.add_child(next_bullet)
func get_movement() -> float:
return Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")
func update_agent() -> void:
agent.position.x = global_position.x
agent.position.y = global_position.y
agent.orientation = rotation
agent.linear_velocity.x = velocity.x
agent.linear_velocity.y = velocity.y
agent.angular_velocity = angular_velocity
func calculate_radius(polygon: PoolVector2Array) -> float:
var furthest_point := Vector2(-INF, -INF)
for p in polygon:
if abs(p.x) > furthest_point.x:
furthest_point.x = p.x
if abs(p.y) > furthest_point.y:
furthest_point.y = p.y
return furthest_point.length()

View File

@ -0,0 +1,59 @@
[gd_scene load_steps=6 format=3]
[ext_resource path="res://Demos/Utils/Line2DDraw.gd" type="Script" id=1]
[ext_resource path="res://Demos/Quickstart/Agent.gd" type="Script" id=2]
[ext_resource path="res://Demos/Quickstart/Player.gd" type="Script" id=3]
[ext_resource path="res://Demos/Quickstart/Bullet.tscn" type="PackedScene" id=4]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[node name="QuickStartDemo" type="Node"]
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Player" type="KinematicBody2D" parent="." groups=["Player"]]
position = Vector2( 402.346, 573.791 )
rotation = 1.5708
collision_mask = 2
script = ExtResource( 3 )
speed_max = 900.0
acceleration_max = 4200.0
rotation_speed_max = 360
rotation_accel_max = 1280
bullet = ExtResource( 4 )
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Player"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="Player"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 0.560784, 0.870588, 0.364706, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 1 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
[node name="Agent" type="KinematicBody2D" parent="."]
position = Vector2( 974.675, 266.224 )
rotation = 1.5708
collision_layer = 2
collision_mask = 5
script = ExtResource( 2 )
speed_max = 600.0
acceleration_max = 2800.0
angular_speed_max = 360
angular_acceleration_max = 1280
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Agent"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="Agent"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 1, 0.709804, 0.439216, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 1 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
[node name="Bullets" type="Node2D" parent="."]

View File

@ -0,0 +1,32 @@
extends Node2D
const COLOR := Color("8fde5d")
func _ready() -> void:
get_tree().root.connect("size_changed", self, "_on_SceneTree_size_changed")
_on_SceneTree_size_changed()
func _draw() -> void:
for b in get_children():
var extents: Vector2 = b.get_node("CollisionShape2D").shape.extents
draw_rect(Rect2(b.global_position - extents, extents * 2), COLOR)
func _on_SceneTree_size_changed() -> void:
var size := Vector2(
ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"]
)
for b in get_children():
var boundary: String = str(b.name).rsplit("Boundary")[0]
match boundary:
"Left":
b.global_position = Vector2(0, size.y / 2)
"Right":
b.global_position = Vector2(size.x, size.y / 2)
"Top":
b.global_position = Vector2(size.x / 2, 0)
"Bottom":
b.global_position = Vector2(size.x / 2, size.y)
update()

View File

@ -0,0 +1,26 @@
extends KinematicBody2D
# Class to control the player in basic left/right up/down movement.
var speed: float
onready var agent := GSAIAgentLocation.new()
func _ready() -> void:
agent.position = GSAIUtils.to_vector3(global_position)
func _physics_process(_delta: float) -> void:
var movement := _get_movement()
if movement.length_squared() < 0.01:
return
# warning-ignore:return_value_discarded
move_and_slide(movement * speed)
agent.position = GSAIUtils.to_vector3(global_position)
func _get_movement() -> Vector2:
return Vector2(
Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"),
Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")
)

View File

@ -0,0 +1,82 @@
extends Node
# Access helper class for children to access window boundaries.
enum Mode { FLEE, SEEK }
export (Mode) var behavior_mode := Mode.SEEK setget set_behavior_mode
export (float, 0, 1000, 30) var linear_speed_max := 200.0 setget set_linear_speed_max
export (float, 0, 2000, 40) var linear_accel_max := 10.0 setget set_linear_accel_max
export (float) var player_speed := 600.0 setget set_player_speed
var camera_boundaries: Rect2
onready var player: KinematicBody2D = $Player
onready var spawner: Node2D = $Spawner
func _ready() -> void:
camera_boundaries = Rect2(
Vector2.ZERO,
Vector2(
ProjectSettings["display/window/size/width"],
ProjectSettings["display/window/size/height"]
)
)
var rng := RandomNumberGenerator.new()
rng.randomize()
player.speed = player_speed
for i in range(spawner.entity_count):
var new_pos := Vector2(
rng.randf_range(0, camera_boundaries.size.x),
rng.randf_range(0, camera_boundaries.size.y)
)
var entity: KinematicBody2D = spawner.entity.instance()
entity.global_position = new_pos
entity.player_agent = player.agent
entity.start_speed = linear_speed_max
entity.start_accel = linear_accel_max
entity.use_seek = behavior_mode == Mode.SEEK
spawner.add_child(entity)
func set_behavior_mode(mode: int) -> void:
behavior_mode = mode
if not is_inside_tree():
return
match mode:
Mode.SEEK:
for child in spawner.get_children():
child.use_seek = true
Mode.FLEE:
for child in spawner.get_children():
child.use_seek = false
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
for child in spawner.get_children():
child.agent.linear_speed_max = value
func set_linear_accel_max(value: float) -> void:
linear_accel_max = value
if not is_inside_tree():
return
for child in spawner.get_children():
child.agent.linear_acceleration_max = value
func set_player_speed(value: float) -> void:
player_speed = value
if not is_inside_tree():
return
player.speed = player_speed

View File

@ -0,0 +1,81 @@
[gd_scene load_steps=12 format=3]
[ext_resource path="res://Demos/SeekFlee/Player.gd" type="Script" id=2]
[ext_resource path="res://Demos/SeekFlee/SeekFleeDemo.gd" type="Script" id=3]
[ext_resource path="res://Demos/SeekFlee/Spawner.gd" type="Script" id=4]
[ext_resource path="res://Demos/Utils/DemoInterface.tscn" type="PackedScene" id=5]
[ext_resource path="res://Demos/SeekFlee/Seeker.tscn" type="PackedScene" id=6]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=7]
[ext_resource path="res://Demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=8]
[ext_resource path="res://Demos/SeekFlee/Boundaries.gd" type="Script" id=9]
[sub_resource type="CircleShape2D" id=1]
radius = 32.0
[sub_resource type="RectangleShape2D" id=2]
extents = Vector2( 10, 542 )
[sub_resource type="RectangleShape2D" id=3]
extents = Vector2( 965.654, 10 )
[node name="SeekFleeDemo" type="Node"]
script = ExtResource( 3 )
linear_speed_max = 570.0
linear_accel_max = 1160.0
[node name="BackgroudLayer" parent="." instance=ExtResource( 8 )]
[node name="Player" type="KinematicBody2D" parent="."]
position = Vector2( 960, 540 )
collision_mask = 2
script = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"]
shape = SubResource( 1 )
script = ExtResource( 7 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 4.0
[node name="Boundaries" type="Node2D" parent="."]
script = ExtResource( 9 )
[node name="LeftBoundary" type="StaticBody2D" parent="Boundaries"]
position = Vector2( 0, 540 )
collision_layer = 2
collision_mask = 5
[node name="CollisionShape2D" type="CollisionShape2D" parent="Boundaries/LeftBoundary"]
shape = SubResource( 2 )
[node name="RightBoundary" type="StaticBody2D" parent="Boundaries"]
position = Vector2( 1920, 540 )
collision_layer = 2
collision_mask = 5
[node name="CollisionShape2D" type="CollisionShape2D" parent="Boundaries/RightBoundary"]
shape = SubResource( 2 )
[node name="TopBoundary" type="StaticBody2D" parent="Boundaries"]
position = Vector2( 960, 0 )
collision_layer = 2
collision_mask = 5
[node name="CollisionShape2D" type="CollisionShape2D" parent="Boundaries/TopBoundary"]
shape = SubResource( 3 )
[node name="BottomBoundary" type="StaticBody2D" parent="Boundaries"]
position = Vector2( 960, 1080 )
collision_layer = 2
collision_mask = 5
[node name="CollisionShape2D" type="CollisionShape2D" parent="Boundaries/BottomBoundary"]
shape = SubResource( 3 )
[node name="Spawner" type="Node2D" parent="."]
script = ExtResource( 4 )
entity = ExtResource( 6 )
[node name="DemoInterface" parent="." instance=ExtResource( 5 )]
text_bbcode = "Seek & Flee Demo
Move the [color=lime]green \"Player\"[/color] around with WASD and notice the [color=#ffb570]orange \"Enemies\"[/color] try to seek to or flee from the player."

View File

@ -0,0 +1,42 @@
extends KinematicBody2D
var player_agent: GSAIAgentLocation
var velocity := Vector2.ZERO
var start_speed: float
var start_accel: float
var use_seek := true
var agent : GSAIKinematicBody2DAgent = null
var accel : GSAITargetAcceleration = null
var seek : GSAISeek = null
var flee : GSAIFlee = null
func _ready() -> void:
agent = GSAIKinematicBody2DAgent.new()
agent.body = self
accel = GSAITargetAcceleration.new()
seek = GSAISeek.new()
seek.agent = agent
seek.target = player_agent
flee = GSAIFlee.new()
flee.agent = agent
flee.target = player_agent
agent.linear_acceleration_max = start_accel
agent.linear_speed_max = start_speed
func _physics_process(delta: float) -> void:
if not player_agent:
return
if use_seek:
seek.calculate_steering(accel)
else:
flee.calculate_steering(accel)
agent.apply_steering(accel, delta)

View File

@ -0,0 +1,19 @@
[gd_scene load_steps=4 format=3]
[ext_resource path="res://Demos/SeekFlee/Seeker.gd" type="Script" id=1]
[ext_resource path="res://Demos/Utils/CircleDraw.gd" type="Script" id=2]
[sub_resource type="CircleShape2D" id=1]
radius = 16.0
[node name="Seeker" type="KinematicBody2D"]
collision_layer = 4
collision_mask = 2
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )
script = ExtResource( 2 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
outer_color = Color( 1, 0.709804, 0.439216, 1 )
stroke = 4.0

View File

@ -0,0 +1,6 @@
extends Node2D
# Holds data to instantiate and configure a number of agent entities.
export (PackedScene) var entity: PackedScene
export var entity_count := 10
export var entity_color := Color.blue

View File

@ -0,0 +1,17 @@
[gd_scene load_steps=2 format=3]
[ext_resource path="res://assets/sprites/background.png" type="Texture" id=1]
[node name="BackgroudLayer" type="CanvasLayer"]
layer = -1
[node name="Background" type="TextureRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
mouse_filter = 2
texture = ExtResource( 1 )
expand = true
stretch_mode = 7
__meta__ = {
"_edit_use_anchors_": false
}

View File

@ -0,0 +1,26 @@
tool
extends CollisionShape2D
export (Color) var inner_color := Color() setget set_inner_color
export (Color) var outer_color := Color() setget set_outer_color
export (float) var stroke := 0.0 setget set_stroke
func _draw() -> void:
draw_circle(Vector2.ZERO, shape.radius + stroke, outer_color)
draw_circle(Vector2.ZERO, shape.radius, inner_color)
func set_inner_color(val: Color) -> void:
inner_color = val
update()
func set_outer_color(val: Color) -> void:
outer_color = val
update()
func set_stroke(val: float) -> void:
stroke = val
update()

View File

@ -0,0 +1,13 @@
tool
extends PanelContainer
export (String, MULTILINE) var text_bbcode := "" setget set_text_bbcode
onready var rich_text_label: RichTextLabel = $MarginContainer/RichTextLabel
func set_text_bbcode(value: String) -> void:
text_bbcode = value
if not rich_text_label:
yield(self, "ready")
rich_text_label.bbcode_text = text_bbcode

View File

@ -0,0 +1,37 @@
[gd_scene load_steps=4 format=3]
[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=1]
[ext_resource path="res://Demos/Utils/DemoInterface.gd" type="Script" id=2]
[sub_resource type="GDScript" id=1]
script/source = "tool
extends RichTextLabel
"
[node name="DemoInterface" type="PanelContainer"]
anchor_right = 1.0
margin_bottom = 140.0
rect_min_size = Vector2( 1024, 0 )
theme = ExtResource( 1 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
text_bbcode = "Replace this text for the demo."
[node name="MarginContainer" type="MarginContainer" parent="."]
margin_right = 1920.0
margin_bottom = 140.0
[node name="RichTextLabel" type="RichTextLabel" parent="MarginContainer"]
margin_left = 16.0
margin_top = 16.0
margin_right = 1904.0
margin_bottom = 124.0
rect_min_size = Vector2( 0, 55 )
bbcode_enabled = true
bbcode_text = "Replace this text for the demo."
text = "Replace this text for the demo."
scroll_active = false
script = SubResource( 1 )

View File

@ -0,0 +1,13 @@
tool
extends Line2D
export (Color) var inner_color := Color() setget set_inner_color
func _draw() -> void:
draw_colored_polygon(points, inner_color)
func set_inner_color(val: Color) -> void:
inner_color = val
update()

21
steering_ai/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 GDQuest
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

44
steering_ai/README.md Normal file
View File

@ -0,0 +1,44 @@
# Steering AI Framework
This demo shows the usage of [GDQuest's Godot Steering AI Framework](https://github.com/GDQuest/godot-steering-ai-framework)'s
c++ port that is built into the engine. [See here](https://github.com/Relintai/pandemonium_engine/tree/master/modules/steering_ai)
It supports all essential steering behaviors like flee, follow, look at, but also blended behaviors, group behaviors,
avoiding neighbors, following a path, following the leader, and much more.
## Introduction
In the 1990s, [Craig Reynolds](http://www.red3d.com/cwr/) developed algorithms for common AI behaviors. They allowed
AI agents to seek out or flee from a target, follow a pre-defined path, or face in a particular direction. They were simple,
repeatable tasks that could be broken down into programming algorithms, which made them easy to reuse, maintain, combine, and extend.
While an AI agent's next action is based on decision making and planning algorithms, steering behaviors dictate
how it will move from one frame to the next. They use available information and calculate where to move at that moment.
Joining these systems together can give sophisticated and graceful movement while also being more
efficient than complex pathfinding algorithms like A\*.
## The framework
This project takes inspiration from the excellent [GDX-AI](https://github.com/libgdx/gdx-ai) framework for the [LibGDX](https://libgdx.badlogicgames.com/)
java-based framework.
Every class in the framework extends Godot's [Reference](https://docs.godotengine.org/en/latest/classes/class_reference.html) type.
There is no need to have a complex scene tree; you can contain that has to do with the AI's movement inside GDScript classes.
### How it works
In GSAI, a steering agent represents a character or a vehicle. The agent stores its position, orientation,
maximum speeds, and current velocity. The agent stores a steering behavior that calculates a linear or
angular change in velocity based on its information.
The coder then applies that acceleration in whatever ways is appropriate to the character to change its v
elocities, like RigidBody's `apply_impulse`, or a KinematicBody's `move_and_slide`.
## Documentation
The documentation is available in-engine. Search for classes which names start with the word "GSAI".
The original framework's original documentation and code reference are available here:
[Godot steering AI framework documentation](https://gdquest.gitbook.io/godot-3-steering-ai-framework-reference/)

BIN
steering_ai/assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icon.png"
dest_files=[ "res://.import/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=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
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

151
steering_ai/assets/icon.svg Normal file
View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="icon.svg"
inkscape:version="1.1-dev (83f2ee46ff, 2020-02-13)"
id="svg1340"
version="1.1"
viewBox="0 0 16.933333 16.933334"
height="64"
width="64">
<defs
id="defs1334">
<clipPath
id="clipPath1560"
clipPathUnits="userSpaceOnUse">
<rect
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#293252;fill-opacity:1;stroke:none;stroke-width:1.40425;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;stop-color:#000000;stop-opacity:1"
id="rect1562"
width="16.933332"
height="16.933332"
x="0"
y="9.6346028e-08" />
</clipPath>
</defs>
<sodipodi:namedview
inkscape:snap-global="true"
inkscape:snap-others="false"
inkscape:object-nodes="false"
inkscape:snap-page="true"
inkscape:snap-bbox="true"
inkscape:window-maximized="1"
inkscape:window-y="0"
inkscape:window-x="0"
inkscape:window-height="1043"
inkscape:window-width="1920"
units="px"
showgrid="false"
inkscape:current-layer="layer1"
inkscape:document-units="mm"
inkscape:cy="31.438019"
inkscape:cx="15.072392"
inkscape:zoom="8"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base" />
<metadata
id="metadata1337">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<rect
y="0"
x="0"
height="16.933332"
width="16.933332"
id="rect1504"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#293252;fill-opacity:1;stroke:none;stroke-width:1.40425;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;stop-color:#000000;stop-opacity:1" />
<path
clip-path="url(#clipPath1560)"
id="path2490"
d="M 2.8526138,-0.0226856 2.9507848,1.274306 C 2.5771927,1.4791664 2.2289224,1.7185349 1.9075218,1.988743 L 0.29690799,1.3221671 -0.40866643,2.1624613 0.56110833,3.5585158 C 0.33791661,3.9257554 0.15316113,4.3166174 0.00975169,4.7250204 l -0.7432386,0.090259 -0.009472,1.7228785 0.40521717,0.191826 c 0,0.2151562 0.0190602,0.4320655 0.0310875,0.6505844 0.0205584,0.2185642 0.0528327,0.4331209 0.0974454,0.6435666 l -0.54416748,0.401985 -0.008756,1.5907221 1.2930922,-0.090536 C 0.75306491,10.299542 1.0115466,10.64731 1.3029499,10.96517 l -0.672761,1.553839 0.858959,0.689584 1.4456413,-0.959917 c 0.3687832,0.203771 0.7600417,0.372343 1.1673979,0.502553 l 0.2153945,1.714295 1.0964166,0.176342 0.7818497,-1.5822 c 0.2037711,0 0.4094501,-0.01685 0.6159876,-0.03895 H 6.812698 L 9.8042599,12.732617 9.3779282,8.4823903 6.3854715,8.7696026 6.5157868,10.092058 C 4.6330774,10.272636 2.9585336,8.9258916 2.7734622,7.0836627 2.5888891,5.2418454 3.9644158,3.6030022 5.8465387,3.4220125 L 8.8381053,3.1348571 8.5438181,0.20619376 5.5531989,0.49334922 C 5.3459823,0.51050176 5.1420605,0.5378074 4.9415586,0.57229759 L 4.4901554,-0.01349219 Z M 10.360111,2.7244603 9.577372,4.3066562 c -0.2035882,0 -0.4084223,0.016659 -0.6150947,0.038946 L 5.969764,4.633705 6.2641051,7.5605285 9.2556723,7.273373 a 3.4244787,3.3513826 0 0 1 3.7431617,3.007448 3.4244787,3.3513826 0 0 1 -3.0739683,3.662595 l -2.9915662,0.28894 0.2652052,2.646411 2.7965066,0.01566 0.2241417,-0.0215 c 0.206675,-0.01714 0.41087,-0.0444 0.610692,-0.07889 l 0.0814,0.105523 1.973596,0.01109 -0.06151,-0.818622 c 0.373232,-0.204827 0.723028,-0.444409 1.044158,-0.714444 l 1.609666,0.667466 0.705575,-0.840294 -0.968773,-1.396053 c 0.222649,-0.367242 0.407573,-0.758822 0.551301,-1.167399 l 1.699205,-0.205645 0.181684,-1.073405 -1.533445,-0.725078 c 0.01889,-0.214756 -0.01899,-0.432247 -0.03098,-0.6505829 -0.02061,-0.2185654 -0.05301,-0.4339146 -0.09935,-0.6444001 L 17.342103,8.3379231 16.950314,7.3203422 15.242313,7.4418002 C 15.020345,7.0685674 14.760954,6.7200461 14.469323,6.4020456 L 15.142137,4.8490976 14.284072,4.1595128 12.836646,5.1194284 C 12.467685,4.9156577 12.078251,4.7477386 11.671033,4.6177136 L 11.454747,2.9034731 Z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2f395f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.17682;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:connector-curvature="0" />
<g
style="stroke-width:1.24672"
transform="matrix(0.18285727,0,0,0.14154908,150.31973,-187.36868)"
id="g2450">
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#5e315b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -822.06042,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2430" />
<path
id="path2432"
d="m -812.80001,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#8c3f5d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#ba6156;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -803.5396,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2434" />
<path
id="path2436"
d="m -794.27919,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#f2a65e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#ffe478;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -785.01878,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2438" />
<path
id="path2440"
d="m -775.75837,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#cfff70;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#8fde5d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -766.49796,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2442" />
<path
id="path2444"
d="m -757.23755,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#3ca370;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#3d6e70;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -747.97714,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2446" />
<path
id="path2448"
d="m -738.71673,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#323e4f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
</g>
<path
sodipodi:nodetypes="cccc"
d="M 1.7415414,13.864431 C 2.8091455,12.301646 3.8954985,10.918152 4.8840406,10.004274 M 12.44693,3.6341761 c 0,0 1.658558,-1.2568206 2.909891,-2.065662"
style="fill:none;stroke:#a0a9ce;stroke-width:1.087;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:1.6;stroke-dasharray:2.174, 2.174;stroke-dashoffset:1.087;stroke-opacity:1"
id="path2283"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path2351"
d="M 4.6789148,3.8638581 6.5936823,6.200326 4.9999674,7.512026 7.0448877,10.007103 8.6388709,8.6952013 10.553866,11.032019 11.16251,4.529541 Z"
style="vector-effect:none;fill:#293252;fill-opacity:1;fill-rule:nonzero;stroke:#7786bb;stroke-width:0.827338;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

Some files were not shown because too many files have changed in this diff Show More