diff --git a/.github/workflows/Publish-Godot-Project.yml b/.github/workflows/Publish-Godot-Project.yml
index 65daaf7..c55f90f 100755
--- a/.github/workflows/Publish-Godot-Project.yml
+++ b/.github/workflows/Publish-Godot-Project.yml
@@ -29,22 +29,13 @@ env:
PROJECT_NAME: "AMSG" # Needs to be added, PLEASE DON'T USE SPACES
ITCH_PROJECT_NAME: "amsg" # Needs to be added
ITCH_USER_NAME: "ywmaa" # Needs to be added
- GODOT_VERSION: 4.1.1 # Needs to be added
+ GODOT_VERSION: 4.3 # Needs to be added
jobs:
- CleanArtifacts:
- # This job clears out the previous artifacts made so you don't run out of space in your github account
- runs-on: ubuntu-latest
- steps:
- - uses: kolpav/purge-artifacts-action@v1
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- expire-in: 1hr
-
Export:
needs: CleanArtifacts # wait for artifacts to clean before making a new one
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Download + Authorize Godot
run: |
@@ -91,17 +82,18 @@ jobs:
./godot --headless --path ./ --export-release "Linux/X11" ./exports/${{ env.PROJECT_NAME }}.x86_64
- - uses: actions/upload-artifact@v2
+ - uses: actions/upload-artifact@v4
with:
name: exports
path: exports
+ overwrite: true
Release:
needs: Export
if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_github_page
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Version
id: tag_version
@@ -114,7 +106,7 @@ jobs:
run: exit 1
- name: Download Exports
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4
with:
name: exports
path: exports
@@ -178,7 +170,7 @@ jobs:
content: v${{ github.event.inputs.export_version }}
mode: 0655
- - uses: actions/upload-artifact@v2
+ - uses: actions/upload-artifact@v4
with:
name: VERSION
path: ./VERSION.txt
@@ -189,7 +181,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download Exports
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4
with:
name: exports
path: exports
diff --git a/AMSG_Examples/Character/Animations/Idle.res b/AMSG_Examples/Character/Animations/Idle.res
old mode 100755
new mode 100644
index 32669cd..a796c7e
Binary files a/AMSG_Examples/Character/Animations/Idle.res and b/AMSG_Examples/Character/Animations/Idle.res differ
diff --git a/AMSG_Examples/Character/Animations/JogForward.res b/AMSG_Examples/Character/Animations/JogForward.res
old mode 100755
new mode 100644
index c915224..bdd5f66
Binary files a/AMSG_Examples/Character/Animations/JogForward.res and b/AMSG_Examples/Character/Animations/JogForward.res differ
diff --git a/AMSG_Examples/Character/Animations/Run.res b/AMSG_Examples/Character/Animations/Run.res
old mode 100755
new mode 100644
index 016d12e..5d51319
Binary files a/AMSG_Examples/Character/Animations/Run.res and b/AMSG_Examples/Character/Animations/Run.res differ
diff --git a/AMSG_Examples/Character/Animations/Walk.res b/AMSG_Examples/Character/Animations/Walk.res
old mode 100755
new mode 100644
index a6b0143..8538ece
Binary files a/AMSG_Examples/Character/Animations/Walk.res and b/AMSG_Examples/Character/Animations/Walk.res differ
diff --git a/AMSG_Examples/Character/mixamo_character.tscn b/AMSG_Examples/Character/mixamo_character.tscn
index 5de1ffe..4102c5a 100644
--- a/AMSG_Examples/Character/mixamo_character.tscn
+++ b/AMSG_Examples/Character/mixamo_character.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=57 format=3 uid="uid://cth47yn1duvdh"]
+[gd_scene load_steps=59 format=3 uid="uid://cth47yn1duvdh"]
[ext_resource type="PackedScene" uid="uid://ccqctdss4s6u5" path="res://addons/PoseWarping/PoseWarping.tscn" id="1_bk0at"]
[ext_resource type="Script" path="res://addons/AMSG/Components/CharacterMovementComponent.gd" id="1_ewnep"]
@@ -31,29 +31,6 @@
[ext_resource type="AudioStream" uid="uid://bpnobn6wg8hxp" path="res://AMSG_Examples/Character/footstep_sound/footstep2.wav" id="27_cpdra"]
[ext_resource type="PackedScene" uid="uid://dpniuhmc5sj82" path="res://addons/AMSG/Components/MantleComponent/MantleComponent.tscn" id="28_6ac02"]
-[sub_resource type="AnimationLibrary" id="AnimationLibrary_5egkr"]
-_data = {
-"CrouchIdle": ExtResource("7_e4twx"),
-"CrouchWalkingForward": ExtResource("8_y04sm"),
-"Falling": ExtResource("9_el410"),
-"FallingStart": ExtResource("10_ceyl8"),
-"FallingToRoll": ExtResource("11_g0fkm"),
-"HardFalling": ExtResource("12_feqar"),
-"Idle": ExtResource("13_6mj36"),
-"Idle1": ExtResource("14_8a0t0"),
-"Idle2": ExtResource("15_h6xx4"),
-"JogForward": ExtResource("16_1nyic"),
-"Jogbackward": ExtResource("17_5glyf"),
-"Kick": ExtResource("18_bjcll"),
-"Run": ExtResource("19_q06n7"),
-"RunToStop": ExtResource("20_fsxql"),
-"TPose": ExtResource("21_wy311"),
-"TurnLeft": ExtResource("22_j0xj5"),
-"TurnRight": ExtResource("23_qis1m"),
-"Walk": ExtResource("24_rjymo"),
-"WalkingBackward": ExtResource("25_fd0ml")
-}
-
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_mb2kt"]
animation = &"TurnLeft"
@@ -91,9 +68,11 @@ sync = true
xfade_time = 0.1
input_0/name = "Forward"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Backward"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_m0htu"]
@@ -107,18 +86,23 @@ sync = true
xfade_time = 0.2
input_0/name = "Idle"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Walk"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
input_2/name = "Run"
input_2/auto_advance = false
+input_2/break_loop_at_end = false
input_2/reset = true
input_3/name = "Jog"
input_3/auto_advance = false
+input_3/break_loop_at_end = false
input_3/reset = true
input_4/name = "Stop"
input_4/auto_advance = false
+input_4/break_loop_at_end = false
input_4/reset = true
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_81j80"]
@@ -134,9 +118,11 @@ sync = true
xfade_time = 0.1
input_0/name = "Forward"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Backward"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_bmtvy"]
@@ -147,9 +133,11 @@ sync = true
xfade_time = 0.3
input_0/name = "stand"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "crouch"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeTransition" id="AnimationNodeTransition_rufvy"]
@@ -157,9 +145,11 @@ sync = true
xfade_time = 0.2
input_0/name = "Idle"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Walk"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_ml0kl"]
@@ -215,6 +205,9 @@ nodes/VelocityDirection/position = Vector2(680, 1400)
nodes/output/position = Vector2(1540, 1400)
node_connections = [&"InAir", 0, &"Turn", &"InAir", 1, &"FallAnimation", &"RightOrLeft", 0, &"AnimTurnLeft", &"RightOrLeft", 1, &"AnimTurnRight", &"Turn", 0, &"VelocityDirection", &"Turn", 1, &"RightOrLeft", &"output", 0, &"InAir"]
+[sub_resource type="SeparationRayShape3D" id="SeparationRayShape3D_xh6ew"]
+length = 0.5
+
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_70w0s"]
resource_local_to_scene = true
radius = 0.375
@@ -425,14 +418,42 @@ bind/66/name = &"LeftToe_End"
bind/66/bone = -1
bind/66/pose = Transform3D(-1, -2.60114e-08, 2.31885e-15, -3.91155e-08, 1.48752e-07, 1, -3.3462e-08, 1, -8.91473e-08, 0.0949782, -0.202502, 0.00119966)
+[sub_resource type="Animation" id="Animation_uns1n"]
+length = 0.001
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_5egkr"]
+_data = {
+"CrouchIdle": ExtResource("7_e4twx"),
+"CrouchWalkingForward": ExtResource("8_y04sm"),
+"Falling": ExtResource("9_el410"),
+"FallingStart": ExtResource("10_ceyl8"),
+"FallingToRoll": ExtResource("11_g0fkm"),
+"HardFalling": ExtResource("12_feqar"),
+"Idle": ExtResource("13_6mj36"),
+"Idle1": ExtResource("14_8a0t0"),
+"Idle2": ExtResource("15_h6xx4"),
+"JogForward": ExtResource("16_1nyic"),
+"Jogbackward": ExtResource("17_5glyf"),
+"Kick": ExtResource("18_bjcll"),
+"RESET": SubResource("Animation_uns1n"),
+"Run": ExtResource("19_q06n7"),
+"RunToStop": ExtResource("20_fsxql"),
+"TPose": ExtResource("21_wy311"),
+"TurnLeft": ExtResource("22_j0xj5"),
+"TurnRight": ExtResource("23_qis1m"),
+"Walk": ExtResource("24_rjymo"),
+"WalkingBackward": ExtResource("25_fd0ml")
+}
+
[node name="Character" type="CharacterBody3D"]
+floor_constant_speed = true
[node name="GroundCheck" type="RayCast3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.186, 0)
target_position = Vector3(0, -0.4, 0)
hit_from_inside = true
-[node name="CharacterMovementComponent" type="Node" parent="." node_paths=PackedStringArray("mesh_ref", "anim_ref", "skeleton_ref", "collision_shape_ref", "camera_root", "character_node", "ground_check", "mantle_component", "pose_warping")]
+[node name="CharacterMovementComponent" type="Node" parent="." node_paths=PackedStringArray("mesh_ref", "anim_ref", "skeleton_ref", "collision_shape_ref", "camera_root", "character_node", "ground_check", "mantle_component", "pose_warping", "stair_collision_shape_3d")]
script = ExtResource("1_ewnep")
mesh_ref = NodePath("../Armature")
anim_ref = NodePath("../AnimationTree")
@@ -444,6 +465,7 @@ ground_check = NodePath("../GroundCheck")
mantle_component = NodePath("../Armature/Skeleton3D/MantleComponent")
pose_warping = NodePath("../Armature/Skeleton3D/PoseWarping")
tilt_power = 0.0
+stair_collision_shape_3d = NodePath("../StairCollisionShape3D")
deacceleration = 0.0
looking_direction_standing_data = ExtResource("2_c4o7m")
looking_direction_crouch_data = ExtResource("3_p3fng")
@@ -460,9 +482,6 @@ PlayerRef = NodePath("../CharacterMovementComponent")
first_person_camera_bone = NodePath("../Armature/Skeleton3D/HeadBone")
[node name="AnimationTree" parent="." node_paths=PackedStringArray("movement_script") instance=ExtResource("3_86f8p")]
-libraries = {
-"": SubResource("AnimationLibrary_5egkr")
-}
tree_root = SubResource("AnimationNodeBlendTree_nuhxy")
anim_player = NodePath("../AnimationPlayer")
parameters/VelocityDirection/JogFB/current_state = "Forward"
@@ -483,6 +502,10 @@ parameters/VelocityDirection/crouching/transition_request = ""
parameters/VelocityDirection/crouching/current_index = 0
movement_script = NodePath("../CharacterMovementComponent")
+[node name="StairCollisionShape3D" type="CollisionShape3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.5, 0.5)
+shape = SubResource("SeparationRayShape3D_xh6ew")
+
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_70w0s")
@@ -494,43 +517,43 @@ bones/0/name = "Hips"
bones/0/parent = -1
bones/0/rest = Transform3D(0.544576, -0.0348814, -0.837986, 0.0102475, 0.999337, -0.0349382, 0.838649, 0.0104393, 0.544573, -0.000172998, 0.901879, -0.00179914)
bones/0/enabled = true
-bones/0/position = Vector3(0.0133876, 0.936884, 0.020478)
-bones/0/rotation = Quaternion(-0.00656786, 0.0965517, 0.0127174, 0.995225)
+bones/0/position = Vector3(-0.000122806, 0.950186, 0.0335941)
+bones/0/rotation = Quaternion(-0.0224975, 0.0782023, -0.00934325, 0.99664)
bones/0/scale = Vector3(1, 1, 1)
bones/1/name = "Spine"
bones/1/parent = 0
bones/1/rest = Transform3D(0.99963, -0.0129189, 0.0239171, 0.01122, 0.997494, 0.0698543, -0.0247596, -0.0695601, 0.99727, 4.88944e-09, 0.0992349, -0.0122733)
bones/1/enabled = true
bones/1/position = Vector3(4.88944e-09, 0.0992349, -0.0122733)
-bones/1/rotation = Quaternion(-0.0229041, -0.0831827, 0.00234219, 0.996268)
+bones/1/rotation = Quaternion(-0.0179268, -0.0635564, 0.0176312, 0.997661)
bones/1/scale = Vector3(1, 1, 1)
bones/2/name = "Spine1"
bones/2/parent = 1
bones/2/rest = Transform3D(0.99985, -0.015446, 0.00786788, 0.0155655, 0.999761, -0.0153596, -0.00762876, 0.0154798, 0.999851, -2.79397e-09, 0.11732, 1.86265e-09)
bones/2/enabled = true
bones/2/position = Vector3(-2.79397e-09, 0.11732, 1.86265e-09)
-bones/2/rotation = Quaternion(0.00183818, -0.0230571, -0.000236633, 0.999732)
+bones/2/rotation = Quaternion(0.00235979, -0.017985, 0.00356301, 0.999829)
bones/2/scale = Vector3(1, 1, 1)
bones/3/name = "Spine2"
bones/3/parent = 2
bones/3/rest = Transform3D(0.999844, -0.014346, 0.0103258, 0.0156141, 0.990645, -0.135571, -0.00828427, 0.135711, 0.990714, -2.79397e-09, 0.134588, -2.51457e-08)
bones/3/enabled = true
bones/3/position = Vector3(-2.79397e-09, 0.134588, -2.51457e-08)
-bones/3/rotation = Quaternion(0.062191, -0.0230232, 0.00125365, 0.997798)
+bones/3/rotation = Quaternion(0.0626086, -0.0177627, 0.00473759, 0.997869)
bones/3/scale = Vector3(1, 1, 1)
bones/4/name = "Neck"
bones/4/parent = 3
bones/4/rest = Transform3D(0.968778, 0.12654, 0.213204, -0.00181599, 0.863542, -0.504273, -0.247921, 0.488142, 0.836811, 2.48197e-07, 0.150325, 0.00792907)
bones/4/enabled = true
bones/4/position = Vector3(2.48197e-07, 0.150325, 0.00792907)
-bones/4/rotation = Quaternion(0.133564, 0.00294991, -0.0034408, 0.99103)
+bones/4/rotation = Quaternion(0.133591, 0.0013655, -0.0019673, 0.991034)
bones/4/scale = Vector3(1, 1, 1)
bones/5/name = "Head"
bones/5/parent = 4
bones/5/rest = Transform3D(0.840773, 0.330252, 0.428993, -0.33245, 0.940342, -0.0723432, -0.427291, -0.0817944, 0.900406, 5.58794e-09, 0.107895, 5.21541e-08)
bones/5/enabled = true
bones/5/position = Vector3(5.58794e-09, 0.107895, 5.21541e-08)
-bones/5/rotation = Quaternion(0.00222489, -0.0109032, -0.0124244, 0.999861)
+bones/5/rotation = Quaternion(0.0129875, -0.0186422, -0.0117148, 0.999673)
bones/5/scale = Vector3(1, 1, 1)
bones/6/name = "HeadTop_End"
bones/6/parent = 5
@@ -558,49 +581,49 @@ bones/9/parent = 3
bones/9/rest = Transform3D(-0.250988, 0.959361, -0.128958, 0.025503, -0.126623, -0.991623, -0.967654, -0.252174, 0.0073142, 0.0610582, 0.0911044, 0.00705553)
bones/9/enabled = true
bones/9/position = Vector3(0.0610582, 0.0911044, 0.00705553)
-bones/9/rotation = Quaternion(-0.577464, -0.435062, 0.584563, -0.368161)
+bones/9/rotation = Quaternion(-0.570932, -0.440699, 0.587714, -0.366624)
bones/9/scale = Vector3(1, 1, 1)
bones/10/name = "LeftArm"
bones/10/parent = 9
bones/10/rest = Transform3D(0.845869, -0.51692, -0.131522, 0.093338, 0.386222, -0.917671, 0.52516, 0.763954, 0.374941, 7.45058e-09, 0.129223, 3.95812e-08)
bones/10/enabled = true
bones/10/position = Vector3(7.45058e-09, 0.129223, 3.95812e-08)
-bones/10/rotation = Quaternion(0.382833, 0.00660452, 0.325751, 0.864455)
+bones/10/rotation = Quaternion(0.427004, 0.0312609, 0.281909, 0.858614)
bones/10/scale = Vector3(1, 1, 1)
bones/11/name = "LeftForeArm"
bones/11/parent = 10
bones/11/rest = Transform3D(0.138967, -0.989426, 0.0415226, 0.989436, 0.140472, 0.0358277, -0.0412816, 0.0361051, 0.998495, -4.47035e-08, 0.274229, -7.45058e-09)
bones/11/enabled = true
bones/11/position = Vector3(-4.47035e-08, 0.274229, -7.45058e-09)
-bones/11/rotation = Quaternion(0.000308475, 0.0351343, 0.255242, 0.966239)
+bones/11/rotation = Quaternion(0.000211332, 0.035705, 0.185318, 0.98203)
bones/11/scale = Vector3(1, 1, 1)
bones/12/name = "LeftHand"
bones/12/parent = 11
bones/12/rest = Transform3D(0.746359, -0.304314, 0.591895, 0.184003, 0.949028, 0.255908, -0.639601, -0.0820888, 0.764311, 6.0536e-09, 0.276326, -1.49012e-08)
bones/12/enabled = true
bones/12/position = Vector3(6.0536e-09, 0.276326, -1.49012e-08)
-bones/12/rotation = Quaternion(-0.126266, -0.0722827, 0.0805157, 0.986078)
+bones/12/rotation = Quaternion(-0.102403, -0.0303159, 0.080992, 0.990977)
bones/12/scale = Vector3(1, 1, 1)
bones/13/name = "LeftHandMiddle1"
bones/13/parent = 12
bones/13/rest = Transform3D(0.98654, 0.118644, -0.112532, -0.118809, 0.0472127, -0.991794, -0.112357, 0.991814, 0.0606732, -3.12924e-07, 0.127755, -7.63685e-08)
bones/13/enabled = true
bones/13/position = Vector3(-3.12924e-07, 0.127755, -7.63685e-08)
-bones/13/rotation = Quaternion(0.286876, -0.00603298, -0.046823, 0.956804)
+bones/13/rotation = Quaternion(0.300271, -0.00416156, -0.055033, 0.952256)
bones/13/scale = Vector3(1, 1, 1)
bones/14/name = "LeftHandMiddle2"
bones/14/parent = 13
bones/14/rest = Transform3D(0.980685, 0.110739, -0.161229, -0.112737, -0.353585, -0.928584, -0.159838, 0.928824, -0.334271, -7.45058e-09, 0.0361397, -5.21541e-08)
bones/14/enabled = true
bones/14/position = Vector3(-7.45058e-09, 0.0361397, -5.21541e-08)
-bones/14/rotation = Quaternion(0.233638, -6.78003e-07, -0.0237419, 0.972034)
+bones/14/rotation = Quaternion(0.248633, -6.92904e-07, -0.0252654, 0.968268)
bones/14/scale = Vector3(1, 1, 1)
bones/15/name = "LeftHandMiddle3"
bones/15/parent = 14
bones/15/rest = Transform3D(0.981085, 0.112002, -0.157883, -0.108383, -0.357956, -0.927427, -0.160389, 0.926997, -0.339046, 0, 0.0345975, 7.07805e-08)
bones/15/enabled = true
bones/15/position = Vector3(0, 0.0345975, 7.07805e-08)
-bones/15/rotation = Quaternion(0.148777, 1.05053e-06, -0.0151084, 0.988755)
+bones/15/rotation = Quaternion(0.164532, 1.17719e-06, -0.0167091, 0.98623)
bones/15/scale = Vector3(1, 1, 1)
bones/16/name = "LeftHandMiddle4"
bones/16/parent = 15
@@ -621,14 +644,14 @@ bones/18/parent = 17
bones/18/rest = Transform3D(0.793061, 0.491162, -0.360297, -0.562049, 0.818065, -0.121947, 0.234851, 0.299216, 0.924832, 1.19209e-07, 0.0474499, -2.44938e-07)
bones/18/enabled = true
bones/18/position = Vector3(1.19209e-07, 0.0474499, -2.44938e-07)
-bones/18/rotation = Quaternion(0.10197, 0.0270494, -0.209325, 0.972139)
+bones/18/rotation = Quaternion(0.10479, 0.024822, -0.215164, 0.970622)
bones/18/scale = Vector3(1, 1, 1)
bones/19/name = "LeftHandThumb3"
bones/19/parent = 18
bones/19/rest = Transform3D(0.347552, 0.931585, -0.106567, -0.924718, 0.359352, 0.12555, 0.155256, 0.0549092, 0.986347, -1.11759e-07, 0.0438214, 3.72529e-08)
bones/19/enabled = true
bones/19/position = Vector3(-1.11759e-07, 0.0438214, 3.72529e-08)
-bones/19/rotation = Quaternion(-0.232044, -0.00385652, 0.182674, 0.955391)
+bones/19/rotation = Quaternion(-0.218307, -0.0108869, 0.172664, 0.960422)
bones/19/scale = Vector3(1, 1, 1)
bones/20/name = "LeftHandThumb4"
bones/20/parent = 19
@@ -642,21 +665,21 @@ bones/21/parent = 12
bones/21/rest = Transform3D(0.983723, 0.142189, -0.109869, -0.119058, 0.0577917, -0.991204, -0.134589, 0.988151, 0.0737798, -0.0282207, 0.122666, 0.00231682)
bones/21/enabled = true
bones/21/position = Vector3(-0.0282207, 0.122666, 0.00231682)
-bones/21/rotation = Quaternion(0.211924, -0.0112666, -0.00691015, 0.977197)
+bones/21/rotation = Quaternion(0.223584, -0.0106888, -0.0136584, 0.97453)
bones/21/scale = Vector3(1, 1, 1)
bones/22/name = "LeftHandIndex2"
bones/22/parent = 21
bones/22/rest = Transform3D(0.978949, 0.10384, -0.175717, -0.111366, -0.44972, -0.8862, -0.171047, 0.887113, -0.428688, 1.11759e-07, 0.0389198, -5.96046e-08)
bones/22/enabled = true
bones/22/position = Vector3(1.11759e-07, 0.0389198, -5.96046e-08)
-bones/22/rotation = Quaternion(0.213634, -1.37091e-06, -0.021712, 0.976673)
+bones/22/rotation = Quaternion(0.229903, -1.52737e-06, -0.0233649, 0.972933)
bones/22/scale = Vector3(1, 1, 1)
bones/23/name = "LeftHandIndex3"
bones/23/parent = 22
bones/23/rest = Transform3D(0.981451, 0.113056, -0.15483, -0.109059, -0.334958, -0.9359, -0.15767, 0.935426, -0.316415, 3.72529e-08, 0.0341517, -1.11759e-08)
bones/23/enabled = true
bones/23/position = Vector3(3.72529e-08, 0.0341517, -1.11759e-08)
-bones/23/rotation = Quaternion(0.100549, -1.9744e-06, -0.0102159, 0.99488)
+bones/23/rotation = Quaternion(0.117928, -2.01166e-06, -0.0119815, 0.99295)
bones/23/scale = Vector3(1, 1, 1)
bones/24/name = "LeftHandIndex4"
bones/24/parent = 23
@@ -670,21 +693,21 @@ bones/25/parent = 12
bones/25/rest = Transform3D(0.991492, 0.0540781, -0.118406, -0.118263, -0.00584495, -0.992965, -0.0543897, 0.99852, 0.000600219, 0.0221662, 0.12147, -9.90927e-05)
bones/25/enabled = true
bones/25/position = Vector3(0.0221662, 0.12147, -9.90927e-05)
-bones/25/rotation = Quaternion(0.299659, 0.00221775, -0.0749724, 0.951093)
+bones/25/rotation = Quaternion(0.313606, 0.00453678, -0.0828107, 0.945924)
bones/25/scale = Vector3(1, 1, 1)
bones/26/name = "LeftHandRing2"
bones/26/parent = 25
bones/26/rest = Transform3D(0.981497, 0.113181, -0.154445, -0.116659, -0.286137, -0.951061, -0.151835, 0.951481, -0.267639, -3.72529e-08, 0.036012, -1.11759e-07)
bones/26/enabled = true
bones/26/position = Vector3(-3.72529e-08, 0.036012, -1.11759e-07)
-bones/26/rotation = Quaternion(0.322405, -2.59653e-06, -0.0327651, 0.946035)
+bones/26/rotation = Quaternion(0.333666, -2.71946e-06, -0.0339093, 0.942081)
bones/26/scale = Vector3(1, 1, 1)
bones/27/name = "LeftHandRing3"
bones/27/parent = 26
bones/27/rest = Transform3D(0.98241, 0.115381, -0.146824, -0.113355, -0.256342, -0.959916, -0.148393, 0.959675, -0.238754, -4.09782e-08, 0.0330728, 0)
bones/27/enabled = true
bones/27/position = Vector3(-4.09782e-08, 0.0330728, 0)
-bones/27/rotation = Quaternion(0.103313, 1.93715e-07, -0.0104938, 0.994594)
+bones/27/rotation = Quaternion(0.120758, 2.5332e-07, -0.0122662, 0.992606)
bones/27/scale = Vector3(1, 1, 1)
bones/28/name = "LeftHandRing4"
bones/28/parent = 27
@@ -698,21 +721,21 @@ bones/29/parent = 12
bones/29/rest = Transform3D(0.991785, 0.0101279, -0.127516, -0.126197, -0.0855001, -0.988314, -0.0209122, 0.996287, -0.0835196, 0.0472581, 0.109082, 0.00226384)
bones/29/enabled = true
bones/29/position = Vector3(0.0472581, 0.109082, 0.00226384)
-bones/29/rotation = Quaternion(0.270006, -0.00351245, -0.0531575, 0.961384)
+bones/29/rotation = Quaternion(0.28716, -0.00254507, -0.0601934, 0.955986)
bones/29/scale = Vector3(1, 1, 1)
bones/30/name = "LeftHandPinky2"
bones/30/parent = 29
bones/30/rest = Transform3D(0.989305, 0.129006, -0.068066, -0.049097, -0.144898, -0.988228, -0.13735, 0.981001, -0.137015, -5.96046e-08, 0.0413669, -1.49012e-08)
bones/30/enabled = true
bones/30/position = Vector3(-5.96046e-08, 0.0413669, -1.49012e-08)
-bones/30/rotation = Quaternion(0.206948, -2.22027e-06, -0.0210362, 0.978126)
+bones/30/rotation = Quaternion(0.220756, -2.26125e-06, -0.0224391, 0.975071)
bones/30/scale = Vector3(1, 1, 1)
bones/31/name = "LeftHandPinky3"
bones/31/parent = 30
bones/31/rest = Transform3D(0.977834, 0.0980185, -0.185023, -0.0947121, -0.581029, -0.808353, -0.186738, 0.807959, -0.558866, -4.47035e-08, 0.0259482, 3.53903e-08)
bones/31/enabled = true
bones/31/position = Vector3(-4.47035e-08, 0.0259482, 3.53903e-08)
-bones/31/rotation = Quaternion(0.137891, -5.21541e-07, -0.0139999, 0.990348)
+bones/31/rotation = Quaternion(0.154317, -4.32134e-07, -0.0156687, 0.987897)
bones/31/scale = Vector3(1, 1, 1)
bones/32/name = "LeftHandPinky4"
bones/32/parent = 31
@@ -726,49 +749,49 @@ bones/33/parent = 3
bones/33/rest = Transform3D(-0.214833, -0.949432, 0.228968, -0.0511495, -0.223182, -0.973434, 0.975311, -0.220837, -0.000616074, -0.061057, 0.0911053, 0.00705566)
bones/33/enabled = true
bones/33/position = Vector3(-0.061057, 0.0911053, 0.00705566)
-bones/33/rotation = Quaternion(0.512212, -0.485295, 0.622497, 0.338564)
+bones/33/rotation = Quaternion(0.519323, -0.479224, 0.622316, 0.336704)
bones/33/scale = Vector3(1, 1, 1)
bones/34/name = "RightArm"
bones/34/parent = 33
bones/34/rest = Transform3D(0.555382, 0.714901, -0.424814, -0.786414, 0.285417, -0.547804, -0.270377, 0.63832, 0.720724, -2.23517e-08, 0.129223, 9.12696e-08)
bones/34/enabled = true
bones/34/position = Vector3(-2.23517e-08, 0.129223, 9.12696e-08)
-bones/34/rotation = Quaternion(0.51707, -0.0554019, 0.0279549, 0.85369)
+bones/34/rotation = Quaternion(0.514512, -0.0358262, -0.00385591, 0.856726)
bones/34/scale = Vector3(1, 1, 1)
bones/35/name = "RightForeArm"
bones/35/parent = 34
bones/35/rest = Transform3D(-0.491194, 0.870247, -0.0374029, -0.870282, -0.488505, 0.0630281, 0.0365786, 0.0635101, 0.997311, 7.45058e-09, 0.274776, -3.72529e-08)
bones/35/enabled = true
bones/35/position = Vector3(7.45058e-09, 0.274776, -3.72529e-08)
-bones/35/rotation = Quaternion(0.000349137, -0.0718339, -0.138728, 0.987722)
+bones/35/rotation = Quaternion(0.000354329, -0.0718236, -0.139773, 0.987575)
bones/35/scale = Vector3(1, 1, 1)
bones/36/name = "RightHand"
bones/36/parent = 35
bones/36/rest = Transform3D(0.953663, 0.121098, 0.275431, -0.18063, 0.962538, 0.202223, -0.240624, -0.242603, 0.939811, 7.45058e-09, 0.276868, 5.96046e-08)
bones/36/enabled = true
bones/36/position = Vector3(7.45058e-09, 0.276868, 5.96046e-08)
-bones/36/rotation = Quaternion(0.0301975, -0.146344, 0.0553801, 0.987221)
+bones/36/rotation = Quaternion(0.00477323, -0.0915028, 0.0163464, 0.995659)
bones/36/scale = Vector3(1, 1, 1)
bones/37/name = "RightHandMiddle1"
bones/37/parent = 36
bones/37/rest = Transform3D(0.986308, -0.119644, 0.1135, 0.119813, 0.0469439, -0.991686, 0.113321, 0.991706, 0.060636, 3.50177e-07, 0.127755, -8.9407e-08)
bones/37/enabled = true
bones/37/position = Vector3(3.50177e-07, 0.127755, -8.9407e-08)
-bones/37/rotation = Quaternion(0.214752, 8.05836e-05, 0.0538795, 0.975181)
+bones/37/rotation = Quaternion(0.218397, 0.00144101, 0.0481887, 0.974668)
bones/37/scale = Vector3(1, 1, 1)
bones/38/name = "RightHandMiddle2"
bones/38/parent = 37
bones/38/rest = Transform3D(0.980361, -0.111685, 0.162538, 0.114835, -0.346749, -0.930902, 0.160328, 0.931285, -0.327114, 6.70552e-08, 0.0361398, -1.02445e-07)
bones/38/enabled = true
bones/38/position = Vector3(6.70552e-08, 0.0361398, -1.02445e-07)
-bones/38/rotation = Quaternion(0.251403, 6.482e-07, 0.0202237, 0.967671)
+bones/38/rotation = Quaternion(0.257922, 7.07805e-07, 0.0207481, 0.965943)
bones/38/scale = Vector3(1, 1, 1)
bones/39/name = "RightHandMiddle3"
bones/39/parent = 38
bones/39/rest = Transform3D(0.980787, -0.112947, 0.159059, 0.107057, -0.369977, -0.922852, 0.163081, 0.922149, -0.350778, 7.45058e-09, 0.0345976, -4.84288e-08)
bones/39/enabled = true
bones/39/position = Vector3(7.45058e-09, 0.0345976, -4.84288e-08)
-bones/39/rotation = Quaternion(0.0553324, -3.20375e-07, 0.00444282, 0.998458)
+bones/39/rotation = Quaternion(0.0576313, -4.17233e-07, 0.00462785, 0.998327)
bones/39/scale = Vector3(1, 1, 1)
bones/40/name = "RightHandMiddle4"
bones/40/parent = 39
@@ -789,14 +812,14 @@ bones/42/parent = 41
bones/42/rest = Transform3D(0.793791, -0.608189, -0.00159446, 0.595053, 0.777184, -0.204689, 0.125729, 0.161531, 0.978826, -1.2666e-07, 0.0474498, -2.68221e-07)
bones/42/enabled = true
bones/42/position = Vector3(-1.2666e-07, 0.0474498, -2.68221e-07)
-bones/42/rotation = Quaternion(0.007073, -0.0406278, 0.237663, 0.970472)
+bones/42/rotation = Quaternion(0.0211532, -0.0367989, 0.261502, 0.964269)
bones/42/scale = Vector3(1, 1, 1)
bones/43/name = "RightHandThumb3"
bones/43/parent = 42
bones/43/rest = Transform3D(0.501426, -0.84416, 0.189648, 0.865092, 0.485702, -0.125336, 0.0136913, 0.226909, 0.973819, 1.56462e-07, 0.0438213, -9.87202e-08)
bones/43/enabled = true
bones/43/position = Vector3(1.56462e-07, 0.0438213, -9.87202e-08)
-bones/43/rotation = Quaternion(-0.175493, -0.0918232, -0.149539, 0.968715)
+bones/43/rotation = Quaternion(-0.155805, -0.0794883, -0.14038, 0.974525)
bones/43/scale = Vector3(1, 1, 1)
bones/44/name = "RightHandThumb4"
bones/44/parent = 43
@@ -810,21 +833,21 @@ bones/45/parent = 36
bones/45/rest = Transform3D(0.978763, -0.172845, 0.110213, 0.120904, 0.0525683, -0.991271, 0.165542, 0.983545, 0.0723496, 0.0282207, 0.122666, 0.00231693)
bones/45/enabled = true
bones/45/position = Vector3(0.0282207, 0.122666, 0.00231693)
-bones/45/rotation = Quaternion(0.0985925, 0.00225035, 0.0178964, 0.994964)
+bones/45/rotation = Quaternion(0.123395, 0.00363555, 0.0168517, 0.992208)
bones/45/scale = Vector3(1, 1, 1)
bones/46/name = "RightHandIndex2"
bones/46/parent = 45
bones/46/rest = Transform3D(0.978593, -0.104714, 0.177172, 0.106914, -0.476935, -0.872412, 0.175853, 0.872679, -0.45553, 1.49012e-07, 0.0389196, -8.75443e-08)
bones/46/enabled = true
bones/46/position = Vector3(1.49012e-07, 0.0389196, -8.75443e-08)
-bones/46/rotation = Quaternion(0.259028, -1.49012e-08, 0.0208402, 0.965645)
+bones/46/rotation = Quaternion(0.288328, 1.3411e-07, 0.0231968, 0.957251)
bones/46/scale = Vector3(1, 1, 1)
bones/47/name = "RightHandIndex3"
bones/47/parent = 46
bones/47/rest = Transform3D(0.981139, -0.114005, 0.156106, 0.114242, -0.309465, -0.944023, 0.155933, 0.944052, -0.290604, -7.45058e-09, 0.0341516, 5.96046e-08)
bones/47/enabled = true
bones/47/position = Vector3(-7.45058e-09, 0.0341516, 5.96046e-08)
-bones/47/rotation = Quaternion(0.0869244, -1.63913e-07, 0.00699165, 0.99619)
+bones/47/rotation = Quaternion(0.0978021, -1.63913e-07, 0.00786658, 0.995175)
bones/47/scale = Vector3(1, 1, 1)
bones/48/name = "RightHandIndex4"
bones/48/parent = 47
@@ -838,21 +861,21 @@ bones/49/parent = 36
bones/49/rest = Transform3D(0.991829, -0.0281871, 0.124419, 0.122843, -0.0520322, -0.991061, 0.0344089, 0.998247, -0.0481446, -0.0221661, 0.12147, -9.89214e-05)
bones/49/enabled = true
bones/49/position = Vector3(-0.0221661, 0.12147, -9.89214e-05)
-bones/49/rotation = Quaternion(0.284454, -0.0079786, 0.0859797, 0.954793)
+bones/49/rotation = Quaternion(0.271181, -0.00485656, 0.0756087, 0.959542)
bones/49/scale = Vector3(1, 1, 1)
bones/50/name = "RightHandRing2"
bones/50/parent = 49
bones/50/rest = Transform3D(0.982662, -0.117406, 0.143498, 0.122607, -0.169092, -0.977944, 0.139081, 0.978583, -0.151765, -7.45058e-09, 0.036012, 0)
bones/50/enabled = true
bones/50/position = Vector3(-7.45058e-09, 0.036012, 0)
-bones/50/rotation = Quaternion(0.223182, 3.48315e-06, 0.017958, 0.974611)
+bones/50/rotation = Quaternion(0.216114, 3.44217e-06, 0.0173895, 0.976213)
bones/50/scale = Vector3(1, 1, 1)
bones/51/name = "RightHandRing3"
bones/51/parent = 50
bones/51/rest = Transform3D(0.982132, -0.116356, 0.147913, 0.107863, -0.296024, -0.949071, 0.154216, 0.948067, -0.278184, -2.23517e-08, 0.0330732, -8.9407e-08)
bones/51/enabled = true
bones/51/position = Vector3(-2.23517e-08, 0.0330732, -8.9407e-08)
-bones/51/rotation = Quaternion(0.0831442, -3.52412e-06, 0.00668463, 0.996515)
+bones/51/rotation = Quaternion(0.0771068, -3.51667e-06, 0.00619901, 0.997004)
bones/51/scale = Vector3(1, 1, 1)
bones/52/name = "RightHandRing4"
bones/52/parent = 51
@@ -866,21 +889,21 @@ bones/53/parent = 36
bones/53/rest = Transform3D(0.989897, 0.0602255, 0.128364, 0.133612, -0.0931972, -0.986642, -0.0474579, 0.993824, -0.100302, -0.047258, 0.109082, 0.00226358)
bones/53/enabled = true
bones/53/position = Vector3(-0.047258, 0.109082, 0.00226358)
-bones/53/rotation = Quaternion(0.30704, 0.00260534, 0.0601345, 0.949791)
+bones/53/rotation = Quaternion(0.294347, 0.00573038, 0.0439418, 0.954671)
bones/53/scale = Vector3(1, 1, 1)
bones/54/name = "RightHandPinky2"
bones/54/parent = 53
bones/54/rest = Transform3D(0.983236, -0.118306, 0.138749, 0.122507, -0.134994, -0.983244, 0.135054, 0.983758, -0.118237, -2.98023e-08, 0.0413665, 4.24334e-08)
bones/54/enabled = true
bones/54/position = Vector3(-2.98023e-08, 0.0413665, 4.24334e-08)
-bones/54/rotation = Quaternion(0.272652, 2.9467e-06, 0.0219399, 0.961863)
+bones/54/rotation = Quaternion(0.253823, 2.69339e-06, 0.0204255, 0.967035)
bones/54/scale = Vector3(1, 1, 1)
bones/55/name = "RightHandPinky3"
bones/55/parent = 54
bones/55/rest = Transform3D(0.977459, -0.0988442, 0.186556, 0.0932951, -0.590451, -0.801664, 0.189392, 0.800998, -0.56792, -5.21541e-08, 0.0259486, -3.72529e-08)
bones/55/enabled = true
bones/55/position = Vector3(-5.21541e-08, 0.0259486, -3.72529e-08)
-bones/55/rotation = Quaternion(0.165435, -1.74344e-06, 0.0132953, 0.986131)
+bones/55/rotation = Quaternion(0.148708, -1.61678e-06, 0.0119498, 0.988809)
bones/55/scale = Vector3(1, 1, 1)
bones/56/name = "RightHandPinky4"
bones/56/parent = 55
@@ -894,28 +917,28 @@ bones/57/parent = 0
bones/57/rest = Transform3D(-0.919821, -0.336213, -0.202214, 0.264978, -0.912457, 0.311783, -0.289337, 0.233202, 0.928386, -0.0912445, -0.0665637, -0.000553781)
bones/57/enabled = true
bones/57/position = Vector3(-0.0912445, -0.0665637, -0.000553781)
-bones/57/rotation = Quaternion(-0.051413, 0.27047, 0.96126, 0.0134798)
+bones/57/rotation = Quaternion(-0.0601304, 0.210408, 0.975578, -0.0189693)
bones/57/scale = Vector3(1, 1, 1)
bones/58/name = "RightLeg"
bones/58/parent = 57
bones/58/rest = Transform3D(0.997811, 0.0392429, -0.0532304, 0.00932048, 0.713425, 0.70067, 0.0654722, -0.699632, 0.711497, 4.84288e-08, 0.405994, 2.6077e-08)
bones/58/enabled = true
bones/58/position = Vector3(4.84288e-08, 0.405994, 2.6077e-08)
-bones/58/rotation = Quaternion(-0.150393, 0.0814245, -0.019361, 0.985077)
+bones/58/rotation = Quaternion(-0.237342, 0.0818959, -0.0107567, 0.967908)
bones/58/scale = Vector3(1, 1, 1)
bones/59/name = "RightFoot"
bones/59/parent = 58
bones/59/rest = Transform3D(0.96994, -0.122934, 0.210008, 0.229929, 0.180407, -0.95634, 0.0796801, 0.975879, 0.20325, -1.02445e-08, 0.42099, 9.31323e-09)
bones/59/enabled = true
bones/59/position = Vector3(-1.02445e-08, 0.42099, 9.31323e-09)
-bones/59/rotation = Quaternion(0.396655, -0.0117189, -0.0468712, 0.916696)
+bones/59/rotation = Quaternion(0.434458, -0.0207596, -0.0439782, 0.899378)
bones/59/scale = Vector3(1, 1, 1)
bones/60/name = "RightToeBase"
bones/60/parent = 59
bones/60/rest = Transform3D(0.999367, 6.43255e-05, 0.0355612, 0.0227211, 0.768109, -0.639916, -0.027356, 0.640319, 0.767622, -5.51563e-09, 0.16432, -1.09159e-07)
bones/60/enabled = true
bones/60/position = Vector3(-5.51563e-09, 0.16432, -1.09159e-07)
-bones/60/rotation = Quaternion(0.397566, 0.0170704, 0.004986, 0.917401)
+bones/60/rotation = Quaternion(0.356814, 0.0168345, 0.0057322, 0.934006)
bones/60/scale = Vector3(1, 1, 1)
bones/61/name = "RightToe_End"
bones/61/parent = 60
@@ -929,28 +952,28 @@ bones/62/parent = 0
bones/62/rest = Transform3D(-0.893651, 0.403296, 0.196826, -0.227377, -0.785047, 0.576195, 0.386895, 0.470164, 0.793258, 0.0912445, -0.0665636, -0.000553777)
bones/62/enabled = true
bones/62/position = Vector3(0.0912445, -0.0665636, -0.000553777)
-bones/62/rotation = Quaternion(0.0646029, -0.15248, 0.98602, -0.0184466)
+bones/62/rotation = Quaternion(0.0499682, -0.0180443, 0.996862, -0.0586879)
bones/62/scale = Vector3(1, 1, 1)
bones/63/name = "LeftLeg"
bones/63/parent = 62
bones/63/rest = Transform3D(0.99576, 0.0029921, 0.0919402, -0.056273, 0.810456, 0.583091, -0.0727688, -0.585792, 0.807188, 5.12227e-08, 0.405994, -2.04891e-08)
bones/63/enabled = true
bones/63/position = Vector3(5.12227e-08, 0.405994, -2.04891e-08)
-bones/63/rotation = Quaternion(-0.196845, 0.0755206, 0.0180967, 0.977354)
+bones/63/rotation = Quaternion(-0.467087, 0.0138946, 0.0240013, 0.883776)
bones/63/scale = Vector3(1, 1, 1)
bones/64/name = "LeftFoot"
bones/64/parent = 63
bones/64/rest = Transform3D(0.977802, 0.128039, -0.165856, -0.209522, 0.59104, -0.778956, -0.00170929, 0.796415, 0.604748, -2.04891e-08, 0.42099, 6.98492e-09)
bones/64/enabled = true
bones/64/position = Vector3(-2.04891e-08, 0.42099, 6.98492e-09)
-bones/64/rotation = Quaternion(0.435056, 0.0338564, -0.00805083, 0.899731)
+bones/64/rotation = Quaternion(0.282556, -0.0176465, -0.0508921, 0.957737)
bones/64/scale = Vector3(1, 1, 1)
bones/65/name = "LeftToeBase"
bones/65/parent = 64
bones/65/rest = Transform3D(0.999367, -0.000945242, -0.0355486, -0.0227206, 0.752033, -0.658734, 0.0273564, 0.659125, 0.751536, 3.66616e-08, 0.16432, -1.10293e-07)
bones/65/enabled = true
bones/65/position = Vector3(3.66616e-08, 0.16432, -1.10293e-07)
-bones/65/rotation = Quaternion(0.621119, -0.00791441, 0.00527677, 0.783659)
+bones/65/rotation = Quaternion(0.386484, -0.0318405, -0.00965911, 0.921696)
bones/65/scale = Vector3(1, 1, 1)
bones/66/name = "LeftToe_End"
bones/66/parent = 65
@@ -969,31 +992,32 @@ mesh = ExtResource("6_e2l25")
skin = SubResource("Skin_hh536")
[node name="HeadBone" type="BoneAttachment3D" parent="Armature/Skeleton3D"]
-transform = Transform3D(0.997557, -0.0260815, -0.0648099, 0.00247161, 0.940292, -0.340359, 0.0698173, 0.339367, 0.938059, -0.013147, 1.53803, 0.04861)
+transform = Transform3D(0.997975, -0.0243662, -0.0587487, 0.0029285, 0.940328, -0.340257, 0.0635339, 0.339396, 0.938495, -0.019118, 1.55175, 0.0471726)
bone_name = "Head"
bone_idx = 5
+[node name="PoseWarping" parent="Armature/Skeleton3D" node_paths=PackedStringArray("character_node", "LeftLegIK", "RightLegIK", "orientation_warping_camera_h_object") instance=ExtResource("1_bk0at")]
+debug = true
+character_node = NodePath("../../..")
+LeftLegIK = NodePath("../LeftLegIK")
+RightLegIK = NodePath("../RightLegIK")
+orientation_warping_camera_h_object = NodePath("../../../SpringArm3D")
+orientation_warping_turn_rate = 10.0
+slope_warping_foot_height_offset = 0.1
+
[node name="LeftLegIK" type="SkeletonIK3D" parent="Armature/Skeleton3D"]
process_priority = 1
root_bone = &"LeftUpLeg"
tip_bone = &"LeftFoot"
-use_magnet = true
magnet = Vector3(0.25, 1, 1)
-target_node = NodePath("/root/@EditorNode@17140/@Panel@13/@VBoxContainer@14/@HSplitContainer@17/@HSplitContainer@25/@HSplitContainer@33/@VBoxContainer@34/@VSplitContainer@36/@VSplitContainer@62/@VBoxContainer@63/@PanelContainer@110/MainScreen/@CanvasItemEditor@9462/@VSplitContainer@9281/@HSplitContainer@9283/@HSplitContainer@9285/@Control@9286/@SubViewportContainer@9287/@SubViewport@9288/Character/Armature/Skeleton3D/PoseWarping/LeftIKTarget")
+target_node = NodePath("/root/@EditorNode@16879/@Panel@13/@VBoxContainer@14/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@25/DockVSplitCenter/@VSplitContainer@52/@VBoxContainer@53/@PanelContainer@98/MainScreen/@CanvasItemEditor@9272/@VSplitContainer@9094/@HSplitContainer@9096/@HSplitContainer@9098/@Control@9099/@SubViewportContainer@9100/@SubViewport@9101/Character/Armature/Skeleton3D/PoseWarping/LeftTargetRotation/LeftIKTarget")
[node name="RightLegIK" type="SkeletonIK3D" parent="Armature/Skeleton3D"]
process_priority = 1
root_bone = &"RightUpLeg"
tip_bone = &"RightFoot"
-use_magnet = true
magnet = Vector3(-0.25, 1, 1)
-target_node = NodePath("/root/@EditorNode@17140/@Panel@13/@VBoxContainer@14/@HSplitContainer@17/@HSplitContainer@25/@HSplitContainer@33/@VBoxContainer@34/@VSplitContainer@36/@VSplitContainer@62/@VBoxContainer@63/@PanelContainer@110/MainScreen/@CanvasItemEditor@9462/@VSplitContainer@9281/@HSplitContainer@9283/@HSplitContainer@9285/@Control@9286/@SubViewportContainer@9287/@SubViewport@9288/Character/Armature/Skeleton3D/PoseWarping/RightIKTarget")
-
-[node name="PoseWarping" parent="Armature/Skeleton3D" node_paths=PackedStringArray("character_node", "LeftLegIK", "RightLegIK", "orientation_warping_camera_h_object") instance=ExtResource("1_bk0at")]
-character_node = NodePath("../../..")
-LeftLegIK = NodePath("../LeftLegIK")
-RightLegIK = NodePath("../RightLegIK")
-orientation_warping_camera_h_object = NodePath("../../../SpringArm3D")
+target_node = NodePath("/root/@EditorNode@16879/@Panel@13/@VBoxContainer@14/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@25/DockVSplitCenter/@VSplitContainer@52/@VBoxContainer@53/@PanelContainer@98/MainScreen/@CanvasItemEditor@9272/@VSplitContainer@9094/@HSplitContainer@9096/@HSplitContainer@9098/@Control@9099/@SubViewportContainer@9100/@SubViewport@9101/Character/Armature/Skeleton3D/PoseWarping/RightTargetRotation/RightIKTarget")
[node name="MantleComponent" parent="Armature/Skeleton3D" node_paths=PackedStringArray("character_collision_shape", "character_node", "animation_tree") instance=ExtResource("28_6ac02")]
character_collision_shape = NodePath("../../../CollisionShape3D")
diff --git a/AMSG_Examples/Maps/LevelManager.gd b/AMSG_Examples/Maps/LevelManager.gd
index 670f328..c8ae558 100644
--- a/AMSG_Examples/Maps/LevelManager.gd
+++ b/AMSG_Examples/Maps/LevelManager.gd
@@ -156,7 +156,3 @@ func create_player(id: int) -> void:
func destroy_player(id: int) -> void:
find_child(str(id),true,false).queue_free()
-
-
-
-
diff --git a/AMSG_Examples/Maps/MovementTestMap.tscn b/AMSG_Examples/Maps/MovementTestMap.tscn
index a1e373f..90d1ea3 100644
--- a/AMSG_Examples/Maps/MovementTestMap.tscn
+++ b/AMSG_Examples/Maps/MovementTestMap.tscn
@@ -101,9 +101,9 @@ transform = Transform3D(1, 0, 0, 0, -0.996865, 0.0791203, 0, -0.0791203, -0.9968
[node name="Stairs" type="Node3D" parent="."]
[node name="CSGBox3D8" type="CSGBox3D" parent="Stairs"]
-transform = Transform3D(-0.999963, -0.00595152, -0.00617832, -0.0059514, 0.999982, -3.67712e-05, 0.00617843, 0, -0.99998, -1.42272, 1.61775, 1.38929)
+transform = Transform3D(-0.999963, -0.00595152, -0.00617832, -0.0059514, 0.999982, -3.67712e-05, 0.00617843, 0, -0.99998, -0.113655, 1.61365, 1.39355)
use_collision = true
-size = Vector3(0.392448, 0.135761, 14.107)
+size = Vector3(1.77032, 0.135761, 14.107)
material = ExtResource("3_27oba")
[node name="CSGBox3D9" type="CSGBox3D" parent="Stairs"]
diff --git a/AMSG_Examples/Player/Player.tscn b/AMSG_Examples/Player/Player.tscn
index c8ddc06..6871d02 100644
--- a/AMSG_Examples/Player/Player.tscn
+++ b/AMSG_Examples/Player/Player.tscn
@@ -55,9 +55,11 @@ sync = true
xfade_time = 0.1
input_0/name = "Forward"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Backward"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_m0htu"]
@@ -71,18 +73,23 @@ sync = true
xfade_time = 0.2
input_0/name = "Idle"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Walk"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
input_2/name = "Run"
input_2/auto_advance = false
+input_2/break_loop_at_end = false
input_2/reset = true
input_3/name = "Jog"
input_3/auto_advance = false
+input_3/break_loop_at_end = false
input_3/reset = true
input_4/name = "Stop"
input_4/auto_advance = false
+input_4/break_loop_at_end = false
input_4/reset = true
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_81j80"]
@@ -98,9 +105,11 @@ sync = true
xfade_time = 0.1
input_0/name = "Forward"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Backward"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_bmtvy"]
@@ -111,9 +120,11 @@ sync = true
xfade_time = 0.3
input_0/name = "stand"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "crouch"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeTransition" id="AnimationNodeTransition_rufvy"]
@@ -121,13 +132,15 @@ sync = true
xfade_time = 0.2
input_0/name = "Idle"
input_0/auto_advance = false
+input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "Walk"
input_1/auto_advance = false
+input_1/break_loop_at_end = false
input_1/reset = true
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_ml0kl"]
-graph_offset = Vector2(-623.521, -192.6)
+graph_offset = Vector2(-638.943, -75.3344)
nodes/CrouchIdle/node = SubResource("AnimationNodeAnimation_urp0s")
nodes/CrouchIdle/position = Vector2(-380, 640)
nodes/CrouchWalkingForward/node = SubResource("AnimationNodeAnimation_ei4oj")
@@ -162,6 +175,7 @@ node_connections = [&"JogFB", 0, &"JogForward", &"JogFB", 1, &"JogBackward", &"S
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_jqd3m"]
resource_local_to_scene = true
+graph_offset = Vector2(253.952, 805.454)
nodes/AnimTurnLeft/node = SubResource("AnimationNodeAnimation_mb2kt")
nodes/AnimTurnLeft/position = Vector2(500, 1540)
nodes/AnimTurnRight/node = SubResource("AnimationNodeAnimation_2rfjg")
@@ -236,7 +250,7 @@ stamina_energy_consumption = 15.0
stamina_attribute = NodePath("../AttributesManager/StaminaAttribute")
networking = NodePath("../Networking")
targeting_component = NodePath("../TargetingComponent")
-deacceleration = 5.0
+deacceleration = 10.0
[node name="LockSystem" type="Node" parent="." index="6"]
script = ExtResource("11_06pi7")
@@ -257,105 +271,75 @@ networking = NodePath("../Networking")
[node name="AnimationTree" parent="." index="10"]
tree_root = SubResource("AnimationNodeBlendTree_jqd3m")
-parameters/VelocityDirection/JogFB/current_state = ""
-parameters/VelocityDirection/JogFB/current_index = -1
-parameters/VelocityDirection/Standing/current_state = ""
-parameters/VelocityDirection/Standing/current_index = -1
-parameters/VelocityDirection/WalkFB/current_state = ""
-parameters/VelocityDirection/WalkFB/current_index = -1
-parameters/VelocityDirection/crouching/current_state = ""
-parameters/VelocityDirection/crouching/current_index = -1
-
-[node name="CollisionShape3D" parent="." index="11"]
+parameters/VelocityDirection/Standing/current_state = "Idle"
+parameters/VelocityDirection/Standing/current_index = 0
+
+[node name="CollisionShape3D" parent="." index="12"]
shape = SubResource("CapsuleShape3D_jrjkm")
[node name="Skeleton3D" parent="Armature" index="0"]
-bones/0/position = Vector3(-0.000172998, 0.901879, -0.00179914)
-bones/0/rotation = Quaternion(0.0129103, -0.477019, 0.0128396, 0.878704)
-bones/1/rotation = Quaternion(-0.034878, 0.0121777, 0.00603897, 0.999299)
-bones/2/rotation = Quaternion(0.00771038, 0.00387442, 0.0077534, 0.999933)
-bones/3/rotation = Quaternion(0.0679804, 0.00466348, 0.00750769, 0.997648)
-bones/4/rotation = Quaternion(0.259049, 0.120367, -0.0335045, 0.957749)
-bones/5/rotation = Quaternion(-0.00246286, 0.223138, -0.172693, 0.959365)
-bones/9/rotation = Quaternion(-0.465919, -0.528453, 0.588414, -0.396769)
-bones/10/rotation = Quaternion(0.520746, -0.203354, 0.188978, 0.807315)
-bones/11/rotation = Quaternion(9.19054e-05, 0.0274316, 0.655564, 0.754641)
-bones/12/rotation = Quaternion(-0.0908578, 0.331043, 0.131266, 0.930013)
-bones/13/rotation = Quaternion(0.68532, -6.03681e-05, -0.0820378, 0.723606)
-bones/14/rotation = Quaternion(0.816783, -0.000611766, -0.0982718, 0.568513)
-bones/15/rotation = Quaternion(0.818243, 0.00110579, -0.0972425, 0.566587)
-bones/17/rotation = Quaternion(0.217917, 0.0898311, 0.175515, 0.955844)
-bones/18/rotation = Quaternion(0.111987, -0.158249, -0.280048, 0.940207)
-bones/19/rotation = Quaternion(-0.0215223, -0.07977, -0.565562, 0.820556)
-bones/21/rotation = Quaternion(0.680469, 0.00849827, -0.0898124, 0.727203)
-bones/22/rotation = Quaternion(0.845186, -0.00222601, -0.10257, 0.524533)
-bones/23/rotation = Quaternion(0.811299, 0.00123152, -0.096296, 0.576645)
-bones/25/rotation = Quaternion(0.70653, -0.0227113, -0.0611423, 0.704671)
-bones/26/rotation = Quaternion(0.796127, -0.00109192, -0.096178, 0.597436)
-bones/27/rotation = Quaternion(0.787005, 0.00064355, -0.0937785, 0.609778)
-bones/29/rotation = Quaternion(0.734984, -0.0394802, -0.050487, 0.675049)
-bones/30/rotation = Quaternion(0.753528, 0.0265116, -0.0681514, 0.653336)
-bones/31/rotation = Quaternion(0.882855, 0.000936385, -0.105273, 0.457695)
-bones/33/rotation = Quaternion(0.502236, -0.498063, 0.599458, 0.374623)
-bones/34/rotation = Quaternion(0.370554, -0.0482472, -0.469022, 0.800238)
-bones/35/rotation = Quaternion(0.000238858, -0.0366692, -0.862701, 0.504384)
-bones/36/rotation = Quaternion(-0.113264, 0.1314, -0.0768276, 0.981836)
-bones/37/rotation = Quaternion(0.685333, 6.17094e-05, 0.0827409, 0.723514)
-bones/38/rotation = Quaternion(0.81459, 0.000966602, 0.0990885, 0.571511)
-bones/39/rotation = Quaternion(0.821818, -0.0017916, 0.0979961, 0.561256)
-bones/41/rotation = Quaternion(0.258103, -0.0464722, -0.166247, 0.950571)
-bones/42/rotation = Quaternion(0.0971873, -0.0337892, 0.319316, 0.942046)
-bones/43/rotation = Quaternion(0.102353, 0.051128, 0.496662, 0.86037)
-bones/45/rotation = Quaternion(0.68078, -0.0190739, 0.101264, 0.725204)
-bones/46/rotation = Quaternion(0.853091, 0.000644792, 0.103455, 0.511402)
-bones/47/rotation = Quaternion(0.803307, 7.36886e-05, 0.0971108, 0.587595)
-bones/49/rotation = Quaternion(0.723188, 0.0327217, 0.0549051, 0.687687)
-bones/50/rotation = Quaternion(0.758867, 0.00171341, 0.0930925, 0.644555)
-bones/51/rotation = Quaternion(0.799428, -0.002656, 0.0944829, 0.59328)
-bones/53/rotation = Quaternion(0.738816, 0.0655906, 0.0273769, 0.670149)
-bones/54/rotation = Quaternion(0.747741, 0.00140453, 0.0915433, 0.657648)
-bones/55/rotation = Quaternion(0.885414, -0.00156687, 0.10615, 0.452518)
-bones/57/rotation = Quaternion(-0.126738, 0.140515, 0.969622, 0.155006)
-bones/58/rotation = Quaternion(-0.378447, -0.0320807, -0.00808686, 0.925032)
-bones/59/rotation = Quaternion(0.629739, 0.0424758, 0.115003, 0.767072)
-bones/60/rotation = Quaternion(0.340454, 0.0167316, 0.00602515, 0.940093)
-bones/62/rotation = Quaternion(0.156635, 0.280779, 0.931659, -0.169234)
-bones/63/rotation = Quaternion(-0.307456, 0.043324, -0.0155887, 0.950448)
-bones/64/rotation = Quaternion(0.442158, -0.046071, -0.0947431, 0.890729)
-bones/65/rotation = Quaternion(0.352065, -0.016805, -0.00581727, 0.935807)
+bones/0/position = Vector3(0.000454078, 0.928049, -0.00899249)
+bones/0/rotation = Quaternion(-0.0360241, -0.36772, -0.0121267, 0.929159)
+bones/1/rotation = Quaternion(-0.0105309, 0.0399228, -0.0061335, 0.999128)
+bones/2/rotation = Quaternion(0.0994243, 0.0809758, -0.00835797, 0.99171)
+bones/3/rotation = Quaternion(0.159936, 0.0802559, -0.0134035, 0.983768)
+bones/4/rotation = Quaternion(0.112829, -0.0103584, 0.00273539, 0.993557)
+bones/5/rotation = Quaternion(-0.0283913, 0.163325, -0.0678375, 0.983828)
+bones/9/rotation = Quaternion(-0.4959, -0.51471, 0.572249, -0.402104)
+bones/10/rotation = Quaternion(0.517184, -0.0859803, 0.14523, 0.839069)
+bones/11/rotation = Quaternion(-0.0120754, 0.088687, 0.440104, 0.893475)
+bones/12/rotation = Quaternion(-0.101813, 0.118644, -0.00737522, 0.987676)
+bones/13/rotation = Quaternion(0.125687, 0.00591213, -0.0846781, 0.988432)
+bones/14/rotation = Quaternion(0.190471, -0.00131661, 0.0144138, 0.981586)
+bones/15/rotation = Quaternion(5.537e-09, -1.56462e-07, 7.97777e-06, 1)
+bones/17/rotation = Quaternion(0.285144, 0.111788, 0.192062, 0.932367)
+bones/18/rotation = Quaternion(-0.0079141, 0.0012289, -0.000708193, 0.999968)
+bones/19/rotation = Quaternion(-6.10948e-07, -5.22193e-06, -9.81533e-06, 1)
+bones/21/rotation = Quaternion(0.0314441, -0.00550813, 0.0612125, 0.997614)
+bones/22/rotation = Quaternion(0.143628, -0.000730686, -0.00676708, 0.989608)
+bones/23/rotation = Quaternion(1.89462e-06, -1.9595e-06, -1.62399e-07, 1)
+bones/25/rotation = Quaternion(0.265273, -0.0137117, -0.129575, 0.955329)
+bones/26/rotation = Quaternion(0.27607, 0.00167089, 0.0244024, 0.960826)
+bones/27/rotation = Quaternion(-1.6953e-08, -1.04308e-07, 3.06626e-06, 1)
+bones/29/rotation = Quaternion(0.291277, -0.0144766, -0.162445, 0.942635)
+bones/30/rotation = Quaternion(0.336913, 0.0112404, 0.0499064, 0.940145)
+bones/31/rotation = Quaternion(2.01584e-06, -2.01911e-06, 9.92743e-06, 1)
+bones/33/rotation = Quaternion(0.545941, -0.476698, 0.539935, 0.427993)
+bones/34/rotation = Quaternion(0.505778, 0.0934148, 0.0767134, 0.854153)
+bones/35/rotation = Quaternion(0.0500849, -0.0446623, -0.426055, 0.902205)
+bones/36/rotation = Quaternion(0.106721, -0.0251789, -0.0684703, 0.991609)
+bones/37/rotation = Quaternion(0.110532, 0.00839432, 0.0252027, 0.993518)
+bones/38/rotation = Quaternion(0.266578, 0.00141572, -0.0173295, 0.963657)
+bones/41/rotation = Quaternion(0.203086, 0.0243983, -0.226341, 0.952329)
+bones/42/rotation = Quaternion(0.00526236, 0.00140206, 0.182551, 0.983181)
+bones/43/rotation = Quaternion(1.69501e-06, 4.45172e-06, 1.02064e-05, 1)
+bones/45/rotation = Quaternion(0.0392521, 0.0100325, 0.00893639, 0.999139)
+bones/46/rotation = Quaternion(0.146719, 0.000159293, 0.00972202, 0.98913)
+bones/47/rotation = Quaternion(-2.49988e-07, -1.93715e-07, 2.5981e-07, 1)
+bones/49/rotation = Quaternion(0.188712, -0.00840324, 0.0671019, 0.979701)
+bones/50/rotation = Quaternion(0.321808, -0.00236791, -0.0343173, 0.94618)
+bones/51/rotation = Quaternion(-3.47811e-06, -3.27826e-06, -3.25148e-06, 1)
+bones/53/rotation = Quaternion(0.208347, -0.0111405, 0.0916694, 0.973686)
+bones/54/rotation = Quaternion(0.35061, -0.0122601, -0.0691607, 0.933884)
+bones/55/rotation = Quaternion(2.05328e-08, 0, -1.09167e-05, 1)
+bones/57/rotation = Quaternion(-0.124009, 0.0272205, 0.983629, 0.127887)
+bones/58/rotation = Quaternion(-0.309852, 0.0738317, -0.0196879, 0.947709)
+bones/59/rotation = Quaternion(0.600693, 0.0604788, 0.111599, 0.789339)
+bones/60/rotation = Quaternion(0.354073, 0.0197564, 0.00431106, 0.934999)
+bones/62/rotation = Quaternion(0.0782759, 0.218128, 0.966907, -0.106695)
+bones/63/rotation = Quaternion(-0.310017, 0.12142, -0.0393272, 0.942125)
+bones/64/rotation = Quaternion(0.486484, -0.0231724, -0.04207, 0.872369)
+bones/65/rotation = Quaternion(0.359453, -0.00152117, -0.0299039, 0.932683)
[node name="HeadBone" parent="Armature/Skeleton3D" index="2"]
-transform = Transform3D(0.990253, -0.111666, -0.0832491, 0.0474898, 0.832572, -0.551877, 0.130937, 0.542544, 0.82976, -0.0634186, 1.48843, 0.0344127)
-
-[node name="LeftIKTarget" parent="Armature/Skeleton3D/PoseWarping" index="0"]
-transform = Transform3D(-0.776967, -0.466155, -0.423109, -0.0355596, -0.638521, 0.768783, -0.628536, 0.612365, 0.479534, 0.0839237, 0.104959, 0.362222)
-
-[node name="RightIKTarget" parent="Armature/Skeleton3D/PoseWarping" index="1"]
-transform = Transform3D(-0.303158, -0.739914, -0.600519, 0.0355596, -0.638519, 0.768784, -0.952277, 0.211709, 0.219883, -0.0315955, 0.104958, -0.310727)
-
-[node name="LeftFootAttachment" parent="Armature/Skeleton3D/PoseWarping" index="2"]
-transform = Transform3D(-0.776963, -0.466153, -0.423106, -0.0355594, -0.638517, 0.768778, -0.628532, 0.612361, 0.479531, 0.0840908, 0.111218, 0.361871)
-external_skeleton = NodePath("/root/@EditorNode@17140/@Panel@13/@VBoxContainer@14/@HSplitContainer@17/@HSplitContainer@25/@HSplitContainer@33/@VBoxContainer@34/@VSplitContainer@36/@VSplitContainer@62/@VBoxContainer@63/@PanelContainer@110/MainScreen/@CanvasItemEditor@9462/@VSplitContainer@9281/@HSplitContainer@9283/@HSplitContainer@9285/@Control@9286/@SubViewportContainer@9287/@SubViewport@9288/Character/Armature/Skeleton3D")
-
-[node name="RightFootAttachment" parent="Armature/Skeleton3D/PoseWarping" index="3"]
-transform = Transform3D(-0.303158, -0.739914, -0.600519, 0.0355596, -0.638519, 0.768784, -0.952277, 0.211709, 0.219883, -0.0313653, 0.102962, -0.312327)
-external_skeleton = NodePath("/root/@EditorNode@17140/@Panel@13/@VBoxContainer@14/@HSplitContainer@17/@HSplitContainer@25/@HSplitContainer@33/@VBoxContainer@34/@VSplitContainer@36/@VSplitContainer@62/@VBoxContainer@63/@PanelContainer@110/MainScreen/@CanvasItemEditor@9462/@VSplitContainer@9281/@HSplitContainer@9283/@HSplitContainer@9285/@Control@9286/@SubViewportContainer@9287/@SubViewport@9288/Character/Armature/Skeleton3D")
-
-[node name="LeftLegRayCast" parent="Armature/Skeleton3D/PoseWarping" index="4"]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0840908, 0.361218, 0.361871)
-
-[node name="RightLegRayCast" parent="Armature/Skeleton3D/PoseWarping" index="5"]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0313653, 0.352962, -0.312327)
+transform = Transform3D(0.997719, -0.066021, 0.0140806, 0.0626208, 0.82726, -0.558319, 0.0252124, 0.557927, 0.829507, -0.0260333, 1.49499, 0.111984)
[node name="flashlight" parent="Armature" index="1" instance=ExtResource("5_euvsl")]
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.12407, 0.156779)
light_energy = 10.0
-[node name="Camera" parent="SpringArm3D" index="0"]
-current = true
-
-[node name="TargetRayCast" type="RayCast3D" parent="SpringArm3D/Camera" index="1"]
-target_position = Vector3(0, 0, -10)
+[node name="AnimationPlayer" parent="." index="14"]
+playback_default_blend_time = 0.2
[node name="Status" type="Control" parent="." index="16" node_paths=PackedStringArray("camera_root")]
layout_mode = 3
@@ -364,6 +348,8 @@ anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
script = ExtResource("6_8h4hk")
camera_root = NodePath("../CameraComponent")
@@ -441,39 +427,56 @@ horizontal_alignment = 1
vertical_alignment = 1
[node name="RichTextLabel" type="RichTextLabel" parent="Status" index="6"]
-visible = false
+clip_contents = false
layout_mode = 0
offset_left = 29.0
offset_top = 354.0
offset_right = 400.0
-offset_bottom = 803.0
-text = " Controls
+offset_bottom = 618.0
+bbcode_enabled = true
+text = "[center]Controls[/center]
(W,A,S,D) Move In The Four Directions
-
-(Shift) Sprint
-
+(Shift) Run
+(Double Shift) Sprint
(C) Long Press : Switch First/Third Person View
-
(C) One Press : Switch Camera Angle (Right Shoulder,Left Shoulder,Head(Center) )
-
(Space) Jump
-
(CTRL) Crouch/UnCrouch
-
-(Q) Run (Temporarily)
-
(F) Interaction
-
-(L) Flashlight"
-
-[node name="HealthBar" type="ProgressBar" parent="Status" index="7"]
+(L) Flashlight
+(P) Pause
+(I) Debug
+(K) Switch Distance Matching
+(N) Show/Hide This Panel
+(1) Enable 3D Debug"
+fit_content = true
+scroll_active = false
+
+[node name="RichTextLabel2" type="RichTextLabel" parent="Status" index="7"]
+clip_contents = false
+layout_mode = 1
+anchors_preset = 5
+anchor_left = 0.5
+anchor_right = 0.5
+offset_left = -133.5
+offset_right = 133.5
+offset_bottom = 69.0
+grow_horizontal = 2
+bbcode_enabled = true
+text = "3D Debug Enabled: [color=green]True[/color]
+Instructions Visible: [color=green]True[/color]
+Distance Matching Enabled: [color=green]True[/color]"
+fit_content = true
+scroll_active = false
+
+[node name="HealthBar" type="ProgressBar" parent="Status" index="8"]
layout_mode = 0
offset_right = 284.0
offset_bottom = 11.0
theme_override_styles/fill = SubResource("StyleBoxFlat_4jtp6")
show_percentage = false
-[node name="StaminaBar" type="ProgressBar" parent="Status" index="8"]
+[node name="StaminaBar" type="ProgressBar" parent="Status" index="9"]
layout_mode = 0
offset_top = 23.0
offset_right = 284.0
@@ -482,7 +485,7 @@ theme_override_styles/background = SubResource("StyleBoxFlat_agyl7")
theme_override_styles/fill = SubResource("StyleBoxFlat_ueab0")
show_percentage = false
-[node name="PauseText" type="Label" parent="Status" index="9"]
+[node name="PauseText" type="Label" parent="Status" index="10"]
visible = false
layout_mode = 1
anchors_preset = 8
@@ -500,6 +503,10 @@ text = "Character locked. Press P to unlock."
horizontal_alignment = 1
vertical_alignment = 1
-[connection signal="Lock_Status_Changed" from="LockSystem" to="Status/PauseText" method="set_visible"]
+[node name="Camera" parent="SpringArm3D" index="0"]
+current = true
-[editable path="Armature/Skeleton3D/PoseWarping"]
+[node name="TargetRayCast" type="RayCast3D" parent="SpringArm3D/Camera" index="1"]
+target_position = Vector3(0, 0, -10)
+
+[connection signal="Lock_Status_Changed" from="LockSystem" to="Status/PauseText" method="set_visible"]
diff --git a/AMSG_Examples/Player/PlayerController.gd b/AMSG_Examples/Player/PlayerController.gd
old mode 100755
new mode 100644
index 08749cf..85ef5ba
--- a/AMSG_Examples/Player/PlayerController.gd
+++ b/AMSG_Examples/Player/PlayerController.gd
@@ -50,8 +50,6 @@ func _physics_process(delta):
return
if lock_system != null && lock_system.is_locked:
- direction = Vector3.ZERO
- character_component.add_movement_input()
return
#------------------ Input Movement ------------------#
@@ -69,9 +67,6 @@ func _physics_process(delta):
character_component.add_movement_input(direction, character_component.current_movement_data.run_speed,character_component.current_movement_data.run_acceleration)
else:
character_component.add_movement_input(direction, character_component.current_movement_data.walk_speed,character_component.current_movement_data.walk_acceleration)
- else:
- direction = Vector3.ZERO
- character_component.add_movement_input()
#------------------ Input Crouch ------------------#
@@ -133,11 +128,22 @@ func _physics_process(delta):
if Input.is_action_just_pressed("interaction"):
character_component.camera_root.Camera.get_node("InteractionRaycast").Interact()
+ if Input.is_action_just_pressed("show_debug"):
+ pass
+ if Input.is_action_just_pressed("switch_distance_matching"):
+ character_component.pose_warping_active = !character_component.pose_warping_active
-
-
+
var view_changed_recently = false
func _input(event):
+ if !Engine.is_editor_hint():
+ if Input.is_key_pressed(KEY_1):
+ DebugDraw3D.debug_enabled = !DebugDraw3D.debug_enabled
+ if Input.is_key_pressed(KEY_2):
+ DebugDraw2D.debug_enabled = !DebugDraw2D.debug_enabled
+ #if Input.is_key_pressed(KEY_3):
+ #DebugDrawManager.debug_enabled = !DebugDrawManager.debug_enabled
+
if event is InputEventMouseMotion:
if !character_component or !controls_the_possessed_character:
return
diff --git a/AMSG_Examples/Player/Status.gd b/AMSG_Examples/Player/Status.gd
old mode 100755
new mode 100644
index fc86db4..824ba0f
--- a/AMSG_Examples/Player/Status.gd
+++ b/AMSG_Examples/Player/Status.gd
@@ -1,11 +1,14 @@
extends Control
+@onready var character_movement_component = $"../CharacterMovementComponent"
@export var camera_root : CameraComponent
@onready var player = get_parent()
@onready var direction = $Control/Direction
@onready var velocity = $Control/Velocity
@onready var mesh = $Control/mesh
-
+@onready var rich_text_label = $RichTextLabel
+@onready var rich_text_label_2 = $RichTextLabel2
+var debug_text : String = ""
func _physics_process(_delta):
visible = camera_root.Camera.current
var h_rot = get_parent().get_node("SpringArm3D").transform.basis.get_euler().y
@@ -14,3 +17,13 @@ func _physics_process(_delta):
# direction.rotation = atan2(player.direction.z, player.direction.x)
velocity.position = Vector2(character_node_velocity.x, character_node_velocity.z) * 10
mesh.rotation = 90-get_node("../Armature").rotation.y - player.rotation.y - .5
+ if Input.is_action_just_pressed("show_panel"):
+ rich_text_label.visible = !rich_text_label.visible
+ debug_text = ""
+ debug_text += "3D_Debug_Enabled:[color="+true_false_text_color(DebugDraw3D.debug_enabled)+"]" + str(DebugDraw3D.debug_enabled) +"[/color] "
+ debug_text += "Instructions_Visible:[color="+true_false_text_color(rich_text_label.visible)+"]" + str(rich_text_label.visible) +"[/color] "
+ debug_text += "Distance_Matching_Enabled:[color="+true_false_text_color(character_movement_component.pose_warping_active)+"]" + str(character_movement_component.pose_warping_active) +"[/color]"
+ rich_text_label_2.text = debug_text
+
+func true_false_text_color(state:bool) -> String:
+ return "green" if state else "red"
diff --git a/README.md b/README.md
index 7523dc5..46a6589 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
The Project is made using [Godot](https://github.com/godotengine/godot) 4
-you can get Godot 4.2 Stable here : https://godotengine.org/
+you can get Godot 4.3 Stable here : https://godotengine.org/
### Watch this video for preview :
diff --git a/addons/AMSG/AI/AI_Base.gd b/addons/AMSG/AI/AI_Base.gd
old mode 100755
new mode 100644
index 1a8ecf0..0dbd1e7
--- a/addons/AMSG/AI/AI_Base.gd
+++ b/addons/AMSG/AI/AI_Base.gd
@@ -32,4 +32,3 @@ func _physics_process(delta):
ik_look_at(-$CameraRoot/SpringArm3D.transform.basis.z * 2.0 + Vector3(0.0,1.5,0.0))
Global.rotation_mode.aiming:
ik_look_at(-$CameraRoot/SpringArm3D.transform.basis.z * 2.0 + Vector3(0.0,1.5,0.0))
-
diff --git a/addons/AMSG/Components/AnimationComponents/AnimationBlend.gd b/addons/AMSG/Components/AnimationComponents/AnimationBlend.gd
index 331d459..0aad05f 100644
--- a/addons/AMSG/Components/AnimationComponents/AnimationBlend.gd
+++ b/addons/AMSG/Components/AnimationComponents/AnimationBlend.gd
@@ -54,15 +54,11 @@ func _physics_process(_delta):
#On Stopped
if !(Input.is_action_pressed("forward") || Input.is_action_pressed("back") || Input.is_action_pressed("right") || Input.is_action_pressed("left")) and (Input.is_action_just_released("right") || Input.is_action_just_released("back") || Input.is_action_just_released("left") || Input.is_action_just_released("forward")):
-
- var seek_time = 0.1#get_node(anim_player).get_animation(tree_root.get_node("VelocityDirection").get_node("StopAnim").animation).length - movement_script.pose_warping_instance.CalculateStopTime((movement_script.actual_velocity * Vector3(1.0,0.0,1.0)),movement_script.deacceleration * movement_script.input_direction)
+ movement_script.pose_warping.CalculateStopLocation(movement_script.deacceleration)
+ var seek_time = 0.0#get_node(anim_player).get_animation(tree_root.get_node("VelocityDirection").get_node("StopAnim").animation).length - movement_script.pose_warping_instance.CalculateStopTime((movement_script.actual_velocity * Vector3(1.0,0.0,1.0)),movement_script.deacceleration * movement_script.input_direction)
set("parameters/VelocityDirection/StopSeek/seek_position",seek_time)
if !movement_script.input_is_moving:
set("parameters/VelocityDirection/Standing/transition_request","Stop")
#Rotate In Place
set("parameters/Turn/blend_amount" , 1 if movement_script.is_rotating_in_place else 0)
set("parameters/RightOrLeft/blend_amount" ,0 if movement_script.rotation_difference_camera_mesh > 0 else 1)
-
-
-
-
diff --git a/addons/AMSG/Components/AttributesComponent/AttributesManager.gd b/addons/AMSG/Components/AttributesComponent/AttributesManager.gd
old mode 100755
new mode 100644
index 94fd390..3e9af25
--- a/addons/AMSG/Components/AttributesComponent/AttributesManager.gd
+++ b/addons/AMSG/Components/AttributesComponent/AttributesManager.gd
@@ -10,5 +10,3 @@ func _ready():
if !(child is GameAttribute):
assert("Only GameAttribute childs are allowed")
attributes[child.attribute_name] = child
-
-
diff --git a/addons/AMSG/Components/CharacterMovementComponent.gd b/addons/AMSG/Components/CharacterMovementComponent.gd
index a57500d..2585368 100644
--- a/addons/AMSG/Components/CharacterMovementComponent.gd
+++ b/addons/AMSG/Components/CharacterMovementComponent.gd
@@ -66,7 +66,8 @@ var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity")
@export var max_stair_climb_height : float = 0.5
## the distance to the stair that the script will start detecting it
-@export var max_close_stair_distance : float = 0.75
+@export var max_close_stair_distance : float = 0.5
+@export var stair_collision_shape_3d: CollisionShape3D
@export var roll_magnitude := 17.0
@@ -298,13 +299,19 @@ func _ready():
update_animations()
update_character_movement()
+
+ stair_collision_shape_3d.shape.length = max_stair_climb_height
+ stair_collision_shape_3d.position.y = max_stair_climb_height
func _process(delta):
calc_animation_data()
- pose_warping.character_velocity = actual_velocity
-
+var pose_warping_active : bool = true
func _physics_process(delta):
+ set_movement_info()
+ apply_deacceleration()
+ pose_warping.stride_warping_enable = pose_warping_active
+ pose_warping.slope_warping_enable = pose_warping_active
#Debug()
#
aim_rate_h = abs((camera_root.HObject.rotation.y - previous_aim_rate_h) / delta)
@@ -315,8 +322,6 @@ func _physics_process(delta):
Global.movement_state.none:
pass
Global.movement_state.grounded:
- pose_warping.stride_warping_enable = true
- pose_warping.slope_warping_enable = true
#------------------ Rotate Character Mesh ------------------#
match movement_action:
Global.movement_action.none:
@@ -341,8 +346,6 @@ func _physics_process(delta):
smooth_character_rotation(input_acceleration ,2.0,delta)
Global.movement_state.in_air:
- pose_warping.stride_warping_enable = false
- pose_warping.slope_warping_enable = false
#------------------ Rotate Character Mesh In Air ------------------#
if mantle_component and !mantle_component.is_climbing:
match rotation_mode:
@@ -383,9 +386,6 @@ func _physics_process(delta):
if character_node is CharacterBody3D and character_node.is_on_ceiling():
vertical_velocity.y = 0
- #------------------ Stair climb ------------------#
- #stair movement must happen after gravity so it can override in air status
- stair_move()
func crouch_update(delta):
var direct_state = character_node.get_world_3d().direct_space_state
@@ -414,43 +414,12 @@ func crouch_update(delta):
collision_shape_ref.shape.height = clamp(collision_shape_ref.shape.height,crouch_height,default_height)
-func stair_move():
- var direct_state = character_node.get_world_3d().direct_space_state
- var obs_ray_info : PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
- obs_ray_info.exclude = [RID(character_node)]
- obs_ray_info.from = mesh_ref.global_transform.origin
- if movement_direction:
- obs_ray_info.to = obs_ray_info.from + Vector3(0, 0, max_close_stair_distance).rotated(Vector3.UP,movement_direction)
-
- #this is used to know if there is obstacle
- var first_collision = direct_state.intersect_ray(obs_ray_info)
- if first_collision and input_is_moving:
- var climb_ray_info : PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
- climb_ray_info.exclude = [RID(character_node)]
- climb_ray_info.from = first_collision.collider.global_position + Vector3(0, max_stair_climb_height, 0)
- climb_ray_info.to = first_collision.collider.global_position
- var stair_top_collision = direct_state.intersect_ray(climb_ray_info)
- if stair_top_collision:
- if stair_top_collision.position.y - character_node.global_position.y > 0 and stair_top_collision.position.y - character_node.global_position.y < 0.15:
- movement_state = Global.movement_state.grounded
- is_moving_on_stair = true
- character_node.position.y += stair_top_collision.position.y - character_node.global_position.y
- character_node.global_position += Vector3(0, 0, 0.01).rotated(Vector3.UP,movement_direction)
- else:
- await get_tree().create_timer(0.4).timeout
- is_moving_on_stair = false
- else:
- await get_tree().create_timer(0.4).timeout
- is_moving_on_stair = false
- else:
- await get_tree().create_timer(0.4).timeout
- is_moving_on_stair = false
-
func smooth_character_rotation(Target:Vector3,nodelerpspeed,delta):
mesh_ref.rotation.y = lerp_angle(mesh_ref.rotation.y, atan2(Target.x,Target.z) , delta * nodelerpspeed)
-
+ stair_collision_shape_3d.position.x = Target.normalized().x * max_close_stair_distance
+ stair_collision_shape_3d.position.z = Target.normalized().z * max_close_stair_distance
func set_bone_x_rotation(skeleton,bone_name, x_rot,CharacterRootNode):
var bone = skeleton.find_bone(bone_name)
@@ -500,49 +469,37 @@ func ik_look_at(position: Vector3):
lookatobject.position = position
-var PrevVelocity :Vector3
-
+var prev_velocity :Vector3
+var current_max_speed : float
## Adds input to move the character, should be called when Idle too, to execute deacceleration for CharacterBody3D or reset velocity for RigidBody3D.
## when Idle speed and direction should be passed as 0, and deacceleration passed, or leave them empty.
-func add_movement_input(direction: Vector3 = Vector3.ZERO, Speed: float = 0, Acceleration: float = deacceleration if character_node is CharacterBody3D else 0) -> void:
+func add_movement_input(p_direction: Vector3 = Vector3.ZERO, p_speed: float = 0, Acceleration: float = deacceleration if character_node is CharacterBody3D else 0) -> void:
if mantle_component and mantle_component.is_climbing:
return
- var max_speed : float = Speed
- input_direction = direction
-
+ current_max_speed = p_speed
+ input_direction = p_direction
+ input_acceleration = Acceleration * input_direction * (1 if current_max_speed != 0 else -1)
if character_node is RigidBody3D:
if is_flying == false:
- velocity.x = direction.x * Acceleration * character_node.mass * get_physics_process_delta_time()
- velocity.z = direction.z * Acceleration * character_node.mass * get_physics_process_delta_time()
+ velocity.x = p_direction.x * Acceleration * character_node.mass * get_physics_process_delta_time()
+ velocity.z = p_direction.z * Acceleration * character_node.mass * get_physics_process_delta_time()
else:
- velocity = direction * Acceleration * character_node.mass * get_physics_process_delta_time()
+ velocity = p_direction * Acceleration * character_node.mass * get_physics_process_delta_time()
if is_inf(character_node.linear_velocity.length()):
character_node.linear_velocity = velocity
- if character_node.linear_velocity.length() > max_speed:
- velocity = direction
+ if character_node.linear_velocity.length() > current_max_speed:
+ velocity = p_direction
character_node.apply_central_impulse(velocity)
if character_node is CharacterBody3D:
if is_flying == false:
- character_node.velocity.x = lerp(character_node.velocity.x,(direction*max_speed).x,Acceleration/(max_speed if max_speed != 0 else (abs(character_node.velocity.x) if character_node.velocity.x != 0 else 1.0))*get_physics_process_delta_time())
- character_node.velocity.z = lerp(character_node.velocity.z,(direction*max_speed).z,Acceleration/(max_speed if max_speed != 0 else (abs(character_node.velocity.z) if character_node.velocity.z != 0 else 1.0))*get_physics_process_delta_time())
+ character_node.velocity.x = lerp(character_node.velocity.x,(p_direction*current_max_speed).x,Acceleration/(current_max_speed if current_max_speed != 0 else 1.0)*get_physics_process_delta_time())
+ character_node.velocity.z = lerp(character_node.velocity.z,(p_direction*current_max_speed).z,Acceleration/(current_max_speed if current_max_speed != 0 else 1.0)*get_physics_process_delta_time())
else:
- character_node.velocity = character_node.velocity.lerp((direction*max_speed),Acceleration/(max_speed if max_speed != 0 else character_node.velocity.x if character_node.velocity.x != 0 else 1.0)*get_physics_process_delta_time())
+ character_node.velocity = character_node.velocity.lerp((p_direction*current_max_speed),Acceleration/(current_max_speed if current_max_speed != 0 else 1.0)*get_physics_process_delta_time())
character_node.move_and_slide()
- # Get the velocity from the character node
- var character_node_velocity = character_node.velocity if character_node is CharacterBody3D else character_node.linear_velocity
-
- input_velocity = direction*max_speed if character_node is CharacterBody3D else velocity
- movement_direction = atan2(input_velocity.x,input_velocity.z)
- input_is_moving = input_velocity.length() > 0.0
- input_acceleration = Acceleration * direction * (1 if max_speed != 0 else -1)
- #
-
- actual_acceleration = (character_node_velocity - PrevVelocity) / (get_physics_process_delta_time())
- PrevVelocity = character_node_velocity
- #
- actual_velocity = character_node_velocity
+
#tiltCharacterMesh
if tilt == true:
var MovementDirectionRelativeToCamera = input_velocity.normalized().rotated(Vector3.UP,-camera_root.HObject.transform.basis.get_euler().y)
@@ -555,6 +512,42 @@ func add_movement_input(direction: Vector3 = Vector3.ZERO, Speed: float = 0, Acc
mesh_ref.rotation.z = lerp(mesh_ref.rotation.z,tiltVector.z,Acceleration * get_physics_process_delta_time())
#
+var prev_acceleration : Vector3
+var prev_position : Vector3
+var current_position : Vector3
+func set_movement_info():
+ input_velocity = input_direction*current_max_speed if character_node is CharacterBody3D else velocity
+ movement_direction = atan2(input_velocity.x,input_velocity.z)
+ input_is_moving = input_velocity.length() > 0.0
+
+ prev_position = current_position
+ prev_velocity = actual_velocity
+ prev_acceleration = actual_acceleration
+
+ current_position = character_node.global_position
+ # Distance/Time = Velocity
+ actual_velocity = (current_position - prev_position) / get_physics_process_delta_time()
+ # Delta Velocity / Delta Time = Acceleration
+ actual_acceleration = (actual_velocity - prev_velocity) / get_physics_process_delta_time()
+
+ current_max_speed = 0
+
+
+func apply_deacceleration():
+ if input_is_moving:
+ return
+ if character_node is CharacterBody3D:
+ var velocity_without_up : Vector3 = (character_node.velocity*Vector3(1,0,1))
+ if velocity_without_up == Vector3.ZERO:
+ velocity_without_up = Vector3.ONE
+ if is_flying == false:
+ character_node.velocity.x = lerp(character_node.velocity.x, 0.0, (deacceleration/velocity_without_up.length())*get_physics_process_delta_time())
+ character_node.velocity.z = lerp(character_node.velocity.z, 0.0, (deacceleration/velocity_without_up.length())*get_physics_process_delta_time())
+ else:
+ character_node.velocity.x = lerp(character_node.velocity.x, 0.0, (deacceleration/velocity_without_up.length())*get_physics_process_delta_time())
+ character_node.velocity.y = lerp(character_node.velocity.y, 0.0, (deacceleration/velocity_without_up.length())*get_physics_process_delta_time())
+ character_node.velocity.z = lerp(character_node.velocity.z, 0.0, (deacceleration/velocity_without_up.length())*get_physics_process_delta_time())
+ character_node.move_and_slide()
func calc_animation_data(): # it is used to modify the animation data to get the wanted animation result
animation_is_moving_backward_relative_to_camera = false if -actual_velocity.rotated(Vector3.UP,-camera_root.HObject.transform.basis.get_euler().y).z >= -0.1 else true
@@ -575,5 +568,3 @@ func jump() -> void:
character_node.apply_impulse(Vector3.UP * jump_magnitude * character_node.mass)
else:
vertical_velocity = Vector3.UP * jump_magnitude
-
-
diff --git a/addons/AMSG/Components/PlayerGameplayComponent.gd b/addons/AMSG/Components/PlayerGameplayComponent.gd
index a90241f..74f074e 100644
--- a/addons/AMSG/Components/PlayerGameplayComponent.gd
+++ b/addons/AMSG/Components/PlayerGameplayComponent.gd
@@ -36,9 +36,6 @@ func _physics_process(delta):
add_movement_input(input_direction, current_movement_data.run_speed,current_movement_data.run_acceleration)
else:
add_movement_input(input_direction, current_movement_data.walk_speed,current_movement_data.walk_acceleration)
- else:
- add_movement_input(input_direction,0,deacceleration)
-
return
#------------------ Look At ------------------#
match rotation_mode:
diff --git a/addons/AMSG/Global.gd b/addons/AMSG/Global.gd
old mode 100755
new mode 100644
index f92cec8..a2bad85
--- a/addons/AMSG/Global.gd
+++ b/addons/AMSG/Global.gd
@@ -16,5 +16,3 @@ enum movement_direction {forward , right, left, backward}
func map_range_clamped(value,InputMin,InputMax,OutputMin,OutputMax):
value = clamp(value,InputMin,InputMax)
return ((value - InputMin) / (InputMax - InputMin) * (OutputMax - OutputMin) + OutputMin)
-
-
diff --git a/addons/PoseWarping/PoseWarping.gd b/addons/PoseWarping/PoseWarping.gd
index 5af883e..85cd648 100644
--- a/addons/PoseWarping/PoseWarping.gd
+++ b/addons/PoseWarping/PoseWarping.gd
@@ -1,39 +1,52 @@
@tool
-extends Node3D
+extends SkeletonModifier3D
class_name PoseWarping
## a Node that Handles Pose Warping for character for enhanced animations
## Must be a child of Skeleton3D
+@export var debug : bool = false
+
## Character Node, either CharacterBody3D or RigidBody3D
@export var character_node : PhysicsBody3D
## The Character Skeleton that is going to be modified
-@onready var character_skeleton : Skeleton3D = get_parent()
+@onready var character_skeleton : Skeleton3D = get_skeleton()
## SkeletonIK3D Node that adjusts the left leg IK
@export var LeftLegIK : SkeletonIK3D
## SkeletonIK3D Node that adjusts the right leg IK
@export var RightLegIK : SkeletonIK3D
## Hips bone name, Please Write the correct hips bone name according to your skeleton.
-@export var hips_bone_name : String = "Hips"
-## MUST BE MODIFIED THROUGH MOVEMENT SCRIPT TO MATCH PLAYER MOVEMENT SPEED
-@export var character_velocity : Vector3
+@export_enum(" ") var hips_bone_name : String = "Hips"
+@export_enum(" ") var left_knee_bone_name : String = "LeftLeg"
+@export_enum(" ") var right_knee_bone_name : String = "RightLeg"
+#@export_enum(" ") var left_leg_root_bone_name : String = "LeftUpLeg"
+#@export_enum(" ") var left_leg_tip_bone_name : String = "LeftFoot"
+#@export_enum(" ") var right_leg_root_bone_name : String = "RightUpLeg"
+#@export_enum(" ") var right_leg_tip_bone_name : String = "RightFoot"
+## Character Info
+var character_velocity : Vector3
+var character_prev_velocity : Vector3
+var character_acceleration : Vector3
+var character_prev_acceleration : Vector3
+var character_position : Vector3
+var character_prev_position : Vector3
-@onready var LeftLegIKTarget : Marker3D = $LeftIKTarget
-@onready var RightLegIKTarget : Marker3D = $RightIKTarget
+@onready var LeftLegIKTarget : Marker3D = $LeftTargetRotation/LeftIKTarget
+@onready var RightLegIKTarget : Marker3D = $RightTargetRotation/RightIKTarget
@export_subgroup("Orientation Warping", "orientation_warping_")
## Orientation Warping is a system that adjusts the character's Legs and Hips (Lower body)
## To adapt to character movement direction.
@export var orientation_warping_enable : bool
-## This is tthe object that contains the camera horizontal rotation
+## This is the object that contains the camera horizontal rotation
## it could be the camera object itself.
@export var orientation_warping_camera_h_object : Node3D
## Spine Bones Names, Please Write the correct bone names for all of the spine bones according to your skeleton.
-@export var orientation_warping_spine_bones_names : Array[String] = ["Spine","Spine1","Spine2"]
+@export_enum(" ") var orientation_warping_spine_bones_names : Array[String] = ["Spine","Spine1","Spine2"]
## An offset added to the Spine Bones rotation relative to camera forward
@export var orientation_warping_offset := 0.0
##
-@export var orientation_warping_turn_rate :float= 10.0
+@export var orientation_warping_turn_rate :float= 1.5
@export_subgroup("Stride - Speed Warping", "stride_warping_")
@@ -50,31 +63,43 @@ class_name PoseWarping
## Foot Raycast Length (The Raycast responsible to detect if foot on ground and should be locked or not)
@export var slope_warping_foot_ground_touch_raycast_length : float = 0.14
@onready var slope_warping_raycast_left_touch_detection : RayCast3D = $LeftFootAttachment/LeftLegTouchRayCast
-@onready var slope_warping_raycast_left : RayCast3D = $LeftLegRayCast
+@onready var slope_warping_raycast_left : RayCast3D = $LeftLegTargetRayCast
@onready var slope_warping_bone_attachment_left_foot : BoneAttachment3D = $LeftFootAttachment
@onready var slope_warping_raycast_right_touch_detection : RayCast3D = $RightFootAttachment/RightLegTouchRayCast
-@onready var slope_warping_raycast_right : RayCast3D = $RightLegRayCast
+@onready var slope_warping_raycast_right : RayCast3D = $RightLegTargetRayCast
@onready var slope_warping_bone_attachment_right_foot : BoneAttachment3D = $RightFootAttachment
-@export var slope_warping_foot_height_offset : float = 0.1
-
+@export var slope_warping_foot_height_offset : float = 0.015
-@onready var left_magnet = $LeftMagnet
-@onready var right_magnet = $RightMagnet
+@onready var left_target_rotation = $LeftTargetRotation
+@onready var right_target_rotation = $RightTargetRotation
+@onready var left_leg_ground_normal_ray_cast = $LeftFootAttachment/LeftLegGroundNormalRayCast
+@onready var right_leg_ground_normal_ray_cast = $RightFootAttachment/RightLegGroundNormalRayCast
+@onready var on_floor_ray_cast: RayCast3D = $OnFloorRayCast
+var is_on_floor: bool = false
-func _get_configuration_warnings():
- if not get_parent() is Skeleton3D:
- return ["Parent Must be Skeleton3D."]
+func _validate_property(property: Dictionary) -> void:
+ if property.name == "hips_bone_name" or property.name == "orientation_warping_spine_bones_names"\
+ or property.name == "right_knee_bone_name" or property.name == "left_knee_bone_name"\
+ or property.name == "left_leg_root_bone_name" or property.name == "left_leg_tip_bone_name"\
+ or property.name == "right_leg_root_bone_name" or property.name == "right_leg_tip_bone_name":
+ if character_skeleton:
+ property.hint = PROPERTY_HINT_ENUM
+ property.hint_string = character_skeleton.get_concatenated_bone_names()
func _ready():
+ if !LeftLegIK:
+ assert(false, "Left Leg IK Must be SkeletonIK3D.")
+ if !RightLegIK:
+ assert(false, "Right Leg IK Must be SkeletonIK3D.")
if not get_parent() is Skeleton3D:
assert(false, "Parent Must be Skeleton3D.")
update_configuration_warnings()
if not character_node is CharacterBody3D and not character_node is RigidBody3D:
assert(false, "Character Node Must be either CharacterBody3D or RigidBody3D, please choose the right node from the inspector.")
- slope_warping_bone_attachment_left_foot.set_external_skeleton(character_skeleton.get_path())
+ #slope_warping_bone_attachment_left_foot.set_external_skeleton(character_skeleton.get_path())
slope_warping_bone_attachment_left_foot.bone_name = String(LeftLegIK.tip_bone)
- slope_warping_bone_attachment_right_foot.set_external_skeleton(character_skeleton.get_path())
+ #slope_warping_bone_attachment_right_foot.set_external_skeleton(character_skeleton.get_path())
slope_warping_bone_attachment_right_foot.bone_name = String(RightLegIK.tip_bone)
slope_warping_raycast_left_touch_detection.target_position.y = slope_warping_foot_ground_touch_raycast_length
@@ -84,20 +109,56 @@ func _ready():
slope_warping_raycast_right.add_exception(character_node)
slope_warping_raycast_left_touch_detection.add_exception(character_node)
slope_warping_raycast_right_touch_detection.add_exception(character_node)
+ on_floor_ray_cast.add_exception(character_node)
LeftLegIK.target_node = LeftLegIKTarget.get_path()
RightLegIK.target_node = RightLegIKTarget.get_path()
-func _process(delta):
+
+@onready var result_debug = $LeftTargetRotation/LeftIKTarget/ResultDebug
+@onready var result_debug2 = $RightTargetRotation/RightIKTarget/ResultDebug
+
+func calculate_character_info():
+ character_prev_position = character_position
+ character_prev_velocity = character_velocity
+ character_prev_acceleration = character_acceleration
+
+
+ character_position = character_skeleton.global_position
+ # Distance/Time = Velocity
+ character_velocity = (character_position - character_prev_position) / get_physics_process_delta_time()
+ # Delta Velocity / Delta Time = Acceleration
+ character_acceleration = (character_velocity - character_prev_velocity) / get_physics_process_delta_time()
+
+ if debug:
+ DebugDraw3D.draw_arrow(character_position, character_position+character_velocity, Color.ORANGE, 0.1, false, 0)
+
+func _physics_process(delta: float) -> void:
+ if !LeftLegIK or !RightLegIK:
+ return
+ calculate_character_info()
+ is_on_floor = on_floor_ray_cast.is_colliding()
+
+func _process_modification():
+ if !LeftLegIK or !RightLegIK:
+ return
+ #DebugDraw3D.draw_sphere(slope_warping_bone_attachment_left_foot.global_position, 0.1, Color.RED, 0.0)
+ #DebugDraw3D.draw_sphere(slope_warping_bone_attachment_right_foot.global_position, 0.1, Color.RED, 0.0)
#if Engine.is_editor_hint():
#return
- RightLegIK.magnet = right_magnet.position.rotated(Vector3.UP, orientation_direction)
- LeftLegIK.magnet = left_magnet.position.rotated(Vector3.UP, orientation_direction)
- if stride_warping_enable or slope_warping_enable:
+ #global_transform.basis = foot_look_at_y(Vector3.ZERO, character_skeleton.global_transform.basis.z, left_leg_ground_normal_ray_cast.get_collision_normal())
+
+ #RightLegIK.magnet = right_magnet.position.rotated(Vector3.UP, orientation_direction)
+ #LeftLegIK.magnet = left_magnet.position.rotated(Vector3.UP, orientation_direction)
+ if (stride_warping_enable or slope_warping_enable) and is_on_floor:
var bone_transform_left = character_skeleton.get_bone_global_pose_no_override(character_skeleton.find_bone(String(LeftLegIK.tip_bone)))
var bone_transform_right = character_skeleton.get_bone_global_pose_no_override(character_skeleton.find_bone(String(RightLegIK.tip_bone)))
- LeftLegIKTarget.transform = bone_transform_left
- RightLegIKTarget.transform = bone_transform_right
+ slope_warping_bone_attachment_left_foot.transform = bone_transform_left
+ slope_warping_bone_attachment_right_foot.transform = bone_transform_right
+ LeftLegIKTarget.transform.origin = lerp(LeftLegIKTarget.transform.origin, bone_transform_left.origin, get_physics_process_delta_time()*2)
+ LeftLegIKTarget.transform.basis = lerp(LeftLegIKTarget.transform.basis, bone_transform_left.basis, get_physics_process_delta_time()*2)
+ RightLegIKTarget.transform.origin = lerp(RightLegIKTarget.transform.origin, bone_transform_right.origin, get_physics_process_delta_time()*2)
+ RightLegIKTarget.transform.basis = lerp(RightLegIKTarget.transform.basis, bone_transform_right.basis, get_physics_process_delta_time()*2)
if !LeftLegIK.is_running():
LeftLegIK.start()
if !RightLegIK.is_running():
@@ -107,49 +168,70 @@ func _process(delta):
LeftLegIK.stop()
if RightLegIK.is_running():
RightLegIK.stop()
-
- if stride_warping_enable:
- stride_warping(LeftLegIKTarget, character_node.get_floor_normal(), character_skeleton, hips_bone_name, String(LeftLegIK.tip_bone), String(LeftLegIK.root_bone))
- stride_warping(RightLegIKTarget, character_node.get_floor_normal(), character_skeleton, hips_bone_name, String(RightLegIK.tip_bone), String(RightLegIK.root_bone))
- if slope_warping_enable:
- slope_warping(LeftLegIKTarget, slope_warping_raycast_left, slope_warping_raycast_left_touch_detection, slope_warping_bone_attachment_left_foot, 0)
- slope_warping(RightLegIKTarget, slope_warping_raycast_right, slope_warping_raycast_right_touch_detection, slope_warping_bone_attachment_right_foot, 1)
-
- orientation_warping(orientation_warping_enable, orientation_warping_camera_h_object, character_velocity, character_skeleton, hips_bone_name, orientation_warping_spine_bones_names, orientation_warping_offset, delta, orientation_warping_turn_rate)
- if orientation_warping_enable:
- rotation.y = orientation_direction
+
+ var left_foot_position : Vector3 = (character_skeleton.global_transform * character_skeleton.get_bone_global_pose_no_override(character_skeleton.find_bone(String(LeftLegIK.tip_bone)))).origin
+ var right_foot_position : Vector3 = (character_skeleton.global_transform * character_skeleton.get_bone_global_pose_no_override(character_skeleton.find_bone(String(RightLegIK.tip_bone)))).origin
+ if debug:
+ DebugDraw3D.draw_sphere(left_foot_position, 0.1, Color.RED, 0.0)
+ DebugDraw3D.draw_sphere(right_foot_position, 0.1, Color.RED, 0.0)
+ if stride_warping_enable and is_on_floor:
+ if debug:
+ DebugDraw3D.draw_sphere((character_skeleton.global_transform * character_skeleton.get_bone_global_pose_override(character_skeleton.find_bone(String(LeftLegIK.tip_bone)))).origin, 0.075, Color.GREEN, 0.0)
+ DebugDraw3D.draw_sphere((character_skeleton.global_transform * character_skeleton.get_bone_global_pose_override(character_skeleton.find_bone(String(RightLegIK.tip_bone)))).origin, 0.075, Color.GREEN, 0.0)
+ stride_warping(LeftLegIKTarget, character_skeleton, hips_bone_name, String(LeftLegIK.tip_bone), String(LeftLegIK.root_bone), left_leg_ground_normal_ray_cast.get_collision_normal() if left_leg_ground_normal_ray_cast.is_colliding() else Vector3.UP)
+ stride_warping(RightLegIKTarget, character_skeleton, hips_bone_name, String(RightLegIK.tip_bone), String(RightLegIK.root_bone), right_leg_ground_normal_ray_cast.get_collision_normal() if right_leg_ground_normal_ray_cast.is_colliding() else Vector3.UP)
else:
- orientation_direction = 0
- rotation.y = 0
+ if debug:
+ DebugDraw3D.draw_sphere(left_foot_position, 0.075, Color.GREEN, 0.0)
+ DebugDraw3D.draw_sphere(right_foot_position, 0.075, Color.GREEN, 0.0)
+
+ if slope_warping_enable and is_on_floor:
+ slope_warping(LeftLegIKTarget, left_target_rotation, left_leg_ground_normal_ray_cast, slope_warping_raycast_left, slope_warping_raycast_left_touch_detection, slope_warping_bone_attachment_left_foot, 0)
+ slope_warping(RightLegIKTarget, right_target_rotation, right_leg_ground_normal_ray_cast, slope_warping_raycast_right, slope_warping_raycast_right_touch_detection, slope_warping_bone_attachment_right_foot, 1)
+
+ set_orientation_warping_direction(orientation_warping_enable, orientation_warping_camera_h_object, character_velocity, orientation_warping_turn_rate, get_physics_process_delta_time())
+ orientation_warping(orientation_warping_enable, character_skeleton, hips_bone_name, orientation_warping_spine_bones_names, orientation_warping_offset)
+ # Adjust ground touch raycast length for slopes
+ if left_leg_ground_normal_ray_cast.get_collision_normal() != Vector3.UP:
+ slope_warping_raycast_left_touch_detection.target_position.y = slope_warping_foot_ground_touch_raycast_length + abs(left_target_rotation.rotation.x)/10.0
+ else:
+ slope_warping_raycast_left_touch_detection.target_position.y = slope_warping_foot_ground_touch_raycast_length
+
+ if right_leg_ground_normal_ray_cast.get_collision_normal() != Vector3.UP:
+ slope_warping_raycast_right_touch_detection.target_position.y = slope_warping_foot_ground_touch_raycast_length + abs(right_target_rotation.rotation.x)/10.0
+ else:
+ slope_warping_raycast_right_touch_detection.target_position.y = slope_warping_foot_ground_touch_raycast_length
## For Predicting Stop Location
-## it uses a linear equation : d = v*t + 0.5 * a * t^2
## v is velocity. t is time. a is acceleration
-func CalculateStopLocation(CurrentCharacterLocation:Vector3,Velocity:Vector3,deacceleration:Vector3,delta):
- var time = CalculateStopTime(Velocity,deacceleration)
- return CurrentCharacterLocation + (Velocity * time + 0.5*deacceleration*pow(time,2))
+func CalculateStopLocation(deacceleration:float) -> Vector3:
+ var time : float = CalculateStopTime(deacceleration)
+ ## it uses a linear equation : d = v*t + 0.5 * a * t^2
+ var predictied_distance_before_stop : Vector3 = (character_velocity * time + 0.5*(-deacceleration*character_velocity.normalized())*pow(time,2))
+ var stop_position : Vector3 = character_position + predictied_distance_before_stop
+ if debug:
+ DebugDraw3D.draw_sphere(stop_position+Vector3(0, 0.75, 0), 0.3, Color.RED, 3.0)
+ return stop_position
-func CalculateStopTime(Velocity:Vector3,deacceleration:Vector3):
- var time = Velocity.length() / deacceleration.length()
+func CalculateStopTime(deacceleration:float) -> float:
+ var time : float = character_velocity.length() / deacceleration
return time
var previous_direction : float
var orientation_direction : float
var cleared_override : bool = true
-func orientation_warping(enabled:bool,CameraObject, Velocity:Vector3, character_skeleton:Skeleton3D, Hip :String= "Hips", Spines :Array[String]= ["Spine","Spine1","Spine2"], Offset := 0.0, delta :float= 1.0, turn_rate :float= 10.0):
-
- if !enabled and !cleared_override:
- set_bone_y_rotation(character_skeleton,Hip,0,false)
- for bone in Spines:
- set_bone_y_rotation(character_skeleton,bone,0,false)
- cleared_override = true
- if is_equal_approx(Velocity.length(),0.0) or !enabled:
+
+#just sets the orientation warping direction, this isn't a specific algorithm,
+#just my way of how the character should walk.
+func set_orientation_warping_direction(enabled:bool, CameraObject, Velocity : Vector3, turn_rate : float, delta:float):
+ if is_equal_approx(character_velocity.length(),0.0) or !orientation_warping_enable:
+ orientation_direction = 0
+ rotation.y = 0
return
- cleared_override = false
var CameraAngle :Quaternion = Quaternion(Vector3(0,1,0),atan2(-CameraObject.transform.basis.z.z, -CameraObject.transform.basis.z.x))
var VelocityAngle :Quaternion = Quaternion(Vector3(0,1,0),atan2(Velocity.z, Velocity.x))
var IsMovingBackwardRelativeToCamera :bool = false if -Velocity.rotated(Vector3.UP,-CameraObject.transform.basis.get_euler().y).z >= -0.1 else true
@@ -161,34 +243,42 @@ func orientation_warping(enabled:bool,CameraObject, Velocity:Vector3, character_
# Make the legs face forward just like the forward walking
orientation_direction *= -1
orientation_direction = orientation_direction + PI
-
-
# Set Left or Right
if IsMovingLeftRelativeToCamera:
orientation_direction *= -1
-
if IsMovingBackwardRelativeToCamera:
# since we rotated the legs to face forward, then the right and left will be reversed
# so we need to reverse it back again after getting the right and left values
orientation_direction *= -1
orientation_direction = clampf(lerp_angle(previous_direction,orientation_direction,delta*turn_rate),-PI/2, PI/2)
- #Orient bones to face the forward direction
+ rotation.y = orientation_direction
+
+func orientation_warping(enabled:bool, character_skeleton:Skeleton3D, Hip :String= "Hips", Spines :Array[String]= ["Spine","Spine1","Spine2"], Offset := 0.0):
+ if !enabled and !cleared_override:
+ set_bone_y_rotation(character_skeleton,Hip,0)
+ for bone in Spines:
+ set_bone_y_rotation(character_skeleton,bone,0)
+ cleared_override = true
+ if !enabled:
+ return
+ cleared_override = false
+ #Orient bones to face the forward direction
set_bone_y_rotation(character_skeleton,Hip,orientation_direction)
for bone in Spines:
- set_bone_y_rotation(character_skeleton,bone,(orientation_direction/(Spines.size()))+Offset)
-
-
-func set_bone_y_rotation(skeleton:Skeleton3D,bone_name:String, y_rot:float, presistant:bool=true):
+ set_bone_y_rotation(character_skeleton,bone,-(orientation_direction/(Spines.size()))+Offset)
+
+
+func set_bone_y_rotation(skeleton:Skeleton3D,bone_name:String, y_rot:float):
var bone = skeleton.find_bone(bone_name)
- var bone_transform : Transform3D = skeleton.get_bone_global_pose_no_override(bone)
+ var bone_transform : Transform3D = skeleton.get_bone_global_pose(bone)
bone_transform = bone_transform.rotated(Vector3(0,1,0), y_rot)
- skeleton.set_bone_global_pose_override(bone, bone_transform,1.0,presistant)
+ skeleton.set_bone_global_pose(bone, bone_transform)
-func stride_warping(target:Node3D, floor_normal:Vector3, skeleton_ref:Skeleton3D, hips_name:String, Foot:String, Thigh:String):
+func stride_warping(target:Node3D, skeleton_ref:Skeleton3D, hips_name:String, Foot:String, Thigh:String, floor_normal:Vector3 = Vector3.UP):
#add_sibling(test_sphere)
#add_sibling(test_sphere1)
@@ -201,10 +291,9 @@ func stride_warping(target:Node3D, floor_normal:Vector3, skeleton_ref:Skeleton3D
var stride_scale : float = 1.0
#Get Bones
var bone = skeleton_ref.find_bone(Foot)
- var bone_transform = skeleton_ref.get_bone_global_pose_no_override(bone)
-
+ var bone_transform = skeleton_ref.get_bone_global_pose(bone)
var thigh_bone = skeleton_ref.find_bone(Thigh)
- var thigh_transform = skeleton_ref.get_bone_global_pose_no_override(thigh_bone)
+ var thigh_transform = skeleton_ref.get_bone_global_pose(thigh_bone)
var thigh_angle = thigh_transform.basis.get_euler().x
#Calculate
@@ -229,35 +318,27 @@ func foot_look_at_y(from:Vector3, to:Vector3, up_ref:Vector3 = Vector3.UP) -> Ba
var right = up_ref.normalized().cross(forward).normalized()
forward = right.cross(up_ref).normalized()
return Basis(right, up_ref, forward)
-func slope_warping(target:Node3D, raycast:RayCast3D, touch_raycast:RayCast3D, no_raycast_pos, leg_number:int):
+func slope_warping(target:Node3D, target_rotation:Node3D, leg_ground_normal_ray_cast:RayCast3D, raycast:RayCast3D, touch_raycast:RayCast3D, no_raycast_pos, leg_number:int):
if updated_raycast_pos.size() < leg_number+1:
updated_raycast_pos.resize(leg_number+1)
if slope_warping_feet_locking_enable:
- if touch_raycast.is_colliding():
+ if touch_raycast.is_colliding() and character_velocity.length() > 0.5:
if updated_raycast_pos[leg_number] == false:
- raycast.global_position = no_raycast_pos.global_position + Vector3(0.0,0.25,0.0)
+ raycast.global_position = no_raycast_pos.global_position + Vector3(0.0,0.25,0.0) # Set the lock position
updated_raycast_pos[leg_number] = true
else:
updated_raycast_pos[leg_number] = false
# Update position to not let the leg yeet towards the old far location
- raycast.global_position = lerp(raycast.global_position, no_raycast_pos.global_position + Vector3(0.0,0.25,0.0), get_process_delta_time()*20)
+ raycast.global_position = lerp(raycast.global_position, no_raycast_pos.global_position + Vector3(0.0,0.25,0.0), get_process_delta_time()*20) #smoothly lerp out of lock
else:
raycast.global_position = no_raycast_pos.global_position + Vector3(0.0,0.25,0.0)
-
+ #character_skeleton.get_bone_global_pose(no_raycast_pos.bone_idx)
if raycast.is_colliding() and (touch_raycast.is_colliding() or character_velocity.length()<1.0): #if raycast is on ground
var hit_point = raycast.get_collision_point() + Vector3.UP*slope_warping_foot_height_offset #gets Y position of where the ground is.
- target.global_transform.origin = hit_point #sets the target to the y position of the hitpoint
+ if character_velocity.length() > 0.5 and slope_warping_feet_locking_enable:
+ target.global_transform.origin = lerp(target.global_transform.origin, hit_point, 1) #sets the target to the position of the hitpoint which helps locking too
+ else:
+ target.global_transform.origin.y = hit_point.y #sets the target to the y position of the hitpoint
var up_ref = raycast.get_collision_normal()
- #if up_ref != Vector3.UP:
- #var forward = (character_skeleton.global_transform.basis.z).normalized()
- #var right = up_ref.normalized().cross(forward).normalized()
- #forward = right.cross(up_ref).normalized()
- #target.rotate(Vector3.RIGHT, forward.angle_to(target.global_transform.basis.y))
- #var relative_normal = hit_point * raycast.get_collision_normal()
-
- #target.global_transform = _basis_from_normal(target.global_transform, raycast.get_collision_normal())
- #target.rotation += Vector3(-35, 0, 180)
- #target.global_transfyouorm.basis = foot_look_at_y(Vector3.ZERO, character_skeleton.global_transform.basis.z, raycast.get_collision_normal())
- #else:
- #raycast.global_transform.origin = target.global_transform.origin #if the raycast not colliding, the player is in the air and so the target position is set to the no_raycast_pos
+ target_rotation.global_transform.basis = foot_look_at_y(Vector3.ZERO, character_skeleton.global_transform.basis.z.rotated(Vector3.UP, orientation_direction), leg_ground_normal_ray_cast.get_collision_normal())
diff --git a/addons/PoseWarping/PoseWarping.tscn b/addons/PoseWarping/PoseWarping.tscn
index f1f88ff..aa16fa5 100644
--- a/addons/PoseWarping/PoseWarping.tscn
+++ b/addons/PoseWarping/PoseWarping.tscn
@@ -10,34 +10,60 @@ material = SubResource("StandardMaterial3D_8kjlp")
radius = 0.1
height = 0.2
-[node name="PoseWarping" type="Node3D"]
+[node name="PoseWarping" type="SkeletonModifier3D"]
+_import_path = NodePath("")
+unique_name_in_owner = false
+process_mode = 0
+process_priority = 0
+process_physics_priority = 0
+process_thread_group = 0
+physics_interpolation_mode = 0
+auto_translate_mode = 0
+editor_description = ""
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+rotation_edit_mode = 0
+rotation_order = 2
+top_level = false
+visible = true
+visibility_parent = NodePath("")
+active = true
+influence = 1.0
script = ExtResource("1_lecgu")
-[node name="LeftIKTarget" type="Marker3D" parent="."]
+[node name="LeftTargetRotation" type="Node3D" parent="."]
+
+[node name="LeftIKTarget" type="Marker3D" parent="LeftTargetRotation"]
transform = Transform3D(-1, 8.74228e-08, 0, -5.61943e-08, -0.642788, 0.766044, 6.69697e-08, 0.766044, 0.642788, 0, 0, 0)
-[node name="ResultDebug" type="MeshInstance3D" parent="LeftIKTarget"]
+[node name="ResultDebug" type="MeshInstance3D" parent="LeftTargetRotation/LeftIKTarget"]
transform = Transform3D(-1, -6.18173e-08, 6.18173e-08, 8.74228e-08, -0.707107, 0.707107, 0, 0.707107, 0.707107, 0, 0, 0)
visible = false
mesh = SubResource("SphereMesh_kea8p")
skeleton = NodePath("../../..")
-[node name="RightIKTarget" type="Marker3D" parent="."]
+[node name="RightTargetRotation" type="Node3D" parent="."]
+
+[node name="RightIKTarget" type="Marker3D" parent="RightTargetRotation"]
transform = Transform3D(-1, -8.74228e-08, 0, 5.61943e-08, -0.642788, 0.766044, -6.69697e-08, 0.766044, 0.642788, 0, 0, 0)
-[node name="ResultDebug" type="MeshInstance3D" parent="RightIKTarget"]
+[node name="ResultDebug" type="MeshInstance3D" parent="RightTargetRotation/RightIKTarget"]
transform = Transform3D(-1, -6.18173e-08, 6.18173e-08, 8.74228e-08, -0.707107, 0.707107, 0, 0.707107, 0.707107, 0, 0, 0)
visible = false
mesh = SubResource("SphereMesh_kea8p")
skeleton = NodePath("../../..")
[node name="LeftFootAttachment" type="BoneAttachment3D" parent="."]
-transform = Transform3D(-0.975623, 0.0371672, 0.216283, -0.0696969, -0.987006, -0.144781, 0.208092, -0.156326, 0.965536, 0.079531, 0.255067, -0.210493)
bone_name = "LeftFoot"
bone_idx = 64
use_external_skeleton = true
external_skeleton = NodePath("")
+[node name="LeftLegGroundNormalRayCast" type="RayCast3D" parent="LeftFootAttachment"]
+transform = Transform3D(1, 0, 0, 0, 0.70711, 0.707111, 0, -0.70711, 0.707111, 0, 0, 0)
+target_position = Vector3(0, 1, 0)
+debug_shape_custom_color = Color(0.662745, 0, 0, 1)
+debug_shape_thickness = 5
+
[node name="LeftLegTouchRayCast" type="RayCast3D" parent="LeftFootAttachment"]
transform = Transform3D(1, 0, 0, 0, 0.70711, 0.707111, 0, -0.70711, 0.707111, 0, 0, 0)
target_position = Vector3(0, 0.14, 0)
@@ -45,28 +71,31 @@ debug_shape_custom_color = Color(0.662745, 0.647059, 0, 1)
debug_shape_thickness = 5
[node name="RightFootAttachment" type="BoneAttachment3D" parent="."]
-transform = Transform3D(-0.990874, -0.123241, -0.0545858, 0.0370522, -0.638419, 0.768797, -0.129596, 0.759758, 0.63716, -0.0396977, 0.103349, 0.111844)
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0396977, 0.103349, 0.111844)
bone_name = "RightFoot"
bone_idx = 59
use_external_skeleton = true
external_skeleton = NodePath("")
-[node name="RightLegTouchRayCast" type="RayCast3D" parent="RightFootAttachment"]
+[node name="RightLegGroundNormalRayCast" type="RayCast3D" parent="RightFootAttachment"]
transform = Transform3D(1, 0, 0, 0, 0.70711, 0.707112, 0, -0.70711, 0.707112, 0, 0, 0)
+target_position = Vector3(0, 1, 0)
+debug_shape_custom_color = Color(0.662745, 0, 0, 1)
+debug_shape_thickness = 5
+
+[node name="RightLegTouchRayCast" type="RayCast3D" parent="RightFootAttachment"]
+transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 0, 0)
target_position = Vector3(0, 0.14, 0)
debug_shape_custom_color = Color(0.662745, 0.647059, 0, 1)
debug_shape_thickness = 5
-[node name="LeftLegRayCast" type="RayCast3D" parent="."]
+[node name="LeftLegTargetRayCast" type="RayCast3D" parent="."]
top_level = true
debug_shape_thickness = 5
-[node name="RightLegRayCast" type="RayCast3D" parent="."]
+[node name="RightLegTargetRayCast" type="RayCast3D" parent="."]
top_level = true
debug_shape_thickness = 5
-[node name="LeftMagnet" type="Marker3D" parent="."]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 1, 1)
-
-[node name="RightMagnet" type="Marker3D" parent="."]
-transform = Transform3D(1, 0, 0, 0, 0.999999, 0, 0, 0, 1, -0.25, 1, 1)
+[node name="OnFloorRayCast" type="RayCast3D" parent="."]
+target_position = Vector3(0, -0.4, 0)
diff --git a/addons/PoseWarping/PoseWarpingPlugin.gd b/addons/PoseWarping/PoseWarpingPlugin.gd
old mode 100755
new mode 100644
index 13c9c53..ef2f207
--- a/addons/PoseWarping/PoseWarpingPlugin.gd
+++ b/addons/PoseWarping/PoseWarpingPlugin.gd
@@ -8,6 +8,3 @@ func _enter_tree():
func _exit_tree():
# Clean-up of the plugin goes here.
pass
-
-
-
diff --git a/addons/debug_draw_3d/LICENSE b/addons/debug_draw_3d/LICENSE
new file mode 100644
index 0000000..617a15b
--- /dev/null
+++ b/addons/debug_draw_3d/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 DmitriySalnikov
+
+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, andor 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.
\ No newline at end of file
diff --git a/addons/debug_draw_3d/README.md b/addons/debug_draw_3d/README.md
new file mode 100644
index 0000000..35fed41
--- /dev/null
+++ b/addons/debug_draw_3d/README.md
@@ -0,0 +1,130 @@
+![icon](/images/icon_3d_128.png)
+
+# Debug drawing utility for Godot
+
+This is an add-on for debug drawing in 3D and for some 2D overlays, which is written in `C++` and can be used with `GDScript` or `C#`.
+
+Based on my previous addon, which was developed [only for C#](https://github.com/DmitriySalnikov/godot_debug_draw_cs), and which was inspired by [Zylann's GDScript addon](https://github.com/Zylann/godot_debug_draw)
+
+## [Documentation](https://dd3d.dmitriysalnikov.ru/docs/)
+
+## [Godot 3 version](https://github.com/DmitriySalnikov/godot_debug_draw_3d/tree/godot_3)
+
+## Support me
+
+Your support adds motivation to develop my public projects.
+
+
+
+
+
+USDT-TRC20 TEw934PrsffHsAn5M63SoHYRuZo984EF6v
+
+## Features
+
+3D:
+
+* Arrow
+* Billboard opaque square
+* Box
+* Camera Frustum
+* Cylinder
+* Gizmo
+* Grid
+* Line
+* Line Path
+* Line with Arrow
+* Plane
+* Points
+* Position 3D (3 crossing axes)
+* Sphere
+
+2D:
+
+* **[Work in progress]**
+
+Overlay:
+
+* Text (with grouping and coloring)
+* FPS Graph
+* Custom Graphs
+
+Precompiled for:
+
+* Windows
+* Linux (built on Ubuntu 20.04)
+* macOS (10.14+)
+* Android (5.0+)
+* iOS
+* Web (Firefox not supported)
+
+This addon also supports working with several World3D and different Viewports.
+
+## [Interactive Web Demo](https://dd3d.dmitriysalnikov.ru/demo/)
+
+[![screenshot_web](/images/screenshot_web.png)](https://dd3d.dmitriysalnikov.ru/demo/)
+
+> [!WARNING]
+>
+> * Firefox most likely can't run this demo
+
+## Download
+
+To download, use the [Godot Asset Library](https://godotengine.org/asset-library/asset/1766) or download the archive by clicking the button at the top of the main repository page: `Code -> Download ZIP`, then unzip it to your project folder. Or use one of the stable versions from the [GitHub Releases](https://github.com/DmitriySalnikov/godot_debug_draw_3d/releases) page (just download one of the `Source Codes` in assets).
+
+### Installation
+
+* Close editor
+* Copy `addons/debug_draw_3d` to your `addons` folder, create it if the folder doesn't exist
+* Launch editor
+
+## Examples
+
+More examples can be found in the `examples_dd3d/` folder.
+
+Simple test:
+
+```gdscript
+func _process(delta: float) -> void:
+ var _time = Time.get_ticks_msec() / 1000.0
+ var box_pos = Vector3(0, sin(_time * 4), 0)
+ var line_begin = Vector3(-1, sin(_time * 4), 0)
+ var line_end = Vector3(1, cos(_time * 4), 0)
+
+ DebugDraw3D.draw_box(box_pos, Vector3(1, 2, 1), Color(0, 1, 0))
+ DebugDraw3D.draw_line(line_begin, line_end, Color(1, 1, 0))
+ DebugDraw2D.set_text("Time", _time)
+ DebugDraw2D.set_text("Frames drawn", Engine.get_frames_drawn())
+ DebugDraw2D.set_text("FPS", Engine.get_frames_per_second())
+ DebugDraw2D.set_text("delta", delta)
+```
+
+![screenshot_1](/images/screenshot_1.png)
+
+## API
+
+This project has a separate [documentation](https://dd3d.dmitriysalnikov.ru/docs/) page.
+
+Also, a list of all functions is available in the documentation inside the editor (see `DebugDraw3D` and `DebugDraw2D`).
+
+![screenshot_4](/images/screenshot_4.png)
+
+## Known issues and limitations
+
+Enabling occlusion culing can lower fps instead of increasing it. At the moment I do not know how to speed up the calculation of the visibility of objects.
+
+The text in the keys and values of a text group cannot contain multi-line strings.
+
+The entire text overlay can only be placed in one corner, unlike `DataGraphs`.
+
+[Frustum of Camera3D does not take into account the window size from ProjectSettings](https://github.com/godotengine/godot/issues/70362).
+
+**The version for Godot 4.0 requires explicitly specifying the exact data types, otherwise errors may occur.**
+
+## More screenshots
+
+`DebugDrawDemoScene.tscn` in editor
+![screenshot_2](/images/screenshot_2.png)
+
+`DebugDrawDemoScene.tscn` in play mode
+![screenshot_3](/images/screenshot_3.png)
diff --git a/addons/debug_draw_3d/debug_draw_3d.gdextension b/addons/debug_draw_3d/debug_draw_3d.gdextension
new file mode 100644
index 0000000..a7482b6
--- /dev/null
+++ b/addons/debug_draw_3d/debug_draw_3d.gdextension
@@ -0,0 +1,90 @@
+[configuration]
+
+entry_symbol = "debug_draw_3d_library_init"
+compatibility_minimum = "4.1.3"
+reloadable = false
+
+[dependencies]
+
+; example.x86_64 = { "relative or absolute path to the dependency" : "the path relative to the exported project", }
+; -------------------------------------
+; debug
+
+macos = { }
+windows.x86_64 = { }
+linux.x86_64 = { }
+
+web.wasm32 = {}
+
+android.arm32 = { }
+android.arm64 = { }
+android.x86_32 = { }
+android.x86_64 = { }
+ios = {}
+
+; -------------------------------------
+; release no debug draw
+
+macos.template_release = { }
+windows.template_release.x86_64 = { }
+linux.template_release.x86_64 = { }
+
+web.template_release.wasm32 = { }
+
+android.template_release.arm32 = { }
+android.template_release.arm64 = { }
+android.template_release.x86_32 = { }
+android.template_release.x86_64 = { }
+ios.template_release = {}
+
+; -------------------------------------
+; release forced debug draw
+
+macos.template_release.forced_dd3d = { }
+windows.template_release.x86_64.forced_dd3d = { }
+linux.template_release.x86_64.forced_dd3d = { }
+
+web.template_release.wasm32.forced_dd3d = { }
+ios.template_release.forced_dd3d = {}
+
+[libraries]
+
+; -------------------------------------
+; debug
+
+macos = "libs/libdd3d.macos.editor.universal.framework"
+windows.x86_64 = "libs/libdd3d.windows.editor.x86_64.dll"
+linux.x86_64 = "libs/libdd3d.linux.editor.x86_64.so"
+
+web.wasm32 = "libs/libdd3d.web.template_debug.wasm32.wasm"
+
+android.arm32 = "libs/libdd3d.android.template_debug.arm32.so"
+android.arm64 = "libs/libdd3d.android.template_debug.arm64.so"
+android.x86_32 = "libs/libdd3d.android.template_debug.x86_32.so"
+android.x86_64 = "libs/libdd3d.android.template_debug.x86_64.so"
+ios = "libs/libdd3d.ios.template_debug.universal.dylib"
+
+; -------------------------------------
+; release no debug draw
+
+macos.template_release = "libs/libdd3d.macos.template_release.universal.framework"
+windows.template_release.x86_64 = "libs/libdd3d.windows.template_release.x86_64.dll"
+linux.template_release.x86_64 = "libs/libdd3d.linux.template_release.x86_64.so"
+
+web.template_release.wasm32 = "libs/libdd3d.web.template_release.wasm32.wasm"
+
+android.template_release.arm32 = "libs/libdd3d.android.template_release.arm32.so"
+android.template_release.arm64 = "libs/libdd3d.android.template_release.arm64.so"
+android.template_release.x86_32 = "libs/libdd3d.android.template_release.x86_32.so"
+android.template_release.x86_64 = "libs/libdd3d.android.template_release.x86_64.so"
+ios.template_release = "libs/libdd3d.ios.template_release.universal.dylib"
+
+; -------------------------------------
+; release forced debug draw
+
+macos.template_release.forced_dd3d = "libs/libdd3d.macos.template_release.universal.enabled.framework"
+windows.template_release.x86_64.forced_dd3d = "libs/libdd3d.windows.template_release.x86_64.enabled.dll"
+linux.template_release.x86_64.forced_dd3d = "libs/libdd3d.linux.template_release.x86_64.enabled.so"
+
+web.template_release.wasm32.forced_dd3d = "libs/libdd3d.web.template_release.wasm32.enabled.wasm"
+ios.template_release.forced_dd3d = "libs/libdd3d.ios.template_release.universal.enabled.dylib"
\ No newline at end of file
diff --git a/addons/debug_draw_3d/libs/.gdignore b/addons/debug_draw_3d/libs/.gdignore
new file mode 100644
index 0000000..e69de29
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm32.so
new file mode 100644
index 0000000..06ab924
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm32.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm64.so
new file mode 100644
index 0000000..71678fc
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm64.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_32.so
new file mode 100644
index 0000000..2f77b8f
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_32.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_64.so
new file mode 100644
index 0000000..e877609
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_64.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm32.so
new file mode 100644
index 0000000..17b8efc
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm32.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm64.so
new file mode 100644
index 0000000..44c5305
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm64.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_32.so
new file mode 100644
index 0000000..5f93a87
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_32.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_64.so
new file mode 100644
index 0000000..d3b36e2
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_64.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.ios.template_debug.universal.dylib b/addons/debug_draw_3d/libs/libdd3d.ios.template_debug.universal.dylib
new file mode 100644
index 0000000..0eb3e53
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.ios.template_debug.universal.dylib differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.dylib b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.dylib
new file mode 100644
index 0000000..22bb100
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.dylib differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.enabled.dylib b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.enabled.dylib
new file mode 100644
index 0000000..5559824
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.enabled.dylib differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.linux.editor.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.linux.editor.x86_64.so
new file mode 100644
index 0000000..a6af2ed
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.linux.editor.x86_64.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.enabled.so b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.enabled.so
new file mode 100644
index 0000000..e8f6def
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.enabled.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.so
new file mode 100644
index 0000000..62b1c32
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.so differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/Resources/Info.plist b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/Resources/Info.plist
new file mode 100644
index 0000000..521e8c3
--- /dev/null
+++ b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/Resources/Info.plist
@@ -0,0 +1,33 @@
+
+
+
+
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ libdd3d.macos.editor.universal
+ CFBundleName
+ Debug Draw 3D
+ CFBundleDisplayName
+ Debug Draw 3D
+ CFBundleIdentifier
+ ru.dmitriysalnikov.dd3d
+ NSHumanReadableCopyright
+ Copyright (c) Dmitriy Salnikov.
+ CFBundleVersion
+ 1.4.0
+ CFBundleShortVersionString
+ 1.4.0
+ CFBundlePackageType
+ FMWK
+ CSResourcesFileMapped
+
+ DTPlatformName
+ macosx
+ LSMinimumSystemVersion
+ 10.14
+
+
+
\ No newline at end of file
diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/libdd3d.macos.editor.universal b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/libdd3d.macos.editor.universal
new file mode 100644
index 0000000..0bb4f27
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/libdd3d.macos.editor.universal differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/Resources/Info.plist b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/Resources/Info.plist
new file mode 100644
index 0000000..878ea79
--- /dev/null
+++ b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/Resources/Info.plist
@@ -0,0 +1,33 @@
+
+
+
+
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ libdd3d.macos.template_release.universal.enabled
+ CFBundleName
+ Debug Draw 3D
+ CFBundleDisplayName
+ Debug Draw 3D
+ CFBundleIdentifier
+ ru.dmitriysalnikov.dd3d
+ NSHumanReadableCopyright
+ Copyright (c) Dmitriy Salnikov.
+ CFBundleVersion
+ 1.4.0
+ CFBundleShortVersionString
+ 1.4.0
+ CFBundlePackageType
+ FMWK
+ CSResourcesFileMapped
+
+ DTPlatformName
+ macosx
+ LSMinimumSystemVersion
+ 10.14
+
+
+
\ No newline at end of file
diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/libdd3d.macos.template_release.universal.enabled b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/libdd3d.macos.template_release.universal.enabled
new file mode 100644
index 0000000..d667916
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/libdd3d.macos.template_release.universal.enabled differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/Resources/Info.plist b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/Resources/Info.plist
new file mode 100644
index 0000000..b081cb0
--- /dev/null
+++ b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/Resources/Info.plist
@@ -0,0 +1,33 @@
+
+
+
+
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ libdd3d.macos.template_release.universal
+ CFBundleName
+ Debug Draw 3D
+ CFBundleDisplayName
+ Debug Draw 3D
+ CFBundleIdentifier
+ ru.dmitriysalnikov.dd3d
+ NSHumanReadableCopyright
+ Copyright (c) Dmitriy Salnikov.
+ CFBundleVersion
+ 1.4.0
+ CFBundleShortVersionString
+ 1.4.0
+ CFBundlePackageType
+ FMWK
+ CSResourcesFileMapped
+
+ DTPlatformName
+ macosx
+ LSMinimumSystemVersion
+ 10.14
+
+
+
\ No newline at end of file
diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/libdd3d.macos.template_release.universal b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/libdd3d.macos.template_release.universal
new file mode 100644
index 0000000..8b87a42
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/libdd3d.macos.template_release.universal differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.wasm
new file mode 100644
index 0000000..8795b8e
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.wasm differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.enabled.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.enabled.wasm
new file mode 100644
index 0000000..c78424d
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.enabled.wasm differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.wasm
new file mode 100644
index 0000000..c4f4103
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.wasm differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.windows.editor.x86_64.dll b/addons/debug_draw_3d/libs/libdd3d.windows.editor.x86_64.dll
new file mode 100644
index 0000000..61056b0
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.windows.editor.x86_64.dll differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.dll b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.dll
new file mode 100644
index 0000000..d2ae39f
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.dll differ
diff --git a/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.enabled.dll b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.enabled.dll
new file mode 100644
index 0000000..2c125e5
Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.enabled.dll differ
diff --git a/default_bus_layout.tres b/default_bus_layout.tres
new file mode 100644
index 0000000..d6b8f79
--- /dev/null
+++ b/default_bus_layout.tres
@@ -0,0 +1,3 @@
+[gd_resource type="AudioBusLayout" format=3 uid="uid://bemotwr4e8kf1"]
+
+[resource]
diff --git a/examples_dd3d/DebugDrawDemoScene.gd b/examples_dd3d/DebugDrawDemoScene.gd
new file mode 100644
index 0000000..e5357b5
--- /dev/null
+++ b/examples_dd3d/DebugDrawDemoScene.gd
@@ -0,0 +1,605 @@
+@tool
+extends Node3D
+
+@export var custom_font : Font
+@export var zylann_example := false
+@export var update_in_physics := false
+@export var test_text := true
+@export var test_graphs := false
+@export var more_test_cases := true
+@export var draw_array_of_boxes := false
+@export var draw_1m_boxes := false
+@export_range(0, 5, 0.001) var debug_thickness := 0.1
+@export_range(0, 1, 0.001) var debug_center_brightness := 0.8
+@export_range(0, 1) var camera_frustum_scale := 0.9
+
+@export_group("Text groups", "text_groups")
+@export var text_groups_show_hints := true
+@export var text_groups_show_stats := false
+@export var text_groups_show_stats_2d := false
+@export var text_groups_position := DebugDraw2DConfig.POSITION_LEFT_TOP
+@export var text_groups_offset := Vector2i(8, 8)
+@export var text_groups_padding := Vector2i(3, 1)
+@export_range(1, 100) var text_groups_default_font_size := 15
+@export_range(1, 100) var text_groups_title_font_size := 20
+@export_range(1, 100) var text_groups_text_font_size := 17
+
+@export_group("Graphs", "graph")
+@export var graph_offset := Vector2i(8, 8)
+@export var graph_size := Vector2i(200, 80)
+@export_range(1, 100) var graph_title_font_size := 14
+@export_range(1, 100) var graph_text_font_size := 12
+@export_range(0, 64) var graph_text_precision := 1
+@export_range(1, 32) var graph_line_width := 1.0
+@export_range(1, 512) var graph_buffer_size := 128
+@export var graph_frame_time_mode := true
+@export var graph_is_enabled := true
+
+var button_presses := {}
+var frame_rendered := false
+var physics_tick_processed := false
+
+var timer_1 := 0.0
+var timer_cubes := 0.0
+var timer_3 := 0.0
+var timer_text := 0.0
+
+# TODO remove after moving to 4.2
+var is_4_2_and_higher = Engine.get_version_info()["major"] >= 4 && Engine.get_version_info()["minor"] >= 2
+
+
+func _process(delta) -> void:
+ $OtherWorld.mesh.material.set_shader_parameter("albedo_texture", $OtherWorld/SubViewport.get_texture())
+
+ physics_tick_processed = false
+ if !update_in_physics:
+ main_update(delta)
+ _update_timers(delta)
+
+
+## Since physics frames may not be called every frame or may be called multiple times in one frame,
+## there is an additional check to ensure that a new frame has been drawn before updating the data.
+func _physics_process(delta: float) -> void:
+ if !physics_tick_processed:
+ physics_tick_processed = true
+ if update_in_physics:
+ main_update(delta)
+ _update_timers(delta)
+
+ # Physics specific:
+ if not zylann_example:
+ DebugDraw3D.draw_line($"Lines/8".global_position, $Lines/Target.global_position, Color.YELLOW)
+
+ if more_test_cases:
+ _draw_rays_casts()
+
+ ## Additional drawing in the Viewport
+ if true:
+ var _w1 = DebugDraw3D.new_scoped_config().set_viewport(%OtherWorldBox.get_viewport()).set_thickness(0.01).set_center_brightness(1)
+ DebugDraw3D.draw_box_xf(Transform3D(Basis()
+ .scaled(Vector3.ONE*0.3)
+ .rotated(Vector3(0,0,1), PI/4)
+ .rotated(Vector3(0,1,0), wrapf(Time.get_ticks_msec() / -1500.0, 0, TAU) - PI/4), %OtherWorldBox.global_transform.origin),
+ Color.BROWN, true, 0.4)
+
+
+func main_update(delta: float) -> void:
+ DebugDraw3D.scoped_config().set_thickness(debug_thickness).set_center_brightness(debug_center_brightness)
+ if false: #test
+ var _s11 = DebugDraw3D.new_scoped_config().set_thickness(1)
+ if true:
+ pass
+ var _s13 = DebugDraw3D.new_scoped_config()
+ _s13.set_thickness(3)
+
+ _update_keys_just_press()
+
+ if _is_key_just_pressed(KEY_F1):
+ zylann_example = !zylann_example
+
+ # Zylann's example :D
+ if zylann_example:
+ DebugDraw2D.clear_graphs()
+ var _time = Time.get_ticks_msec() / 1000.0
+ var box_pos = Vector3(0, sin(_time * 4), 0)
+ var line_begin = Vector3(-1, sin(_time * 4), 0)
+ var line_end = Vector3(1, cos(_time * 4), 0)
+
+ DebugDraw3D.draw_box(box_pos, Quaternion.IDENTITY, Vector3(1, 2, 1), Color(0, 1, 0))
+ DebugDraw3D.draw_line(line_begin, line_end, Color(1, 1, 0))
+ DebugDraw2D.set_text("Time", _time)
+ DebugDraw2D.set_text("Frames drawn", Engine.get_frames_drawn())
+ DebugDraw2D.set_text("FPS", Engine.get_frames_per_second())
+ DebugDraw2D.set_text("delta", delta)
+ $HitTest.visible = false
+ $LagTest.visible = false
+ return
+
+ $HitTest.visible = true
+ $LagTest.visible = true
+
+ # Testing the rendering layers by showing the image from the second camera inside the 2D panel
+ DebugDraw3D.config.geometry_render_layers = 1 if !Input.is_key_pressed(KEY_ALT) else 0b10010
+ $Panel.visible = Input.is_key_pressed(KEY_ALT)
+ DebugDraw2D.custom_canvas = %CustomCanvas if Input.is_key_pressed(KEY_ALT) else null
+
+ # More property toggles
+ DebugDraw3D.config.freeze_3d_render = Input.is_key_pressed(KEY_DOWN)
+ DebugDraw3D.config.visible_instance_bounds = Input.is_key_pressed(KEY_RIGHT)
+
+ # Regenerate meshes
+ if Input.is_action_just_pressed("ui_end"):
+ DebugDraw3D.regenerate_geometry_meshes()
+
+ # Some property toggles
+ if _is_key_just_pressed(KEY_LEFT):
+ DebugDraw3D.config.use_frustum_culling = !DebugDraw3D.config.use_frustum_culling
+ if _is_key_just_pressed(KEY_UP):
+ DebugDraw3D.config.force_use_camera_from_scene = !DebugDraw3D.config.force_use_camera_from_scene
+ if _is_key_just_pressed(KEY_CTRL):
+ if !Engine.is_editor_hint():
+ get_viewport().msaa_3d = Viewport.MSAA_DISABLED if get_viewport().msaa_3d == Viewport.MSAA_4X else Viewport.MSAA_4X
+
+ if !Engine.is_editor_hint():
+ if _is_key_just_pressed(KEY_1):
+ DebugDraw3D.debug_enabled = !DebugDraw3D.debug_enabled
+ if _is_key_just_pressed(KEY_2):
+ DebugDraw2D.debug_enabled = !DebugDraw2D.debug_enabled
+ if _is_key_just_pressed(KEY_3):
+ DebugDrawManager.debug_enabled = !DebugDrawManager.debug_enabled
+
+
+ DebugDraw3D.config.frustum_length_scale = camera_frustum_scale
+
+ # Zones with black borders
+ for z in $Zones.get_children():
+ DebugDraw3D.draw_box_xf(z.global_transform, Color.BLACK)
+
+ # Spheres
+ DebugDraw3D.draw_sphere_xf($Spheres/SphereTransform.global_transform, Color.CRIMSON)
+ if true:
+ var _shd = DebugDraw3D.new_scoped_config().set_hd_sphere(true)
+ DebugDraw3D.draw_sphere_xf($Spheres/SphereHDTransform.global_transform, Color.ORANGE_RED)
+
+ # Delayed spheres
+ if timer_1 < 0:
+ DebugDraw3D.draw_sphere($Spheres/SpherePosition.global_position, 2.0, Color.BLUE_VIOLET, 2.0)
+ var _shd = DebugDraw3D.new_scoped_config().set_hd_sphere(true)
+ DebugDraw3D.draw_sphere($Spheres/SpherePosition.global_position + Vector3.FORWARD * 4, 2.0, Color.CORNFLOWER_BLUE, 2.0)
+ timer_1 = 2
+
+ # Cylinders
+ DebugDraw3D.draw_cylinder($Cylinders/Cylinder1.global_transform, Color.CRIMSON)
+ DebugDraw3D.draw_cylinder(Transform3D(Basis.IDENTITY.scaled(Vector3(1,2,1)), $Cylinders/Cylinder2.global_position), Color.RED)
+ DebugDraw3D.draw_cylinder_ab($"Cylinders/Cylinder3/1".global_position, $"Cylinders/Cylinder3/2".global_position, 0.7)
+
+ # Boxes
+ DebugDraw3D.draw_box_xf($Boxes/Box1.global_transform, Color.MEDIUM_PURPLE)
+ DebugDraw3D.draw_box($Boxes/Box2.global_position, Quaternion.from_euler(Vector3(0, deg_to_rad(45), deg_to_rad(45))), Vector3.ONE, Color.REBECCA_PURPLE)
+ DebugDraw3D.draw_box_xf(Transform3D(Basis(Vector3.UP, PI * 0.25).scaled(Vector3.ONE * 2), $Boxes/Box3.global_position), Color.ROSY_BROWN)
+
+ DebugDraw3D.draw_aabb(AABB($Boxes/AABB_fixed.global_position, Vector3(2, 1, 2)), Color.AQUA)
+ DebugDraw3D.draw_aabb_ab($Boxes/AABB/a.global_position, $Boxes/AABB/b.global_position, Color.DEEP_PINK)
+
+ # Boxes AB
+ DebugDraw3D.draw_arrow($Boxes/BoxAB.global_position, $Boxes/BoxAB/o/up.global_position, Color.GOLD, 0.1, true)
+ DebugDraw3D.draw_box_ab($Boxes/BoxAB/a.global_position, $Boxes/BoxAB/b.global_position, $Boxes/BoxAB/o/up.global_position - $Boxes/BoxAB.global_position, Color.PERU)
+
+ DebugDraw3D.draw_arrow($Boxes/BoxABEdge.global_position, $Boxes/BoxABEdge/o/up.global_position, Color.DARK_RED, 0.1, true)
+ DebugDraw3D.draw_box_ab($Boxes/BoxABEdge/a.global_position, $Boxes/BoxABEdge/b.global_position, $Boxes/BoxABEdge/o/up.global_position - $Boxes/BoxABEdge.global_position, Color.DARK_OLIVE_GREEN, false)
+
+ # Lines
+ var target = $Lines/Target
+ DebugDraw3D.draw_square(target.global_position, 0.5, Color.RED)
+
+ DebugDraw3D.draw_line($"Lines/1".global_position, target.global_position, Color.FUCHSIA)
+ DebugDraw3D.draw_ray($"Lines/3".global_position, (target.global_position - $"Lines/3".global_position).normalized(), 3.0, Color.CRIMSON)
+
+ if timer_3 < 0:
+ DebugDraw3D.draw_line($"Lines/6".global_position, target.global_position, Color.FUCHSIA, 2.0)
+ timer_3 = 2
+
+ # Test UP vector
+ DebugDraw3D.draw_line($"Lines/7".global_position, target.global_position, Color.RED)
+
+ # Lines with Arrow
+ DebugDraw3D.draw_arrow($"Lines/2".global_position, target.global_position, Color.BLUE, 0.5, true)
+ DebugDraw3D.draw_arrow_ray($"Lines/4".global_position, (target.global_position - $"Lines/4".global_position).normalized(), 8.0, Color.LAVENDER, 0.5, true)
+
+ DebugDraw3D.draw_line_hit_offset($"Lines/5".global_position, target.global_position, true, abs(sin(Time.get_ticks_msec() / 1000.0)), 0.25, Color.AQUA)
+
+ # Path
+
+ ## preparing data
+ var points: PackedVector3Array = []
+ var points_below: PackedVector3Array = []
+ var points_below2: PackedVector3Array = []
+ var points_below3: PackedVector3Array = []
+ var points_below4: PackedVector3Array = []
+ var lines_above: PackedVector3Array = []
+
+ for c in $LinePath.get_children():
+ if not c is Node3D:
+ break
+ points.append(c.global_position)
+ points_below.append(c.global_position + Vector3.DOWN)
+ points_below2.append(c.global_position + Vector3.DOWN * 2)
+ points_below3.append(c.global_position + Vector3.DOWN * 3)
+ points_below4.append(c.global_position + Vector3.DOWN * 4)
+
+ for x in points.size()-1:
+ lines_above.append(points[x] + Vector3.UP)
+ lines_above.append(points[x+1] + Vector3.UP)
+
+ ## drawing lines
+ DebugDraw3D.draw_lines(lines_above)
+ DebugDraw3D.draw_line_path(points, Color.BEIGE)
+ DebugDraw3D.draw_points(points_below, DebugDraw3D.POINT_TYPE_SQUARE, 0.2, Color.DARK_GREEN)
+ DebugDraw3D.draw_point_path(points_below2, DebugDraw3D.POINT_TYPE_SQUARE, 0.25, Color.BLUE, Color.TOMATO)
+ DebugDraw3D.draw_arrow_path(points_below3, Color.GOLD, 0.5)
+ if true:
+ var _sl = DebugDraw3D.new_scoped_config().set_thickness(0.05)
+ DebugDraw3D.draw_point_path(points_below4, DebugDraw3D.POINT_TYPE_SPHERE, 0.25, Color.MEDIUM_SEA_GREEN, Color.MEDIUM_VIOLET_RED)
+
+ # Other world
+
+ if true:
+ var _w1 = DebugDraw3D.new_scoped_config().set_viewport(%OtherWorldBox.get_viewport())
+ DebugDraw3D.draw_box_xf(%OtherWorldBox.global_transform.rotated_local(Vector3(1,1,-1).normalized(), wrapf(Time.get_ticks_msec() / 1000.0, 0, TAU)), Color.SANDY_BROWN)
+ DebugDraw3D.draw_box_xf(%OtherWorldBox.global_transform.rotated_local(Vector3(-1,1,-1).normalized(), wrapf(Time.get_ticks_msec() / -1000.0, 0, TAU) - PI/4), Color.SANDY_BROWN)
+
+ # Misc
+ if Engine.is_editor_hint():
+ #for i in 1000:
+ var _a11 = DebugDraw3D.new_scoped_config().set_thickness(0)
+ DebugDraw3D.draw_camera_frustum($Camera, Color.DARK_ORANGE)
+
+ if true:
+ var _s123 = DebugDraw3D.new_scoped_config().set_center_brightness(0.1)
+ DebugDraw3D.draw_arrowhead($Misc/Arrow.global_transform, Color.YELLOW_GREEN)
+
+ DebugDraw3D.draw_square($Misc/Billboard.global_position, 0.5, Color.GREEN)
+
+ DebugDraw3D.draw_position($Misc/Position.global_transform, Color.BROWN)
+
+ DebugDraw3D.draw_gizmo($Misc/GizmoTransform.global_transform, DebugDraw3D.empty_color, true)
+ DebugDraw3D.draw_gizmo($Misc/GizmoOneColor.global_transform, Color.BROWN, true)
+ if true:
+ var _s123 = DebugDraw3D.new_scoped_config().set_center_brightness(0.5)
+ DebugDraw3D.draw_gizmo($Misc/GizmoNormal.global_transform.orthonormalized(), DebugDraw3D.empty_color, false)
+
+ var tg : Transform3D = $Grids/Grid.global_transform
+ var tn : Vector3 = $Grids/Grid/Subdivision.transform.origin
+ DebugDraw3D.draw_grid(tg.origin, tg.basis.x, tg.basis.z, Vector2i(int(tn.x*10), int(tn.z*10)), Color.LIGHT_CORAL, false)
+
+ var tn1 = $Grids/GridCentered/Subdivision.transform.origin
+ DebugDraw3D.draw_grid_xf($Grids/GridCentered.global_transform, Vector2i(tn1.x*10, tn1.z*10))
+
+ # 2D
+ DebugDraw2D.config.text_default_size = text_groups_default_font_size
+ DebugDraw2D.config.text_block_offset = text_groups_offset
+ DebugDraw2D.config.text_block_position = text_groups_position
+ DebugDraw2D.config.text_padding = text_groups_padding
+
+ DebugDraw2D.config.text_custom_font = custom_font
+
+ if test_text:
+ _text_tests()
+
+ # Graphs
+ # Enable FPSGraph if not exists
+ _create_graph(&"FPS", true, false, DebugDraw2DGraph.TEXT_CURRENT | DebugDraw2DGraph.TEXT_AVG | DebugDraw2DGraph.TEXT_MAX | DebugDraw2DGraph.TEXT_MIN, &"", DebugDraw2DGraph.SIDE_BOTTOM, DebugDraw2DGraph.POSITION_LEFT_TOP if Engine.is_editor_hint() else DebugDraw2DGraph.POSITION_RIGHT_TOP, Vector2i(200, 80), custom_font)
+ if Engine.is_editor_hint():
+ if DebugDraw2D.get_graph(&"FPS"):
+ DebugDraw2D.get_graph(&"FPS").offset = Vector2i(0, 64)
+
+ # Adding more graphs
+ if test_graphs and DebugDraw2D.debug_enabled:
+ _graph_test()
+ else:
+ _remove_graphs()
+ _upd_graph_params()
+
+ # Lag Test
+ $LagTest.position = $LagTest/RESET.get_animation("RESET").track_get_key_value(0,0) + Vector3(sin(Time.get_ticks_msec() / 100.0) * 2.5, 0, 0)
+ DebugDraw3D.draw_box($LagTest.global_position, Quaternion.IDENTITY, Vector3.ONE * 2.01, DebugDraw3D.empty_color, true)
+
+ if more_test_cases:
+ for ray in $HitTest/RayEmitter.get_children():
+ ray.set_physics_process_internal(true)
+
+ _more_tests()
+ else:
+ for ray in $HitTest/RayEmitter.get_children():
+ ray.set_physics_process_internal(false)
+
+ if draw_array_of_boxes:
+ _draw_array_of_boxes()
+
+
+func _text_tests():
+ if timer_text < 0:
+ DebugDraw2D.set_text("Some delayed text", "for 2.5s", -1, Color.BLACK, 2.5) # it's supposed to show text for 2.5 seconds
+ timer_text = 5
+
+ DebugDraw2D.set_text("FPS", "%.2f" % Engine.get_frames_per_second(), 0, Color.GOLD)
+
+ DebugDraw2D.begin_text_group("-- First Group --", 2, Color.LIME_GREEN, true, text_groups_title_font_size, text_groups_text_font_size)
+ DebugDraw2D.set_text("Simple text")
+ DebugDraw2D.set_text("Text", "Value", 0, Color.AQUAMARINE)
+ DebugDraw2D.set_text("Text out of order", null, -1, Color.SILVER)
+ DebugDraw2D.begin_text_group("-- Second Group --", 1, Color.BEIGE)
+ DebugDraw2D.set_text("Rendered frames", Engine.get_frames_drawn())
+ DebugDraw2D.end_text_group()
+
+ if text_groups_show_stats or text_groups_show_stats_2d:
+ DebugDraw2D.begin_text_group("-- Stats --", 3, Color.WHEAT)
+
+ var render_stats := DebugDraw3D.get_render_stats()
+ if render_stats && text_groups_show_stats:
+ DebugDraw2D.set_text("Total", render_stats.total_geometry)
+ DebugDraw2D.set_text("Instances", render_stats.instances + render_stats.instances_physics, 1)
+ DebugDraw2D.set_text("Lines", render_stats.lines + render_stats.lines_physics, 2)
+ DebugDraw2D.set_text("Total Visible", render_stats.total_visible, 3)
+ DebugDraw2D.set_text("Visible Instances", render_stats.visible_instances, 4)
+ DebugDraw2D.set_text("Visible Lines", render_stats.visible_lines, 5)
+
+ DebugDraw2D.set_text("---", null, 6)
+
+ DebugDraw2D.set_text("Culling time", "%.2f ms" % (render_stats.total_time_culling_usec / 1000.0), 7)
+ DebugDraw2D.set_text("Filling instances buffer", "%.2f ms" % (render_stats.time_filling_buffers_instances_usec / 1000.0), 8)
+ DebugDraw2D.set_text("Filling lines buffer", "%.2f ms" % (render_stats.time_filling_buffers_lines_usec / 1000.0), 9)
+ DebugDraw2D.set_text("Filling time", "%.2f ms" % (render_stats.total_time_filling_buffers_usec / 1000.0), 10)
+ DebugDraw2D.set_text("Total time", "%.2f ms" % (render_stats.total_time_spent_usec / 1000.0), 11)
+
+ DebugDraw2D.set_text("---", null, 14)
+
+ DebugDraw2D.set_text("Created scoped configs", "%d" % render_stats.created_scoped_configs, 15)
+
+ if text_groups_show_stats && text_groups_show_stats_2d:
+ DebugDraw2D.set_text("----", null, 19)
+
+ var render_stats_2d := DebugDraw2D.get_render_stats()
+ if render_stats_2d && text_groups_show_stats_2d:
+ DebugDraw2D.set_text("Text groups", render_stats_2d.overlay_text_groups, 20)
+ DebugDraw2D.set_text("Text lines", render_stats_2d.overlay_text_lines, 21)
+ DebugDraw2D.set_text("Graphs total", render_stats_2d.overlay_graphs_total, 22)
+ DebugDraw2D.set_text("Graphs enabled", render_stats_2d.overlay_graphs_enabled, 23)
+
+ DebugDraw2D.end_text_group()
+
+ if text_groups_show_hints:
+ DebugDraw2D.begin_text_group("controls", 1024, Color.WHITE, false)
+ if not Engine.is_editor_hint():
+ DebugDraw2D.set_text("WASD QE, LMB", "To move", 0)
+ DebugDraw2D.set_text("Alt: change render layers", DebugDraw3D.config.geometry_render_layers, 1)
+ if not OS.has_feature("web"):
+ DebugDraw2D.set_text("Ctrl: toggle anti-aliasing", "MSAA 4x" if get_viewport().msaa_3d == Viewport.MSAA_4X else "Disabled", 2)
+ DebugDraw2D.set_text("Down: freeze render", DebugDraw3D.config.freeze_3d_render, 3)
+ if Engine.is_editor_hint():
+ DebugDraw2D.set_text("Up: use scene camera", DebugDraw3D.config.force_use_camera_from_scene, 4)
+ DebugDraw2D.set_text("1,2,3: toggle debug", "%s, %s 😐, %s 😏" % [DebugDraw3D.debug_enabled, DebugDraw2D.debug_enabled, DebugDrawManager.debug_enabled], 5)
+ DebugDraw2D.set_text("Left: toggle frustum culling", DebugDraw3D.config.use_frustum_culling, 6)
+ DebugDraw2D.set_text("Right: draw bounds for culling", DebugDraw3D.config.visible_instance_bounds, 7)
+ DebugDraw2D.end_text_group()
+
+
+func _draw_rays_casts():
+ # Line hits render
+ for ray in $HitTest/RayEmitter.get_children():
+ if ray is RayCast3D:
+ ray.force_raycast_update()
+ DebugDraw3D.draw_line_hit(ray.global_position, ray.to_global(ray.target_position), ray.get_collision_point(), ray.is_colliding(), 0.3)
+
+
+func _more_tests():
+ # Delayed line render
+ if true:
+ var _a12 = DebugDraw3D.new_scoped_config().set_thickness(0.035)
+ DebugDraw3D.draw_line($LagTest.global_position + Vector3.UP, $LagTest.global_position + Vector3(0,3,sin(Time.get_ticks_msec() / 50.0)), DebugDraw3D.empty_color, 0.5)
+
+ # Draw plane
+ if true:
+ var _s11 = DebugDraw3D.new_scoped_config().set_thickness(0.02).set_plane_size(10)
+
+ var pl_node: Node3D = $PlaneOrigin
+ var xf: Transform3D = pl_node.global_transform
+ var normal: = xf.basis.y.normalized()
+ var plane = Plane(normal, xf.origin.dot(normal))
+
+ var vp: Viewport = get_viewport()
+ if is_4_2_and_higher:
+ if Engine.is_editor_hint() and Engine.get_singleton(&"EditorInterface").get_editor_viewport_3d(0):
+ vp = Engine.get_singleton(&"EditorInterface").get_editor_viewport_3d(0)
+
+ var cam = vp.get_camera_3d()
+ if cam:
+ var dir = vp.get_camera_3d().project_ray_normal(vp.get_mouse_position())
+ var intersect = plane.intersects_ray(cam.global_position, dir)
+
+ DebugDraw3D.draw_plane(plane, Color.CORAL * Color(1,1,1, 0.4), pl_node.global_position)
+ if is_4_2_and_higher:
+ if intersect and intersect.distance_to(pl_node.global_position) < _s11.get_plane_size() * 0.5:
+ # Need to test different colors on both sides of the plane
+ var col = Color.FIREBRICK if plane.is_point_over(cam.global_position) else Color.AQUAMARINE
+ DebugDraw3D.draw_sphere(intersect, 0.3, col)
+
+
+func _draw_array_of_boxes():
+ # Lots of boxes to check performance..
+ var x_size := 50
+ var y_size := 50
+ var z_size := 3
+ var mul := 1
+ var cubes_max_time := 1.25
+ var cfg = DebugDraw3D.new_scoped_config()
+
+ if draw_1m_boxes:
+ x_size = 100
+ y_size = 100
+ z_size = 100
+ mul = 4
+ cubes_max_time = 60
+
+ if timer_cubes < 0:
+ for x in x_size:
+ for y in y_size:
+ for z in z_size:
+ var size = Vector3.ONE
+ cfg.set_thickness(randf_range(0, 0.1))
+ #var size = Vector3(randf_range(0.1, 100),randf_range(0.1, 100),randf_range(0.1, 100))
+ DebugDraw3D.draw_box(Vector3(x * mul, (-4-z) * mul, y * mul), Quaternion.IDENTITY, size, DebugDraw3D.empty_color, false, cubes_max_time)
+ timer_cubes = cubes_max_time
+
+
+func _graph_test():
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps", true, true, DebugDraw2DGraph.TEXT_CURRENT, &"", DebugDraw2DGraph.SIDE_LEFT, DebugDraw2DGraph.POSITION_RIGHT_TOP)
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps2", true, false, DebugDraw2DGraph.TEXT_CURRENT, &"fps", DebugDraw2DGraph.SIDE_BOTTOM, 0, Vector2i(200, 100))
+# warning-ignore:return_value_discarded
+ _create_graph(&"Sin Wave!", false, true, DebugDraw2DGraph.TEXT_CURRENT, &"fps2", DebugDraw2DGraph.SIDE_BOTTOM)
+
+# warning-ignore:return_value_discarded
+ _create_graph(&"randf", false, true, DebugDraw2DGraph.TEXT_AVG, &"", DebugDraw2DGraph.SIDE_LEFT, DebugDraw2DGraph.POSITION_RIGHT_BOTTOM, Vector2i(256, 60), custom_font)
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps5", true, true, DebugDraw2DGraph.TEXT_ALL, &"randf", DebugDraw2DGraph.SIDE_TOP)
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps6", true, true, DebugDraw2DGraph.TEXT_ALL, &"fps5", DebugDraw2DGraph.SIDE_TOP)
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps12", true, true, DebugDraw2DGraph.TEXT_ALL, &"fps5", DebugDraw2DGraph.SIDE_LEFT)
+
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps7", true, false, DebugDraw2DGraph.TEXT_ALL, &"FPS", DebugDraw2DGraph.SIDE_BOTTOM)
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps8", true, true, DebugDraw2DGraph.TEXT_ALL, &"", DebugDraw2DGraph.SIDE_TOP, DebugDraw2DGraph.POSITION_LEFT_BOTTOM)
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps9", true, false, DebugDraw2DGraph.TEXT_ALL, &"fps8", DebugDraw2DGraph.SIDE_RIGHT)
+# warning-ignore:return_value_discarded
+ _create_graph(&"fps10", true, false, DebugDraw2DGraph.TEXT_ALL, &"fps8", DebugDraw2DGraph.SIDE_TOP)
+ # warning-ignore:return_value_discarded
+ _create_graph(&"fps11", true, true, DebugDraw2DGraph.TEXT_ALL, &"fps9", DebugDraw2DGraph.SIDE_RIGHT)
+ # warning-ignore:return_value_discarded
+ _create_graph(&"fps13", true, true, DebugDraw2DGraph.TEXT_ALL, &"", DebugDraw2DGraph.SIDE_RIGHT)
+ if not DebugDraw2D.get_graph(&"fps13"):
+ return
+
+ DebugDraw2D.get_graph(&"fps13").enabled = false
+
+ # If graphs exists, then more tests are done
+ DebugDraw2D.get_graph(&"Sin Wave!").data_getter = Callable(self, &"_get_sin_wave_for_graph")
+ DebugDraw2D.get_graph(&"Sin Wave!").upside_down =false
+
+ DebugDraw2D.get_graph(&"randf").text_suffix = "utf8 ноль zéro"
+ #DebugDraw2D.get_graph(&"fps9").line_position = DebugDraw2DGraph.LINE_TOP
+ DebugDraw2D.get_graph(&"fps9").offset = Vector2i(0, 0)
+ #DebugDraw2D.get_graph(&"fps11").line_position = DebugDraw2DGraph.LINE_BOTTOM
+ DebugDraw2D.get_graph(&"fps11").offset = Vector2i(16, 0)
+ DebugDraw2D.get_graph(&"fps6").offset = Vector2i(0, 32)
+ DebugDraw2D.get_graph(&"fps").offset = Vector2i(16, 72)
+
+ DebugDraw2D.get_graph(&"fps9").enabled = graph_is_enabled
+ if !Engine.is_editor_hint():
+ DebugDraw2D.get_graph(&"fps").corner = DebugDraw2DGraph.POSITION_LEFT_TOP
+
+ # Just sending random data to the graph
+ DebugDraw2D.graph_update_data(&"randf", randf())
+
+
+func _upd_graph_params():
+ DebugDraw2D.config.graphs_base_offset = graph_offset
+ for g in [&"FPS", &"fps5", &"fps8"]:
+ var graph := DebugDraw2D.get_graph(g) as DebugDraw2DFPSGraph
+ if graph:
+ graph.size = graph_size
+ graph.title_size = graph_title_font_size
+ graph.text_size = graph_text_font_size
+ graph.line_width = graph_line_width
+ graph.text_precision = graph_text_precision
+ graph.buffer_size = graph_buffer_size
+ if Engine.is_editor_hint() or g != &"FPS":
+ graph.frame_time_mode = graph_frame_time_mode
+
+
+func _get_sin_wave_for_graph() -> float:
+ var mul = 4 if Input.is_key_pressed(KEY_END) else 2
+ return sin(Engine.get_frames_drawn() * 0.5) * mul
+
+
+func _remove_graphs():
+ DebugDraw2D.remove_graph(&"randf")
+ DebugDraw2D.remove_graph(&"fps")
+ DebugDraw2D.remove_graph(&"fps2")
+ DebugDraw2D.remove_graph(&"Sin Wave!")
+ DebugDraw2D.remove_graph(&"fps5")
+ DebugDraw2D.remove_graph(&"fps6")
+ DebugDraw2D.remove_graph(&"fps7")
+ DebugDraw2D.remove_graph(&"fps8")
+ DebugDraw2D.remove_graph(&"fps9")
+ DebugDraw2D.remove_graph(&"fps10")
+ DebugDraw2D.remove_graph(&"fps11")
+ DebugDraw2D.remove_graph(&"fps12")
+ DebugDraw2D.remove_graph(&"fps13")
+
+
+func _create_graph(title, is_fps, show_title, flags, parent := &"", parent_side := DebugDraw2DGraph.SIDE_BOTTOM, pos = DebugDraw2DGraph.POSITION_LEFT_BOTTOM, size := Vector2i(256, 60), font = null) -> DebugDraw2DGraph:
+ var graph := DebugDraw2D.get_graph(title)
+ if !graph:
+ if is_fps:
+ graph = DebugDraw2D.create_fps_graph(title)
+ else:
+ graph = DebugDraw2D.create_graph(title)
+
+ if graph:
+ graph.size = size
+ graph.buffer_size = 50
+ graph.corner = pos
+ graph.show_title = show_title
+ graph.show_text_flags = flags
+ graph.custom_font = font
+ graph.set_parent(parent, parent_side)
+
+ return graph
+
+
+func _ready() -> void:
+ _update_keys_just_press()
+
+ await get_tree().process_frame
+
+ # this check is required for inherited scenes, because an instance of this
+ # script is created first, and then overridden by another
+ if !is_inside_tree():
+ return
+
+
+func _is_key_just_pressed(key):
+ if (button_presses[key] == 1):
+ button_presses[key] = 2
+ return true
+ return false
+
+
+func _update_keys_just_press():
+ var set_key = func (k: Key):
+ if Input.is_key_pressed(k) and button_presses.has(k):
+ if button_presses[k] == 0:
+ return 1
+ else:
+ return button_presses[k]
+ else:
+ return 0
+ button_presses[KEY_LEFT] = set_key.call(KEY_LEFT)
+ button_presses[KEY_UP] = set_key.call(KEY_UP)
+ button_presses[KEY_CTRL] = set_key.call(KEY_CTRL)
+ button_presses[KEY_F1] = set_key.call(KEY_F1)
+ button_presses[KEY_1] = set_key.call(KEY_1)
+ button_presses[KEY_2] = set_key.call(KEY_2)
+ button_presses[KEY_3] = set_key.call(KEY_3)
+
+
+func _update_timers(delta : float):
+ timer_1 -= delta
+ timer_cubes -= delta
+ timer_3 -= delta
+ timer_text -= delta
diff --git a/examples_dd3d/DebugDrawDemoScene.tscn b/examples_dd3d/DebugDrawDemoScene.tscn
new file mode 100644
index 0000000..a410a81
--- /dev/null
+++ b/examples_dd3d/DebugDrawDemoScene.tscn
@@ -0,0 +1,939 @@
+[gd_scene load_steps=35 format=3 uid="uid://c3sccy6x0ht5j"]
+
+[ext_resource type="Script" path="res://examples_dd3d/DebugDrawDemoScene.gd" id="1"]
+[ext_resource type="FontFile" uid="uid://erdgllynwqkw" path="res://examples_dd3d/Roboto-Bold.ttf" id="2_aedbq"]
+[ext_resource type="Script" path="res://examples_dd3d/demo_camera_movement.gd" id="3_3m1mp"]
+[ext_resource type="Script" path="res://examples_dd3d/demo_music_visualizer.gd" id="4_eq2lt"]
+[ext_resource type="Script" path="res://examples_dd3d/demo_settings_panel.gd" id="5_31v5h"]
+[ext_resource type="Script" path="res://examples_dd3d/demo_web_docs_version_select.gd" id="6_07f7q"]
+
+[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_87638"]
+sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
+ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
+
+[sub_resource type="Sky" id="Sky_4jfme"]
+sky_material = SubResource("ProceduralSkyMaterial_87638")
+
+[sub_resource type="Environment" id="Environment_38m85"]
+sky = SubResource("Sky_4jfme")
+tonemap_mode = 2
+
+[sub_resource type="Animation" id="9"]
+resource_name = "New Anim"
+length = 1.5
+loop_mode = 1
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Spatial2:transform")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 0.7),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0.31558, 1)]
+}
+tracks/1/type = "value"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("Spatial5:transform")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0, 0.5),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1, 1), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1.5801, 1)]
+}
+tracks/2/type = "value"
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/path = NodePath("Spatial4:transform")
+tracks/2/interp = 1
+tracks/2/loop_wrap = true
+tracks/2/keys = {
+"times": PackedFloat32Array(0, 1),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, 0, 1.53767), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, -0.791383, 1.53767)]
+}
+tracks/3/type = "value"
+tracks/3/imported = false
+tracks/3/enabled = true
+tracks/3/path = NodePath("Spatial7:position")
+tracks/3/interp = 1
+tracks/3/loop_wrap = true
+tracks/3/keys = {
+"times": PackedFloat32Array(0.4, 1),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Vector3(1.33, -0.119, -0.025), Vector3(1.32989, -0.583818, -0.025198)]
+}
+
+[sub_resource type="Animation" id="10"]
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Spatial2:transform")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1)]
+}
+tracks/1/type = "value"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("Spatial5:transform")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1, 1)]
+}
+tracks/2/type = "value"
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/path = NodePath("Spatial4:transform")
+tracks/2/interp = 1
+tracks/2/loop_wrap = true
+tracks/2/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, 0, 1.53767)]
+}
+tracks/3/type = "value"
+tracks/3/imported = false
+tracks/3/enabled = true
+tracks/3/path = NodePath("Spatial7:position")
+tracks/3/interp = 1
+tracks/3/loop_wrap = true
+tracks/3/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(1.32989, -0.583818, -0.025198)]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_nj4nv"]
+_data = {
+"New Anim": SubResource("9"),
+"RESET": SubResource("10")
+}
+
+[sub_resource type="Shader" id="Shader_621vv"]
+code = "shader_type spatial;
+render_mode unshaded;
+
+uniform sampler2D albedo_texture : source_color;
+
+void fragment() {
+ ALBEDO = texture(albedo_texture,UV).rgb;
+}
+"
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_ho0aq"]
+render_priority = 0
+shader = SubResource("Shader_621vv")
+
+[sub_resource type="PlaneMesh" id="PlaneMesh_c6mie"]
+material = SubResource("ShaderMaterial_ho0aq")
+size = Vector2(4, 4)
+
+[sub_resource type="Animation" id="Animation_ucqh5"]
+resource_name = "RESET"
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:mesh:material:shader_parameter/albedo_texture")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 1,
+"values": [null]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_cq37i"]
+_data = {
+"RESET": SubResource("Animation_ucqh5")
+}
+
+[sub_resource type="CapsuleMesh" id="CapsuleMesh_tigpa"]
+
+[sub_resource type="SphereShape3D" id="4"]
+radius = 1.0
+
+[sub_resource type="StandardMaterial3D" id="5"]
+transparency = 1
+albedo_color = Color(0.54902, 0.54902, 0.729412, 0.403922)
+emission_enabled = true
+emission = Color(0.752941, 0.741176, 0.862745, 1)
+
+[sub_resource type="Animation" id="6"]
+resource_name = "New Anim"
+length = 3.0
+loop_mode = 1
+tracks/0/type = "rotation_3d"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("RayEmitter")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1, 1.3, 1, 1.31237e-06, -9.55543e-07, -2.2333e-06, 1, 2.3, 1, -0.158418, 0.0315871, 0.980558, -0.111409)
+tracks/1/type = "position_3d"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("RayEmitter")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = PackedFloat32Array(0, 1, -1.03574, 2.47907, -0.819963, 0.5, 1, 0.914907, 1.78507, -0.103575, 1.3, 1, 0.00863326, 2.47907, -0.595551, 2.3, 1, 1.00051, 1.4046, 1.02585)
+
+[sub_resource type="Animation" id="7"]
+length = 0.001
+tracks/0/type = "position_3d"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("RayEmitter")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = PackedFloat32Array(0, 1, -1.03574, 2.47907, -0.819963)
+tracks/1/type = "rotation_3d"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("RayEmitter")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1)
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_vh8ml"]
+_data = {
+"New Anim": SubResource("6"),
+"RESET": SubResource("7")
+}
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_rbfyn"]
+transparency = 1
+cull_mode = 2
+shading_mode = 0
+albedo_color = Color(0.215686, 0.215686, 0.215686, 0.764706)
+
+[sub_resource type="QuadMesh" id="QuadMesh_1t0id"]
+material = SubResource("StandardMaterial3D_rbfyn")
+orientation = 1
+
+[sub_resource type="StandardMaterial3D" id="1"]
+shading_mode = 0
+albedo_color = Color(0.533333, 0.105882, 0.105882, 1)
+
+[sub_resource type="Animation" id="8"]
+resource_name = "RESET"
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:position")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(7, -2, 0)]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_a7f1a"]
+_data = {
+"RESET": SubResource("8")
+}
+
+[sub_resource type="Gradient" id="Gradient_tup4c"]
+offsets = PackedFloat32Array(0.00471698, 0.316038, 0.646226, 1)
+colors = PackedColorArray(0, 0.0156863, 1, 1, 0.0988327, 1, 0.122977, 1, 1, 0.111986, 0.118936, 1, 0, 0.0156863, 1, 1)
+
+[sub_resource type="Animation" id="Animation_n750a"]
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("../MusicPlayer:stream")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 1,
+"values": [null]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_0ity1"]
+_data = {
+"RESET": SubResource("Animation_n750a")
+}
+
+[sub_resource type="Theme" id="3"]
+
+[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_oj5gf"]
+content_margin_top = 5.0
+content_margin_bottom = 7.0
+
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_boyhr"]
+content_margin_left = 5.0
+content_margin_top = 5.0
+content_margin_right = 5.0
+content_margin_bottom = 5.0
+bg_color = Color(0.0705882, 0.0705882, 0.0705882, 0.784314)
+corner_radius_top_left = 4
+corner_radius_top_right = 4
+corner_radius_bottom_right = 4
+corner_radius_bottom_left = 4
+
+[node name="DebugDrawDemoScene" type="Node3D"]
+process_priority = 1
+script = ExtResource("1")
+custom_font = ExtResource("2_aedbq")
+text_groups_position = 2
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0)
+visible = false
+directional_shadow_max_distance = 200.0
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_38m85")
+
+[node name="Camera" type="Camera3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 0.953191, 0.30237, 0, -0.30237, 0.953191, -6.988, 10.986, 29.2059)
+cull_mask = 1
+current = true
+fov = 53.0
+far = 100.0
+script = ExtResource("3_3m1mp")
+
+[node name="Panel" type="PanelContainer" parent="."]
+visible = false
+custom_minimum_size = Vector2(300, 300)
+anchors_preset = 2
+anchor_top = 1.0
+anchor_bottom = 1.0
+offset_top = -300.0
+offset_right = 300.0
+grow_vertical = 0
+
+[node name="ViewportContainer" type="SubViewportContainer" parent="Panel"]
+layout_mode = 2
+
+[node name="Viewport" type="SubViewport" parent="Panel/ViewportContainer"]
+handle_input_locally = false
+size = Vector2i(300, 300)
+render_target_update_mode = 0
+
+[node name="CameraLayer2_5" type="Camera3D" parent="Panel/ViewportContainer/Viewport"]
+transform = Transform3D(1, 0, 0, 0, 0.34202, 0.939693, 0, -0.939693, 0.34202, -3.988, 39.474, 14.053)
+cull_mask = 2
+current = true
+fov = 38.8
+near = 2.63
+far = 52.5
+
+[node name="Zones" type="Node3D" parent="."]
+
+[node name="Spheres" type="Node3D" parent="Zones"]
+transform = Transform3D(8.3761, 0, 0, 0, 4.89771, 0, 0, 0, 9.36556, -11.1864, 0.645876, -7.86506)
+
+[node name="Path" type="Node3D" parent="Zones"]
+transform = Transform3D(5.95153, 0, 0, 0, 7.71864, 0, 0, 0, 6.31617, 0.184938, 1.12881, -7.18731)
+
+[node name="Boxes" type="Node3D" parent="Zones"]
+transform = Transform3D(10.0513, 0, 0, 0, 5.99877, 0, 0, 0, 12.1174, -16.0257, -0.206735, 6.27643)
+
+[node name="Misc" type="Node3D" parent="Zones"]
+transform = Transform3D(4.38886, 0, 0, 0, 2.72083, 0, 0, 0, 7.17107, -5.69728, -0.206735, 4.4244)
+
+[node name="Cylinders" type="Node3D" parent="Zones"]
+transform = Transform3D(9.78549, 0, 0, 0, 4.20302, 0, 0, 0, 5.62455, -23.6827, -0.015712, -6.19233)
+
+[node name="Lines" type="Node3D" parent="Zones"]
+transform = Transform3D(10.7186, 0, 0, 0, 3.9777, 0, 0, 0, 7.05487, 10.6302, 1.91174, -7.11416)
+
+[node name="Label3D" type="Label3D" parent="."]
+transform = Transform3D(1, -1.93359e-07, -8.48396e-08, -1.17881e-07, 1, 5.96046e-08, 6.22839e-09, 0, 1, 0, 0, 0)
+visible = false
+pixel_size = 0.0025
+billboard = 1
+double_sided = false
+modulate = Color(0, 0, 0, 1)
+outline_modulate = Color(1, 1, 1, 1)
+text = "TestTestTestTest
+TestTestTest"
+font_size = 80
+
+[node name="LinesAnim" type="AnimationPlayer" parent="."]
+root_node = NodePath("../LinePath")
+libraries = {
+"": SubResource("AnimationLibrary_nj4nv")
+}
+autoplay = "New Anim"
+
+[node name="LinePath" type="Node3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.0543, -8)
+
+[node name="Spatial" type="Node3D" parent="LinePath"]
+
+[node name="Spatial2" type="Node3D" parent="LinePath"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1)
+
+[node name="Spatial3" type="Node3D" parent="LinePath"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.462435, 0, 3)
+
+[node name="Spatial4" type="Node3D" parent="LinePath"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, 0, 1.53767)
+
+[node name="Spatial5" type="Node3D" parent="LinePath"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1, 1)
+
+[node name="Spatial6" type="Node3D" parent="LinePath"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, -1)
+
+[node name="Spatial7" type="Node3D" parent="LinePath"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.32989, -0.583818, -0.025198)
+
+[node name="Cylinders" type="Node3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -23.5266, 4.76837e-07, -5.82213)
+
+[node name="Cylinder1" type="Node3D" parent="Cylinders"]
+transform = Transform3D(1.20775, 0.591481, -3.4521e-07, 0.554162, -1.12986, 0.858242, 0.208031, -0.424147, -2.28622, -3.03832, 0, -0.377882)
+
+[node name="Cylinder2" type="Node3D" parent="Cylinders"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.234978, -0.4237, 0.332998)
+
+[node name="Cylinder3" type="Node3D" parent="Cylinders"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.35527, -0.655492, -0.352802)
+
+[node name="1" type="Node3D" parent="Cylinders/Cylinder3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.419773, -2.38419e-07, -1.40591)
+
+[node name="2" type="Node3D" parent="Cylinders/Cylinder3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.01018, 0.486778, 1.32635)
+
+[node name="Spheres" type="Node3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.1201, 0.166728, -7.893)
+
+[node name="SphereTransform" type="Node3D" parent="Spheres"]
+transform = Transform3D(3.018, 0, 0, 0, 0.945452, -3.30182, 0, 1.04515, 2.98686, -2.14465, 4.76837e-07, 2.11952)
+
+[node name="SphereHDTransform" type="Node3D" parent="Spheres"]
+transform = Transform3D(1.26984, 1.16629, -2.42095, 0.098772, 0.80937, 4.21576, -2.65493, 0.587941, -1.00109, -2.13175, 4.76837e-07, -2.62531)
+
+[node name="SpherePosition" type="Node3D" parent="Spheres"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.76745, 0.458486, 1.95921)
+
+[node name="Boxes" type="Node3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.2493, 0, 6.42043)
+
+[node name="Box1" type="Node3D" parent="Boxes"]
+transform = Transform3D(2.90583, -0.000527017, -5.34615, 0.00469241, 3.92788, 0.0141019, 0.556318, -0.0303774, 1.91619, -0.961557, 0, -3.78672)
+rotation_edit_mode = 2
+
+[node name="Box2" type="Node3D" parent="Boxes"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.531922, -1.34723, 1.44924)
+
+[node name="Box3" type="Node3D" parent="Boxes"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.34837, -1.08298, 4.36414)
+
+[node name="AABB_fixed" type="Node3D" parent="Boxes"]
+transform = Transform3D(0.834492, 0, -0.551019, 0, 1, 0, 0.55102, 0, 0.834493, -3.71325, -1.03995, 0.470324)
+
+[node name="AABB" type="Node3D" parent="Boxes"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.99963, -0.869998, 0.205034)
+
+[node name="a" type="Node3D" parent="Boxes/AABB"]
+transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, 1.48526, -1.45318, 1.96619)
+
+[node name="b" type="Node3D" parent="Boxes/AABB"]
+transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, -1.24128, 1.47773, -2.13102)
+
+[node name="BoxAB" type="Node3D" parent="Boxes"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.66169, -2.2624, 4.04042)
+
+[node name="a" type="Node3D" parent="Boxes/BoxAB"]
+transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, 0.556136, -0.666145, 0.951601)
+
+[node name="b" type="Node3D" parent="Boxes/BoxAB"]
+transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, -0.548804, 0.715255, -0.942184)
+
+[node name="o" type="Node3D" parent="Boxes/BoxAB"]
+transform = Transform3D(0.826805, 0.360538, 0.431748, -0.102949, 0.851596, -0.51399, -0.552988, 0.380522, 0.741221, 0, 0, 0)
+metadata/_edit_group_ = true
+
+[node name="up" type="Node3D" parent="Boxes/BoxAB/o"]
+transform = Transform3D(1, -1.49012e-08, 0, -1.04308e-07, 1, 0, 0, 0, 1, 0, 0.553809, -0.331842)
+
+[node name="BoxABEdge" type="Node3D" parent="Boxes"]
+transform = Transform3D(0.965926, -0.0669873, -0.25, 0, 0.965926, -0.258819, 0.258819, 0.25, 0.933013, 0.348115, -1.30239, 4.88007)
+
+[node name="a" type="Node3D" parent="Boxes/BoxABEdge"]
+transform = Transform3D(0.241143, 0.650584, 0.720132, -0.123077, 0.756539, -0.642262, -0.962654, 0.066246, 0.262507, 0.384618, -0.635015, 0.0956135)
+
+[node name="b" type="Node3D" parent="Boxes/BoxABEdge"]
+transform = Transform3D(0.241143, 0.650584, 0.720133, -0.123077, 0.756539, -0.642261, -0.962654, 0.0662459, 0.262507, -0.287622, 0.997905, -0.144578)
+
+[node name="o" type="Node3D" parent="Boxes/BoxABEdge"]
+transform = Transform3D(1, 1.49012e-08, 2.98023e-08, 7.45058e-09, 1, -1.49012e-08, -1.49012e-08, -1.49012e-08, 1, 0, 0, 0)
+metadata/_edit_group_ = true
+
+[node name="up" type="Node3D" parent="Boxes/BoxABEdge/o"]
+transform = Transform3D(1, -7.45058e-09, 0, -7.45058e-09, 1, 0, 2.98023e-08, -1.49012e-08, 1, -9.53674e-07, 0.6, 0)
+
+[node name="OtherWorld" type="MeshInstance3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.53219, -2.5, 5.30229)
+mesh = SubResource("PlaneMesh_c6mie")
+skeleton = NodePath("")
+
+[node name="RESET" type="AnimationPlayer" parent="OtherWorld"]
+libraries = {
+"": SubResource("AnimationLibrary_cq37i")
+}
+
+[node name="SubViewport" type="SubViewport" parent="OtherWorld"]
+own_world_3d = true
+render_target_update_mode = 4
+
+[node name="Camera3D" type="Camera3D" parent="OtherWorld/SubViewport"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57063, 0.6, 7.25557)
+current = true
+far = 5.0
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="OtherWorld/SubViewport"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57063, 0.6, 4.85623)
+mesh = SubResource("CapsuleMesh_tigpa")
+
+[node name="OtherWorldBox" type="Node3D" parent="OtherWorld/SubViewport"]
+unique_name_in_owner = true
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57063, 0.6, 5.72253)
+
+[node name="Misc" type="Node3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.68259, 0, 4.46741)
+
+[node name="Billboard" type="Node3D" parent="Misc"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.403353, -0.331599, 2.22542)
+
+[node name="Arrow" type="Node3D" parent="Misc"]
+transform = Transform3D(0.802141, -0.286294, -0.524028, -0.539546, 0.0285125, -0.841473, 0.25585, 0.957718, -0.131597, -0.475607, -0.670307, 2.30581)
+
+[node name="Position" type="Node3D" parent="Misc"]
+transform = Transform3D(1.51514, 0.589536, 1.00858, -1.34875, 0.662262, 1.133, 0, -0.462445, 2.90833, 0.853743, -0.331599, -1.73676)
+
+[node name="GizmoNormal" type="Node3D" parent="Misc"]
+transform = Transform3D(1.95938, 0, -0.848962, 0, 0.999999, 0, 0.525014, 0, 3.16837, 0.890203, -0.306246, 0.356159)
+
+[node name="GizmoTransform" type="Node3D" parent="Misc"]
+transform = Transform3D(0.879881, 0.248446, -0.405072, -0.346604, 0.918688, -0.189411, 0.325077, 0.307059, 0.894449, -0.838587, -0.458, -0.176491)
+
+[node name="GizmoOneColor" type="Node3D" parent="Misc"]
+transform = Transform3D(0.385568, 0.0415614, 0.921743, 0.082879, 0.993386, -0.0794599, -0.91895, 0.107031, 0.379573, -0.838587, -0.139425, -1.93055)
+
+[node name="HitTest" type="Node3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.724359, -1.03227, 7.85404)
+
+[node name="StaticBody" type="StaticBody3D" parent="HitTest"]
+
+[node name="CollisionShape" type="CollisionShape3D" parent="HitTest/StaticBody"]
+shape = SubResource("4")
+
+[node name="CSGSphere" type="CSGSphere3D" parent="HitTest/StaticBody"]
+radius = 1.0
+radial_segments = 16
+rings = 10
+material = SubResource("5")
+
+[node name="RayEmitter" type="Node3D" parent="HitTest"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.03574, 2.47907, -0.819963)
+
+[node name="RayCast" type="RayCast3D" parent="HitTest/RayEmitter"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.732104, 0, -0.814761)
+enabled = false
+target_position = Vector3(0, -3.464, 0)
+
+[node name="RayCast2" type="RayCast3D" parent="HitTest/RayEmitter"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.684873, 0, -0.791145)
+enabled = false
+target_position = Vector3(0, -3.464, 0)
+
+[node name="RayCast3" type="RayCast3D" parent="HitTest/RayEmitter"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.708488, 0, 0.543175)
+enabled = false
+target_position = Vector3(0, -3.464, 0)
+
+[node name="RayCast4" type="RayCast3D" parent="HitTest/RayEmitter"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.708489, 0, 0.566791)
+enabled = false
+target_position = Vector3(0, -3.464, 0)
+
+[node name="RayCast5" type="RayCast3D" parent="HitTest/RayEmitter"]
+transform = Transform3D(0.974217, -0.225614, 0, 0.225614, 0.974217, 0, 0, 0, 1, -0.447564, 0, -0.259778)
+enabled = false
+target_position = Vector3(0, -3.464, 0)
+
+[node name="RayCast6" type="RayCast3D" parent="HitTest/RayEmitter"]
+transform = Transform3D(0.935992, 0.352021, 0, -0.352021, 0.935992, 0, 0, 0, 1, 0.35227, -0.245904, -0.25849)
+enabled = false
+target_position = Vector3(0, -3.464, 0)
+
+[node name="RayEmitterAnimationPlayer" type="AnimationPlayer" parent="HitTest"]
+unique_name_in_owner = true
+libraries = {
+"": SubResource("AnimationLibrary_vh8ml")
+}
+autoplay = "New Anim"
+
+[node name="Grids" type="Node3D" parent="."]
+transform = Transform3D(0.707106, 0, -0.707108, 0, 1, 0, 0.707108, 0, 0.707106, 0.730597, -2.5, 2.76274)
+
+[node name="GridCentered" type="Node3D" parent="Grids"]
+transform = Transform3D(1.74492, 0.723785, -1.74493, -1.24976, -7.72562e-08, -1.24975, -1.74493, 0.723783, 1.74493, 1.74919, -0.0010004, 1.75466)
+rotation_edit_mode = 2
+
+[node name="Subdivision" type="Node3D" parent="Grids/GridCentered"]
+transform = Transform3D(1, -6.03961e-14, -2.68221e-07, 3.55271e-13, 1, 1.42109e-14, -1.19209e-07, 1.1724e-13, 1, -0.2, 4.76837e-07, 0.4)
+
+[node name="Grid" type="Node3D" parent="Grids"]
+transform = Transform3D(5, 0, 2.38419e-07, 0, 1, 0, -2.38419e-07, 0, 5, 0, 0, 0)
+
+[node name="Subdivision" type="Node3D" parent="Grids/Grid"]
+transform = Transform3D(1, 0, -2.98023e-08, 0, 0.999999, 1.90735e-05, 0, 4.65661e-10, 0.999999, 1, 0, 1)
+
+[node name="PlaneOrigin" type="MeshInstance3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 11.0482, 7.33669, -13.1715)
+mesh = SubResource("QuadMesh_1t0id")
+
+[node name="Lines" type="Node3D" parent="."]
+transform = Transform3D(1.51514, 0.589536, 1.00858, -1.34875, 0.662262, 1.133, 0, -0.462445, 2.90833, 10.2488, -0.331599, -10.3326)
+
+[node name="1" type="Node3D" parent="Lines"]
+transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 9.40939e-07, 1, 0, -2.76085e-08, -1.49012e-08, 1, -1.46213, -4.03317, 0.61692)
+
+[node name="2" type="Node3D" parent="Lines"]
+transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 9.40939e-07, 1, 0, -2.76085e-08, -1.49012e-08, 1, -1.01875, -1.79584, -0.163045)
+
+[node name="3" type="Node3D" parent="Lines"]
+transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 6.87561e-07, 1, 0, -2.87275e-08, -1.49012e-08, 1, -0.1559, -0.407045, 0.0523388)
+
+[node name="4" type="Node3D" parent="Lines"]
+transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 4.9239e-07, 1, 0, -3.40677e-08, -1.49012e-08, 1, 1.18591, 1.8987, 0.301906)
+
+[node name="5" type="Node3D" parent="Lines"]
+transform = Transform3D(-0.998871, -0.0207882, -0.0355643, 0.0855375, -0.5714, -2.68836, 0.0136011, -0.249864, 0.572532, 1.43126, 0.26242, 1.92347)
+
+[node name="6" type="Node3D" parent="Lines"]
+transform = Transform3D(-0.998872, -0.0207882, -0.0355643, 0.085537, -0.5714, -2.68836, 0.0136012, -0.249864, 0.572533, 1.43441, 1.50606, 1.20028)
+
+[node name="7" type="Node3D" parent="Lines"]
+transform = Transform3D(-0.998873, -0.0207882, -0.0355641, 0.0855357, -0.5714, -2.68836, 0.0136014, -0.249864, 0.572533, 0.0511096, -1.3236, 1.06745)
+
+[node name="8" type="Node3D" parent="Lines"]
+transform = Transform3D(-0.998873, -0.0207882, -0.0355641, 0.0855353, -0.5714, -2.68836, 0.0136016, -0.249864, 0.572533, -1.01372, -3.80486, 1.25019)
+
+[node name="Target" type="Node3D" parent="Lines"]
+transform = Transform3D(1, -2.7352e-06, 2.60722e-07, 4.10378e-06, 1, 0, -4.28605e-07, -1.49012e-08, 1, -0.69134, 0.176475, 1.30597)
+
+[node name="LagTest" type="CSGBox3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, -2, 0)
+size = Vector3(2, 2, 2)
+material = SubResource("1")
+
+[node name="RESET" type="AnimationPlayer" parent="LagTest"]
+libraries = {
+"": SubResource("AnimationLibrary_a7f1a")
+}
+
+[node name="MusicVisualizer" type="VBoxContainer" parent="."]
+offset_left = 10.0
+offset_top = 10.0
+offset_right = 50.0
+offset_bottom = 50.0
+script = ExtResource("4_eq2lt")
+colors = SubResource("Gradient_tup4c")
+
+[node name="OpenFile" type="Button" parent="MusicVisualizer"]
+layout_mode = 2
+size_flags_horizontal = 0
+text = "Open music"
+
+[node name="RESET" type="AnimationPlayer" parent="MusicVisualizer"]
+root_node = NodePath("../OpenFile")
+libraries = {
+"": SubResource("AnimationLibrary_0ity1")
+}
+
+[node name="MusicPlayer" type="AudioStreamPlayer" parent="MusicVisualizer"]
+unique_name_in_owner = true
+autoplay = true
+
+[node name="VBox" type="VBoxContainer" parent="MusicVisualizer"]
+layout_mode = 2
+
+[node name="HBoxContainer" type="HBoxContainer" parent="MusicVisualizer/VBox"]
+layout_mode = 2
+
+[node name="VolumeSlider" type="HSlider" parent="MusicVisualizer/VBox/HBoxContainer"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(100, 0)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+max_value = 1.0
+step = 0.01
+value = 1.0
+
+[node name="MuteMaster" type="CheckBox" parent="MusicVisualizer/VBox/HBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+text = "Mute"
+
+[node name="AudioVisualizer" type="Node3D" parent="."]
+unique_name_in_owner = true
+transform = Transform3D(0.2, 0, 0, 0, 5, 0, 0, 0, 0.2, -5.31036, -1.422, 14.14)
+
+[node name="CustomCanvas" type="Control" parent="."]
+unique_name_in_owner = true
+layout_mode = 3
+anchors_preset = 1
+anchor_left = 1.0
+anchor_right = 1.0
+offset_left = -545.0
+offset_top = 46.0
+offset_right = -37.0
+offset_bottom = 638.0
+grow_horizontal = 0
+mouse_filter = 2
+metadata/_edit_lock_ = true
+
+[node name="Settings" type="Control" parent="."]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+theme = SubResource("3")
+script = ExtResource("5_31v5h")
+switch_to_scene = "res://examples_dd3d/DebugDrawDemoSceneCS.tscn"
+metadata/_edit_lock_ = true
+
+[node name="HBox" type="HBoxContainer" parent="Settings"]
+layout_mode = 1
+anchors_preset = 3
+anchor_left = 1.0
+anchor_top = 1.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = -497.0
+offset_top = -372.0
+offset_right = -10.0006
+offset_bottom = -10.0
+grow_horizontal = 0
+grow_vertical = 0
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Settings/HBox"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 8
+
+[node name="VersionBlock" type="HBoxContainer" parent="Settings/HBox/VBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+script = ExtResource("6_07f7q")
+
+[node name="Label" type="Label" parent="Settings/HBox/VBoxContainer/VersionBlock"]
+layout_mode = 2
+size_flags_horizontal = 10
+theme_override_font_sizes/font_size = 13
+text = "Demo version:"
+
+[node name="OptionButton" type="OptionButton" parent="Settings/HBox/VBoxContainer/VersionBlock"]
+layout_mode = 2
+size_flags_horizontal = 8
+theme_override_font_sizes/font_size = 13
+item_count = 1
+popup/item_0/text = "1.0.0"
+popup/item_0/id = 0
+
+[node name="Label" type="Label" parent="Settings/HBox/VBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 8
+theme_override_styles/normal = SubResource("StyleBoxEmpty_oj5gf")
+text = "GDScript example"
+horizontal_alignment = 2
+metadata/_edit_use_anchors_ = true
+
+[node name="VBox" type="VBoxContainer" parent="Settings/HBox"]
+layout_mode = 2
+alignment = 2
+
+[node name="HideShowPanelButton" type="Button" parent="Settings/HBox/VBox"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 4
+theme_override_font_sizes/font_size = 13
+text = "Hide panel"
+
+[node name="SettingsPanel" type="PanelContainer" parent="Settings/HBox/VBox"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 8
+theme_override_styles/panel = SubResource("StyleBoxFlat_boyhr")
+
+[node name="VBox" type="VBoxContainer" parent="Settings/HBox/VBox/SettingsPanel"]
+layout_mode = 2
+size_flags_horizontal = 3
+alignment = 2
+
+[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.792157, 0.792157, 0.792157, 1)
+text = "Common:"
+
+[node name="HBox3" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox3"]
+layout_mode = 2
+text = "Thickness "
+
+[node name="ThicknessSlider" type="HSlider" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox3"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+max_value = 0.5
+step = 0.001
+value = 0.05
+
+[node name="HBox5" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox5"]
+layout_mode = 2
+text = "Frustum Scale"
+
+[node name="FrustumScaleSlider" type="HSlider" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox5"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+max_value = 1.0
+step = 0.001
+value = 0.5
+
+[node name="UpdateInPhysics" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+unique_name_in_owner = true
+layout_mode = 2
+text = "Update in physics (15 Ticks) *"
+
+[node name="Label2" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.792157, 0.792157, 0.792157, 1)
+text = "FPS Graph:"
+
+[node name="FPSEnabled" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+button_pressed = true
+text = "FPS Graph enabled"
+
+[node name="FPSMS" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+unique_name_in_owner = true
+layout_mode = 2
+button_pressed = true
+text = "FPS Graph ms or FPS"
+
+[node name="HBox" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox"]
+layout_mode = 2
+text = "Width "
+
+[node name="WidthSlider" type="HSlider" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+min_value = 50.0
+max_value = 1000.0
+value = 200.0
+
+[node name="HBox2" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox2"]
+layout_mode = 2
+text = "BufferSize"
+
+[node name="BufferSlider" type="HSlider" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox2"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+min_value = 50.0
+max_value = 1000.0
+value = 128.0
+
+[node name="Label3" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.792157, 0.792157, 0.792157, 1)
+text = "Misc:"
+
+[node name="ShowStats" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+unique_name_in_owner = true
+layout_mode = 2
+text = "Show debug stats"
+
+[node name="HBox4" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+layout_mode = 2
+
+[node name="DrawBoxes" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox4"]
+unique_name_in_owner = true
+layout_mode = 2
+text = "Draw an array of boxes"
+
+[node name="Draw1MBoxes" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox4"]
+unique_name_in_owner = true
+layout_mode = 2
+tooltip_text = "Draw 1 Million boxes, otherwise 7500pcs."
+text = "1M"
+
+[node name="SwitchLang" type="Button" parent="Settings/HBox/VBox/SettingsPanel/VBox"]
+unique_name_in_owner = true
+layout_mode = 2
+text = "Switch to C#"
+
+[connection signal="pressed" from="MusicVisualizer/OpenFile" to="MusicVisualizer" method="_pressed"]
+[connection signal="value_changed" from="MusicVisualizer/VBox/HBoxContainer/VolumeSlider" to="MusicVisualizer" method="_on_volume_slider_value_changed"]
+[connection signal="toggled" from="MusicVisualizer/VBox/HBoxContainer/MuteMaster" to="MusicVisualizer" method="_on_mute_master_toggled"]
+[connection signal="pressed" from="Settings/HBox/VBox/HideShowPanelButton" to="Settings" method="_on_hide_show_panel_pressed"]
+[connection signal="value_changed" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox3/ThicknessSlider" to="Settings" method="_on_thickness_slider_value_changed"]
+[connection signal="value_changed" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox5/FrustumScaleSlider" to="Settings" method="_on_frustum_scale_slider_value_changed"]
+[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/UpdateInPhysics" to="Settings" method="_on_update_in_physics_toggled"]
+[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/FPSEnabled" to="Settings" method="_on_CheckBox_toggled"]
+[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/FPSMS" to="Settings" method="_on_FPSMS_toggled"]
+[connection signal="value_changed" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox/WidthSlider" to="Settings" method="_on_width_slider_value_changed"]
+[connection signal="value_changed" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox2/BufferSlider" to="Settings" method="_on_buffer_slider_value_changed"]
+[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/ShowStats" to="Settings" method="_on_show_stats_toggled"]
+[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox4/DrawBoxes" to="Settings" method="_on_draw_boxes_toggled"]
+[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox4/Draw1MBoxes" to="Settings" method="_on_draw_1m_boxes_toggled"]
+[connection signal="pressed" from="Settings/HBox/VBox/SettingsPanel/VBox/SwitchLang" to="Settings" method="_on_Button_pressed"]
diff --git a/examples_dd3d/DebugDrawDemoSceneCS.cs b/examples_dd3d/DebugDrawDemoSceneCS.cs
new file mode 100644
index 0000000..c07b1a5
--- /dev/null
+++ b/examples_dd3d/DebugDrawDemoSceneCS.cs
@@ -0,0 +1,845 @@
+
+using Godot;
+using System;
+using System.Collections.Generic;
+
+[Tool]
+public partial class DebugDrawDemoSceneCS : Node3D
+{
+ Random random = new Random();
+
+ [Export] Font custom_font;
+ [Export] bool zylann_example = false;
+ [Export] bool update_in_physics = false;
+ [Export] bool test_text = true;
+ [Export] bool test_graphs = false;
+ [Export] bool more_test_cases = true;
+ [Export] bool draw_array_of_boxes = false;
+ [Export] bool draw_1m_boxes = false;
+ [Export(PropertyHint.Range, "0, 5, 0.001")] float debug_thickness = 0.1f;
+ [Export(PropertyHint.Range, "0, 1")] float camera_frustum_scale = 0.9f;
+
+ [ExportGroup("Text groups", "text_groups")]
+ [Export] bool text_groups_show_hints = true;
+ [Export] bool text_groups_show_stats = true;
+ [Export] bool text_groups_show_stats_2d = true;
+ [Export] DebugDraw2DConfig.BlockPosition text_groups_position = DebugDraw2DConfig.BlockPosition.LeftTop;
+ [Export] Vector2I text_groups_offset = new Vector2I(8, 8);
+ [Export] Vector2I text_groups_padding = new Vector2I(3, 1);
+ [Export(PropertyHint.Range, "1, 100")] int text_groups_default_font_size = 15;
+ [Export(PropertyHint.Range, "1, 100")] int text_groups_title_font_size = 20;
+ [Export(PropertyHint.Range, "1, 100")] int text_groups_text_font_size = 17;
+
+ [ExportGroup("Graphs", "graph")]
+ [Export] Vector2I graph_offset = new Vector2I(8, 8);
+ [Export] Vector2I graph_size = new Vector2I(200, 80);
+ [Export(PropertyHint.Range, "1, 100")] int graph_title_font_size = 14;
+ [Export(PropertyHint.Range, "1, 100")] int graph_text_font_size = 12;
+ [Export(PropertyHint.Range, "0, 64")] int graph_text_precision = 1;
+ [Export(PropertyHint.Range, "1, 32")] float graph_line_width = 1.0f;
+ [Export(PropertyHint.Range, "1, 512")] int graph_buffer_size = 128;
+ [Export] bool graph_frame_time_mode = true;
+ [Export] bool graph_is_enabled = true;
+
+ Dictionary button_presses = new Dictionary() {
+ { Key.Left, 0 },
+ { Key.Up, 0 },
+ { Key.Ctrl, 0 },
+ { Key.F1, 0 },
+ { Key.Key1, 0 },
+ { Key.Key2, 0 },
+ { Key.Key3, 0 },
+ };
+
+ double timer_1 = 0.0;
+ double timer_cubes = 0.0;
+ double timer_3 = 0.0;
+ double timer_text = 0.0;
+
+ // TODO remove after moving to 4.2
+ bool is_4_2_and_higher = ((int)Engine.GetVersionInfo()["major"]) >= 4 && ((int)Engine.GetVersionInfo()["minor"]) >= 2;
+
+ Node3D dHitTest;
+ CsgBox3D dLagTest;
+ PanelContainer dPanel;
+ Node3D dZones;
+ Node3D dSpherePosition;
+ Node3D dSphereTransform;
+ Node3D dSphereHDTransform;
+ Node3D dAABB;
+ Node3D dAABB_fixed;
+ Node3D dBox1;
+ Node3D dBox2;
+ Node3D dBox3;
+ Node3D dBoxAB;
+ Node3D dBoxABa;
+ Node3D dBoxABb;
+ Node3D dBoxABup;
+ Node3D dBoxABEdge;
+ Node3D dBoxABEdgea;
+ Node3D dBoxABEdgeb;
+ Node3D dBoxABEdgeup;
+ Node3D dLines_1;
+ Node3D dLines_2;
+ Node3D dLines_3;
+ Node3D dLines_4;
+ Node3D dLines_5;
+ Node3D dLines_6;
+ Node3D dLines_7;
+ Node3D dLines_8;
+ Node3D dLines_Target;
+ Node3D dLinePath;
+ Node3D dCylinder1;
+ Node3D dCylinder2;
+ Node3D dCylinder3a;
+ Node3D dCylinder3b;
+
+ MeshInstance3D dOtherWorld;
+ SubViewport dOtherWorldViewport;
+ Node3D dOtherWorldBox;
+
+ Control dCustomCanvas;
+ Node3D dMisc_Arrow;
+ Camera3D dCamera;
+ Node3D dMisc_Billboard;
+ Node3D dMisc_Position;
+ Node3D dMisc_GizmoTransform;
+ Node3D dMisc_GizmoNormal;
+ Node3D dMisc_GizmoOneColor;
+
+ Node3D dMisc_Grids_Grid;
+ Node3D dMisc_Grids_Grid_Subdivision;
+ Node3D dMisc_Grids_GridCentered_Subdivision;
+ Node3D dMisc_Grids_GridCentered;
+
+ AnimationPlayer dLagTest_RESET;
+ Node3D dHitTest_RayEmitter;
+
+
+ public override async void _Ready()
+ {
+ dHitTest = GetNode("HitTest");
+ dLagTest = GetNode("LagTest");
+ dPanel = GetNode("Panel");
+ dZones = GetNode("Zones");
+ dSpherePosition = GetNode("Spheres/SpherePosition");
+ dSphereTransform = GetNode("Spheres/SphereTransform");
+ dSphereHDTransform = GetNode("Spheres/SphereHDTransform");
+ dAABB = GetNode("Boxes/AABB");
+ dAABB_fixed = GetNode("Boxes/AABB_fixed");
+ dBox1 = GetNode("Boxes/Box1");
+ dBox2 = GetNode("Boxes/Box2");
+ dBox3 = GetNode("Boxes/Box3");
+ dBoxAB = GetNode("Boxes/BoxAB");
+ dBoxABa = GetNode("Boxes/BoxAB/a");
+ dBoxABb = GetNode("Boxes/BoxAB/b");
+ dBoxABup = GetNode("Boxes/BoxAB/o/up");
+ dBoxABEdge = GetNode("Boxes/BoxABEdge");
+ dBoxABEdgea = GetNode("Boxes/BoxABEdge/a");
+ dBoxABEdgeb = GetNode("Boxes/BoxABEdge/b");
+ dBoxABEdgeup = GetNode("Boxes/BoxABEdge/o/up");
+ dLines_1 = GetNode("Lines/1");
+ dLines_2 = GetNode("Lines/2");
+ dLines_3 = GetNode("Lines/3");
+ dLines_4 = GetNode("Lines/4");
+ dLines_5 = GetNode("Lines/5");
+ dLines_6 = GetNode("Lines/6");
+ dLines_7 = GetNode("Lines/7");
+ dLines_8 = GetNode("Lines/8");
+ dLines_Target = GetNode("Lines/Target");
+ dLinePath = GetNode("LinePath");
+ dCylinder1 = GetNode("Cylinders/Cylinder1");
+ dCylinder2 = GetNode("Cylinders/Cylinder2");
+ dCylinder3a = GetNode("Cylinders/Cylinder3/1");
+ dCylinder3b = GetNode("Cylinders/Cylinder3/2");
+
+ dOtherWorld = GetNode("OtherWorld");
+ dOtherWorldViewport = GetNode("OtherWorld/SubViewport");
+ dOtherWorldBox = GetNode("OtherWorld/SubViewport/OtherWorldBox");
+
+ dCustomCanvas = GetNode("CustomCanvas");
+ dMisc_Arrow = GetNode("Misc/Arrow");
+ dCamera = GetNode("Camera");
+ dMisc_Billboard = GetNode("Misc/Billboard");
+ dMisc_Position = GetNode("Misc/Position");
+ dMisc_GizmoTransform = GetNode("Misc/GizmoTransform");
+ dMisc_GizmoNormal = GetNode("Misc/GizmoNormal");
+ dMisc_GizmoOneColor = GetNode("Misc/GizmoOneColor");
+
+ dMisc_Grids_Grid = GetNode("Grids/Grid");
+ dMisc_Grids_Grid_Subdivision = GetNode("Grids/Grid/Subdivision");
+ dMisc_Grids_GridCentered_Subdivision = GetNode("Grids/GridCentered/Subdivision");
+ dMisc_Grids_GridCentered = GetNode("Grids/GridCentered");
+
+ dLagTest_RESET = GetNode("LagTest/RESET");
+ dHitTest_RayEmitter = GetNode("HitTest/RayEmitter");
+
+ _update_keys_just_press();
+
+ await new SignalAwaiter(GetTree(), "process_frame", this);
+
+ // this check is required for inherited scenes, because an instance of this
+ // script is created first, and then overridden by another
+ if (!IsInsideTree())
+ return;
+
+ }
+
+ bool _is_key_just_pressed(Key key)
+ {
+ if (button_presses[key] == 1)
+ {
+ button_presses[key] = 2;
+ return true;
+ }
+ return false;
+ }
+
+ void _update_timers(double delta)
+ {
+ timer_1 -= delta;
+ timer_cubes -= delta;
+ timer_3 -= delta;
+ timer_text -= delta;
+ }
+
+ void _update_keys_just_press()
+ {
+ var set = (Key k) => Input.IsKeyPressed(k) ? (button_presses[k] == 0 ? 1 : button_presses[k]) : 0;
+ button_presses[Key.Left] = set(Key.Left);
+ button_presses[Key.Up] = set(Key.Up);
+ button_presses[Key.Ctrl] = set(Key.Ctrl);
+ button_presses[Key.F1] = set(Key.F1);
+ button_presses[Key.Key1] = set(Key.Key1);
+ button_presses[Key.Key2] = set(Key.Key2);
+ button_presses[Key.Key3] = set(Key.Key3);
+ }
+
+ bool phys_frame_called = false;
+ public override void _Process(double delta)
+ {
+ ((ShaderMaterial)((PrimitiveMesh)dOtherWorld.Mesh).Material).SetShaderParameter("albedo_texture", dOtherWorldViewport.GetTexture());
+
+ phys_frame_called = false;
+ if (!update_in_physics)
+ {
+ MainUpdate(delta);
+ _update_timers(delta);
+ }
+ }
+
+ public override void _PhysicsProcess(double delta)
+ {
+ if (!phys_frame_called)
+ {
+ phys_frame_called = true;
+ if (update_in_physics)
+ {
+ MainUpdate(delta);
+ _update_timers(delta);
+ }
+ }
+
+ // Physics specific:
+ if (!zylann_example)
+ {
+ DebugDraw3D.DrawLine(dLines_8.GlobalPosition, dLines_Target.GlobalPosition, Colors.Yellow);
+ if (more_test_cases)
+ {
+ _draw_rays_casts();
+ }
+
+ // Additional drawing in the Viewport
+ using (var _w1 = DebugDraw3D.NewScopedConfig().SetViewport(dOtherWorldBox.GetViewport()).SetThickness(0.01f).SetCenterBrightness(1))
+ {
+ DebugDraw3D.DrawBoxXf(new Transform3D(Basis.Identity
+ .Scaled(Vector3.One * 0.3f)
+ .Rotated(new Vector3(0, 0, 1), Mathf.Pi / 4)
+ .Rotated(new Vector3(0, 1, 0), Mathf.Wrap(Time.GetTicksMsec() / -1500.0f, 0, Mathf.Tau) - Mathf.Pi / 4), dOtherWorldBox.GlobalPosition),
+ Colors.Brown, true, 0.4f);
+ }
+ }
+ }
+
+ void MainUpdate(double delta)
+ {
+ DebugDraw3D.ScopedConfig().SetThickness(debug_thickness);
+#pragma warning disable CS0162 // Unreachable code detected
+ if (false) // #test
+ {
+ using var s11 = DebugDraw3D.NewScopedConfig().SetThickness(1);
+ using var s13 = DebugDraw3D.NewScopedConfig();
+ s13.SetThickness(3);
+ }
+#pragma warning restore CS0162 // Unreachable code detected
+
+ _update_keys_just_press();
+
+ if (_is_key_just_pressed(Key.F1))
+ zylann_example = !zylann_example;
+
+ // Zylann's example :D
+ if (zylann_example)
+ {
+ DebugDraw2D.ClearGraphs();
+ var _time = Time.GetTicksMsec() / 1000.0f;
+ var box_pos = new Vector3(0, Mathf.Sin(_time * 4f), 0);
+ var line_begin = new Vector3(-1, Mathf.Sin(_time * 4f), 0);
+ var line_end = new Vector3(1, Mathf.Cos(_time * 4f), 0);
+ DebugDraw3D.DrawBox(box_pos, Quaternion.Identity, new Vector3(1, 2, 1), new Color(0, 1, 0));
+ DebugDraw3D.DrawLine(line_begin, line_end, new Color(1, 1, 0));
+ DebugDraw2D.SetText("Time", _time);
+ DebugDraw2D.SetText("Frames drawn", Engine.GetFramesDrawn());
+ DebugDraw2D.SetText("FPS", Engine.GetFramesPerSecond());
+ DebugDraw2D.SetText("delta", delta);
+ dHitTest.Visible = false;
+ dLagTest.Visible = false;
+ return;
+ }
+
+ dHitTest.Visible = true;
+ dLagTest.Visible = true;
+
+ // Testing the rendering layers by showing the image from the second camera inside the 2D panel
+ DebugDraw3D.Config.GeometryRenderLayers = !Input.IsKeyPressed(Key.Alt) ? 1 : 0b10010;
+ dPanel.Visible = Input.IsKeyPressed(Key.Alt);
+ DebugDraw2D.CustomCanvas = Input.IsKeyPressed(Key.Alt) ? dCustomCanvas : null;
+
+ // More property toggles
+ DebugDraw3D.Config.Freeze3dRender = Input.IsKeyPressed(Key.Down);
+ DebugDraw3D.Config.VisibleInstanceBounds = Input.IsKeyPressed(Key.Right);
+
+ // Regenerate meshes
+ if (Input.IsActionJustPressed("ui_end"))
+ DebugDraw3D.RegenerateGeometryMeshes();
+
+ // Some property toggles
+ if (_is_key_just_pressed(Key.Left))
+ DebugDraw3D.Config.UseFrustumCulling = !DebugDraw3D.Config.UseFrustumCulling;
+
+ if (_is_key_just_pressed(Key.Up))
+ DebugDraw3D.Config.ForceUseCameraFromScene = !DebugDraw3D.Config.ForceUseCameraFromScene;
+
+ if (_is_key_just_pressed(Key.Ctrl))
+ if (!Engine.IsEditorHint())
+ GetViewport().Msaa3D = GetViewport().Msaa3D == Viewport.Msaa.Msaa4X ? Viewport.Msaa.Disabled : Viewport.Msaa.Msaa4X;
+
+ if (!Engine.IsEditorHint())
+ {
+ if (_is_key_just_pressed(Key.Key1))
+ DebugDraw3D.DebugEnabled = !DebugDraw3D.DebugEnabled;
+ if (_is_key_just_pressed(Key.Key2))
+ DebugDraw2D.DebugEnabled = !DebugDraw2D.DebugEnabled;
+ if (_is_key_just_pressed(Key.Key3))
+ DebugDrawManager.DebugEnabled = !DebugDrawManager.DebugEnabled;
+ }
+
+
+ DebugDraw3D.Config.FrustumLengthScale = camera_frustum_scale;
+
+ // Zones with black borders
+ foreach (var node in dZones.GetChildren())
+ {
+ if (node is Node3D z)
+ {
+ DebugDraw3D.DrawBoxXf(z.GlobalTransform, Colors.Black);
+ }
+ }
+
+ // Spheres
+ DebugDraw3D.DrawSphereXf(dSphereTransform.GlobalTransform, Colors.Crimson);
+ using (var _s1 = DebugDraw3D.NewScopedConfig().SetHdSphere(true))
+ DebugDraw3D.DrawSphereXf(dSphereHDTransform.GlobalTransform, Colors.OrangeRed);
+
+ // Delayed spheres
+ if (timer_1 <= 0)
+ {
+ DebugDraw3D.DrawSphere(dSpherePosition.GlobalPosition, 2.0f, Colors.BlueViolet, 2.0f);
+ using (var _s1 = DebugDraw3D.NewScopedConfig().SetHdSphere(true))
+ DebugDraw3D.DrawSphere(dSpherePosition.GlobalPosition + Vector3.Forward * 4, 2.0f, Colors.CornflowerBlue, 2.0f);
+ timer_1 = 2;
+ }
+
+ timer_1 -= delta;
+
+ // Cylinders
+ DebugDraw3D.DrawCylinder(dCylinder1.GlobalTransform, Colors.Crimson);
+ DebugDraw3D.DrawCylinder(new Transform3D(Basis.Identity.Scaled(new Vector3(1, 2, 1)), dCylinder2.GlobalPosition), Colors.Red);
+ DebugDraw3D.DrawCylinderAb(dCylinder3a.GlobalPosition, dCylinder3b.GlobalPosition, 0.7f);
+
+ // Boxes
+ DebugDraw3D.DrawBoxXf(dBox1.GlobalTransform, Colors.MediumPurple);
+ DebugDraw3D.DrawBox(dBox2.GlobalPosition, Quaternion.FromEuler(new Vector3(0, Mathf.DegToRad(45), Mathf.DegToRad(45))), Vector3.One, Colors.RebeccaPurple);
+ DebugDraw3D.DrawBoxXf(new Transform3D(new Basis(Vector3.Up, Mathf.Pi * 0.25f).Scaled(Vector3.One * 2), dBox3.GlobalPosition), Colors.RosyBrown);
+
+ DebugDraw3D.DrawAabb(new Aabb(dAABB_fixed.GlobalPosition, new Vector3(2, 1, 2)), Colors.Aqua);
+ DebugDraw3D.DrawAabbAb(dAABB.GetChild(0).GlobalPosition, dAABB.GetChild(1).GlobalPosition, Colors.DeepPink);
+
+ // Boxes AB
+
+ DebugDraw3D.DrawArrow(dBoxAB.GlobalPosition, dBoxABup.GlobalPosition, Colors.Gold, 0.1f, true);
+ DebugDraw3D.DrawBoxAb(dBoxABa.GlobalPosition, dBoxABb.GlobalPosition, dBoxABup.GlobalPosition - dBoxAB.GlobalPosition, Colors.Peru);
+
+ DebugDraw3D.DrawArrow(dBoxABEdge.GlobalPosition, dBoxABEdgeup.GlobalPosition, Colors.DarkRed, 0.1f, true);
+ DebugDraw3D.DrawBoxAb(dBoxABEdgea.GlobalPosition, dBoxABEdgeb.GlobalPosition, dBoxABEdgeup.GlobalPosition - dBoxABEdge.GlobalPosition, Colors.DarkOliveGreen, false);
+
+ // Lines
+ DebugDraw3D.DrawSquare(dLines_Target.GlobalPosition, 0.5f, Colors.Red);
+
+ DebugDraw3D.DrawLine(dLines_1.GlobalPosition, dLines_Target.GlobalPosition, Colors.Fuchsia);
+ DebugDraw3D.DrawRay(dLines_3.GlobalPosition, (dLines_Target.GlobalPosition - dLines_3.GlobalPosition).Normalized(), 3.0f, Colors.Crimson);
+
+
+ if (timer_3 <= 0)
+ {
+ DebugDraw3D.DrawLine(dLines_6.GlobalPosition, dLines_Target.GlobalPosition, Colors.Fuchsia, 2.0f);
+ timer_3 = 2;
+ }
+
+ timer_3 -= delta;
+
+ // Test UP vector
+ DebugDraw3D.DrawLine(dLines_7.GlobalPosition, dLines_Target.GlobalPosition, Colors.Red);
+
+ // Lines with Arrow
+ DebugDraw3D.DrawArrow(dLines_2.GlobalPosition, dLines_Target.GlobalPosition, Colors.Blue, 0.5f, true);
+ DebugDraw3D.DrawArrowRay(dLines_4.GlobalPosition, (dLines_Target.GlobalPosition - dLines_4.GlobalPosition).Normalized(), 8.0f, Colors.Lavender, 0.5f, true);
+
+ DebugDraw3D.DrawLineHitOffset(dLines_5.GlobalPosition, dLines_Target.GlobalPosition, true, Mathf.Abs(Mathf.Sin(Time.GetTicksMsec() / 1000.0f)), 0.25f, Colors.Aqua);
+
+ // Path
+
+ // preparing data
+ List points = new List();
+ List points_below = new List();
+ List points_below2 = new List();
+ List points_below3 = new List();
+ List points_below4 = new List();
+ List lines_above = new List();
+
+ foreach (var node in dLinePath.GetChildren())
+ {
+ if (node is Node3D c)
+ {
+ points.Add(c.GlobalPosition);
+ points_below.Add(c.GlobalPosition + Vector3.Down);
+ points_below2.Add(c.GlobalPosition + Vector3.Down * 2);
+ points_below3.Add(c.GlobalPosition + Vector3.Down * 3);
+ points_below4.Add(c.GlobalPosition + Vector3.Down * 4);
+ }
+ }
+
+ for (int x = 0; x < points.Count - 1; x++)
+ {
+ lines_above.Add(points[x] + Vector3.Up);
+ lines_above.Add(points[x + 1] + Vector3.Up);
+ }
+
+ // drawing lines
+ DebugDraw3D.DrawLines(lines_above.ToArray());
+ DebugDraw3D.DrawLinePath(points.ToArray(), Colors.Beige);
+ DebugDraw3D.DrawPoints(points_below.ToArray(), DebugDraw3D.PointType.TypeSquare, 0.2f, Colors.DarkGreen);
+ DebugDraw3D.DrawPointPath(points_below2.ToArray(), DebugDraw3D.PointType.TypeSquare, 0.25f, Colors.Blue, Colors.Tomato);
+ DebugDraw3D.DrawArrowPath(points_below3.ToArray(), Colors.Gold, 0.5f);
+ using (var _sl = DebugDraw3D.NewScopedConfig().SetThickness(0.05f))
+ DebugDraw3D.DrawPointPath(points_below4.ToArray(), DebugDraw3D.PointType.TypeSphere, 0.25f, Colors.MediumSeaGreen, Colors.MediumVioletRed);
+
+ // Other world
+
+ using (var s = DebugDraw3D.NewScopedConfig().SetViewport(dOtherWorldBox.GetViewport()))
+ {
+ DebugDraw3D.DrawBoxXf(dOtherWorldBox.GlobalTransform.RotatedLocal(new Vector3(1, 1, -1).Normalized(), Mathf.Wrap(Time.GetTicksMsec() / 1000.0f, 0f, Mathf.Tau)), Colors.SandyBrown);
+ DebugDraw3D.DrawBoxXf(dOtherWorldBox.GlobalTransform.RotatedLocal(new Vector3(-1, 1, -1).Normalized(), Mathf.Wrap(Time.GetTicksMsec() / 1000.0f, 0f, Mathf.Tau) - Mathf.Pi / 4), Colors.SandyBrown);
+ }
+
+ // Misc
+ if (Engine.IsEditorHint())
+ {
+ using var s = DebugDraw3D.NewScopedConfig().SetThickness(0);
+ DebugDraw3D.DrawCameraFrustum(dCamera, Colors.DarkOrange);
+ }
+
+ using (var s = DebugDraw3D.NewScopedConfig().SetCenterBrightness(0.1f))
+ {
+ DebugDraw3D.DrawArrowhead(dMisc_Arrow.GlobalTransform, Colors.YellowGreen);
+ }
+
+ DebugDraw3D.DrawSquare(dMisc_Billboard.GlobalPosition, 0.5f, Colors.Green);
+
+ DebugDraw3D.DrawPosition(dMisc_Position.GlobalTransform, Colors.Brown);
+
+ DebugDraw3D.DrawGizmo(dMisc_GizmoTransform.GlobalTransform, null, true);
+ DebugDraw3D.DrawGizmo(dMisc_GizmoOneColor.GlobalTransform, Colors.Brown, true);
+ using (var s = DebugDraw3D.NewScopedConfig().SetCenterBrightness(0.5f))
+ {
+ DebugDraw3D.DrawGizmo(dMisc_GizmoNormal.GlobalTransform.Orthonormalized(), null, false);
+ }
+
+ Transform3D tg = dMisc_Grids_Grid.GlobalTransform;
+ Vector3 tn = dMisc_Grids_Grid_Subdivision.Transform.Origin;
+ DebugDraw3D.DrawGrid(tg.Origin, tg.Basis.X, tg.Basis.Z, new Vector2I((int)tn.X * 10, (int)tn.Z * 10), Colors.LightCoral, false);
+
+ var tn1 = dMisc_Grids_GridCentered_Subdivision.Transform.Origin;
+ DebugDraw3D.DrawGridXf(dMisc_Grids_GridCentered.GlobalTransform, new Vector2I((int)(tn1.X * 10), (int)(tn1.Z * 10)));
+
+ // 2D
+ DebugDraw2D.Config.TextDefaultSize = text_groups_default_font_size;
+ DebugDraw2D.Config.TextBlockOffset = text_groups_offset;
+ DebugDraw2D.Config.TextBlockPosition = text_groups_position;
+ DebugDraw2D.Config.TextPadding = text_groups_padding;
+
+ DebugDraw2D.Config.TextCustomFont = custom_font;
+
+
+ if (test_text)
+ {
+ timer_text -= delta;
+ _text_tests();
+ }
+
+ // Graphs
+ // Enable FPSGraph if not exists
+ _create_graph("FPS", true, false, DebugDraw2DGraph.TextFlags.Current | DebugDraw2DGraph.TextFlags.Avg | DebugDraw2DGraph.TextFlags.Max | DebugDraw2DGraph.TextFlags.Min, "", DebugDraw2DGraph.GraphSide.Bottom, Engine.IsEditorHint() ? DebugDraw2DGraph.GraphPosition.LeftTop : DebugDraw2DGraph.GraphPosition.RightTop, new Vector2I(200, 80), custom_font);
+ if (Engine.IsEditorHint())
+ {
+ if (DebugDraw2D.GetGraph("FPS") != null)
+ {
+ DebugDraw2D.GetGraph("FPS").Offset = new Vector2I(0, 64);
+ }
+ }
+
+ // Adding more graphs
+ if (test_graphs)
+ {
+ _graph_test();
+ }
+ else
+ {
+ _remove_graphs();
+ }
+ _upd_graph_params();
+
+ // Lag Test
+ dLagTest.Position = ((Vector3)dLagTest_RESET.GetAnimation("RESET").TrackGetKeyValue(0, 0)) + new Vector3(Mathf.Sin(Time.GetTicksMsec() / 100.0f) * 2.5f, 0, 0);
+ DebugDraw3D.DrawBox(dLagTest.GlobalPosition, Quaternion.Identity, Vector3.One * 2.01f, null, true);
+
+ if (more_test_cases)
+ {
+ foreach (var node in dHitTest_RayEmitter.GetChildren())
+ {
+ if (node is RayCast3D ray)
+ ray.SetPhysicsProcessInternal(true);
+ }
+
+ _more_tests();
+ }
+ else
+ {
+ foreach (var node in dHitTest_RayEmitter.GetChildren())
+ {
+ if (node is RayCast3D ray)
+ ray.SetPhysicsProcessInternal(false);
+ }
+ }
+
+ if (draw_array_of_boxes)
+ {
+ _draw_array_of_boxes();
+ }
+
+ }
+
+ void _text_tests()
+ {
+
+ if (timer_text < 0)
+ {
+ DebugDraw2D.SetText("Some delayed text", "for 2.5s", -1, Colors.Black, 2.5f); // it's supposed to show text for 2.5 seconds
+ timer_text += 5;
+ }
+
+ DebugDraw2D.SetText("FPS", $"{Engine.GetFramesPerSecond():F2}", 0, Colors.Gold);
+ DebugDraw2D.BeginTextGroup("-- First Group --", 2, Colors.LimeGreen, true, text_groups_title_font_size, text_groups_text_font_size);
+ DebugDraw2D.SetText("Simple text");
+ DebugDraw2D.SetText("Text", "Value", 0, Colors.Aquamarine);
+ DebugDraw2D.SetText("Text out of order", null, -1, Colors.Silver);
+ DebugDraw2D.BeginTextGroup("-- Second Group --", 1, Colors.Beige);
+ DebugDraw2D.SetText("Rendered frames", Engine.GetFramesDrawn());
+ DebugDraw2D.EndTextGroup();
+
+ if (text_groups_show_stats)
+ {
+ DebugDraw2D.BeginTextGroup("-- Stats --", 3, Colors.Wheat);
+ var render_stats = DebugDraw3D.GetRenderStats();
+
+ if (render_stats != null && text_groups_show_stats)
+ {
+ DebugDraw2D.SetText("Total", render_stats.TotalGeometry);
+ DebugDraw2D.SetText("Instances", render_stats.Instances, 1);
+ DebugDraw2D.SetText("Lines", render_stats.Lines, 2);
+ DebugDraw2D.SetText("Total Visible", render_stats.TotalVisible, 3);
+ DebugDraw2D.SetText("Visible Instances", render_stats.VisibleInstances, 4);
+ DebugDraw2D.SetText("Visible Lines", render_stats.VisibleLines, 5);
+
+ DebugDraw2D.SetText("---", "", 6);
+
+ DebugDraw2D.SetText("Culling time", $"{(render_stats.TotalTimeCullingUsec / 1000.0):F2} ms", 7);
+ DebugDraw2D.SetText("Filling instances buffer", $"{(render_stats.TimeFillingBuffersInstancesUsec / 1000.0):F2} ms", 8);
+ DebugDraw2D.SetText("Filling lines buffer", $"{(render_stats.TimeFillingBuffersLinesUsec / 1000.0):F2} ms", 9);
+ DebugDraw2D.SetText("Filling time", $"{(render_stats.TotalTimeFillingBuffersUsec / 1000.0):F2} ms", 10);
+ DebugDraw2D.SetText("Total time", $"{(render_stats.TotalTimeSpentUsec / 1000.0):F2} ms", 11);
+
+ DebugDraw2D.SetText("---", null, 14);
+
+ DebugDraw2D.SetText("Created scoped configs", $"{render_stats.CreatedScopedConfigs}", 15);
+ }
+
+ if (text_groups_show_stats && text_groups_show_stats_2d)
+ {
+ DebugDraw2D.SetText("----", null, 19);
+ }
+
+ var render_stats_2d = DebugDraw2D.GetRenderStats();
+ if (render_stats_2d != null && text_groups_show_stats_2d)
+ {
+ DebugDraw2D.SetText("Text groups", render_stats_2d.OverlayTextGroups, 20);
+ DebugDraw2D.SetText("Text lines", render_stats_2d.OverlayTextLines, 21);
+ DebugDraw2D.SetText("Graphs total", render_stats_2d.OverlayGraphsTotal, 22);
+ DebugDraw2D.SetText("Graphs enabled", render_stats_2d.OverlayGraphsEnabled, 23);
+ }
+ DebugDraw2D.EndTextGroup();
+ }
+
+ if (text_groups_show_hints)
+ {
+ DebugDraw2D.BeginTextGroup("controls", 1024, Colors.White, false);
+ if (!Engine.IsEditorHint())
+ {
+ DebugDraw2D.SetText("WASD QE, LMB", "To move", 0);
+ }
+ DebugDraw2D.SetText("Alt: change render layers", DebugDraw3D.Config.GeometryRenderLayers, 1);
+ if (!OS.HasFeature("web"))
+ {
+ DebugDraw2D.SetText("Ctrl: toggle anti-aliasing", GetViewport().Msaa3D == Viewport.Msaa.Msaa4X ? "MSAA 4x" : "Disabled", 2);
+ }
+ DebugDraw2D.SetText("Down: freeze render", DebugDraw3D.Config.Freeze3dRender, 3);
+ if (Engine.IsEditorHint())
+ {
+ DebugDraw2D.SetText("Up: use scene camera", DebugDraw3D.Config.ForceUseCameraFromScene, 4);
+ }
+ DebugDraw2D.SetText("1,2,3: toggle debug", $"{DebugDraw3D.DebugEnabled}, {DebugDraw2D.DebugEnabled} 😐, {DebugDrawManager.DebugEnabled} 😏", 5);
+ DebugDraw2D.SetText("Left: toggle frustum culling", DebugDraw3D.Config.UseFrustumCulling, 6);
+ DebugDraw2D.SetText("Right: draw bounds for culling", DebugDraw3D.Config.VisibleInstanceBounds, 7);
+ }
+ }
+
+ void _draw_rays_casts()
+ {
+ // Line hits render
+ foreach (var node in dHitTest_RayEmitter.GetChildren())
+ {
+ if (node is RayCast3D ray)
+ {
+ ray.ForceRaycastUpdate();
+ DebugDraw3D.DrawLineHit(ray.GlobalPosition, ray.ToGlobal(ray.TargetPosition), ray.GetCollisionPoint(), ray.IsColliding(), 0.3f);
+ }
+ }
+ }
+
+ void _more_tests()
+ {
+ // Delayed line render
+ using (var s = DebugDraw3D.NewScopedConfig().SetThickness(0.035f))
+ {
+ DebugDraw3D.DrawLine(dLagTest.GlobalPosition + Vector3.Up, dLagTest.GlobalPosition + new Vector3(0, 3, Mathf.Sin(Time.GetTicksMsec() / 50.0f)), null, 0.5f);
+ }
+
+ // Draw plane
+ using (var _s11 = DebugDraw3D.NewScopedConfig().SetThickness(0.02f).SetPlaneSize(10))
+ {
+ var pl_node = GetNode("PlaneOrigin");
+ var xf = pl_node.GlobalTransform;
+ var normal = xf.Basis.Y.Normalized();
+ var plane = new Plane(normal, xf.Origin.Dot(normal));
+
+ var vp = GetViewport();
+ if (is_4_2_and_higher)
+ {
+ if (Engine.IsEditorHint() && (Viewport)Engine.GetSingleton("EditorInterface").Call("get_editor_viewport_3d", 0) != null)
+ {
+ vp = (Viewport)Engine.GetSingleton("EditorInterface").Call("get_editor_viewport_3d", 0);
+ }
+ }
+
+ var cam = vp.GetCamera3D();
+ if (cam != null)
+ {
+ var dir = vp.GetCamera3D().ProjectRayNormal(vp.GetMousePosition());
+ Vector3? intersect = plane.IntersectsRay(cam.GlobalPosition, dir);
+
+ DebugDraw3D.DrawPlane(plane, Colors.Coral * new Color(1, 1, 1, 0.4f), pl_node.GlobalPosition);
+ if (is_4_2_and_higher)
+ {
+ if (intersect.HasValue && intersect.Value.DistanceTo(pl_node.GlobalPosition) < _s11.GetPlaneSize() * 0.5f)
+ {
+ // Need to test different colors on both sides of the plane
+ var col = plane.IsPointOver(cam.GlobalPosition) ? Colors.Firebrick : Colors.Aquamarine;
+ DebugDraw3D.DrawSphere(intersect.Value, 0.3f, col);
+ }
+ }
+ }
+ }
+ }
+
+ void _draw_array_of_boxes()
+ {
+ // Lots of boxes to check performance..
+ var x_size = 50;
+ var y_size = 50;
+ var z_size = 3;
+ var mul = 1.0f;
+ var cubes_max_time = 1.25f;
+ using var cfg = DebugDraw3D.NewScopedConfig();
+
+ if (draw_1m_boxes)
+ {
+ x_size = 100;
+ y_size = 100;
+ z_size = 100;
+ mul = 4.0f;
+ cubes_max_time = 60f;
+ }
+
+ if (timer_cubes <= 0)
+ {
+ for (int x = 0; x < x_size; x++)
+ {
+ for (int y = 0; y < y_size; y++)
+ {
+ for (int z = 0; z < z_size; z++)
+ {
+ var size = Vector3.One;
+ cfg.SetThickness(Random.Shared.NextSingle() * 0.1f);
+ //size = new Vector3(Random.Shared.NextSingle() * 100 + 0.1f, Random.Shared.NextSingle() * 100 + 0.1f, Random.Shared.NextSingle() * 100 + 0.1f);
+ DebugDraw3D.DrawBox(new Vector3(x * mul, (-4 - z) * mul, y * mul), Quaternion.Identity, size, null, false, cubes_max_time);
+ }
+ }
+ }
+ timer_cubes = cubes_max_time;
+ }
+ }
+
+ void _graph_test()
+ {
+ _create_graph("fps", true, true, DebugDraw2DGraph.TextFlags.Current, "", DebugDraw2DGraph.GraphSide.Left, DebugDraw2DGraph.GraphPosition.RightTop);
+ _create_graph("fps2", true, false, DebugDraw2DGraph.TextFlags.Current, "fps", DebugDraw2DGraph.GraphSide.Bottom, 0, new Vector2I(200, 100));
+
+ _create_graph("Sin Wave!", false, true, DebugDraw2DGraph.TextFlags.Current, "fps2", DebugDraw2DGraph.GraphSide.Bottom);
+
+ _create_graph("randf", false, true, DebugDraw2DGraph.TextFlags.Avg, "", DebugDraw2DGraph.GraphSide.Left, DebugDraw2DGraph.GraphPosition.RightBottom, new Vector2I(256, 60), custom_font);
+
+ _create_graph("fps5", true, true, DebugDraw2DGraph.TextFlags.All, "randf", DebugDraw2DGraph.GraphSide.Top);
+ _create_graph("fps6", true, true, DebugDraw2DGraph.TextFlags.All, "fps5", DebugDraw2DGraph.GraphSide.Top);
+ _create_graph("fps12", true, true, DebugDraw2DGraph.TextFlags.All, "fps5", DebugDraw2DGraph.GraphSide.Left);
+
+ _create_graph("fps7", true, false, DebugDraw2DGraph.TextFlags.All, "FPS", DebugDraw2DGraph.GraphSide.Bottom);
+ _create_graph("fps8", true, true, DebugDraw2DGraph.TextFlags.All, "", DebugDraw2DGraph.GraphSide.Top, DebugDraw2DGraph.GraphPosition.LeftBottom);
+ _create_graph("fps9", true, false, DebugDraw2DGraph.TextFlags.All, "fps8", DebugDraw2DGraph.GraphSide.Right);
+ _create_graph("fps10", true, false, DebugDraw2DGraph.TextFlags.All, "fps8", DebugDraw2DGraph.GraphSide.Top);
+ _create_graph("fps11", true, true, DebugDraw2DGraph.TextFlags.All, "fps9", DebugDraw2DGraph.GraphSide.Right);
+
+ // If graphs exists, then more tests are done
+ DebugDraw2D.GetGraph("Sin Wave!").DataGetter = new Callable(this, "_get_sin_wave_for_graph");
+ DebugDraw2D.GetGraph("Sin Wave!").UpsideDown = false;
+
+ DebugDraw2D.GetGraph("randf").TextSuffix = "utf8 ноль zéro";
+ //DebugDraw2D.GetGraph("fps9").line_position = DebugDraw2DGraph.LINE_TOP
+ DebugDraw2D.GetGraph("fps9").Offset = new Vector2I(0, 0);
+ //DebugDraw2D.GetGraph("fps11").LlinePosition = DebugDraw2DGraph.LINE_BOTTOM
+ DebugDraw2D.GetGraph("fps11").Offset = new Vector2I(16, 0);
+ DebugDraw2D.GetGraph("fps6").Offset = new Vector2I(0, 32);
+ DebugDraw2D.GetGraph("fps").Offset = new Vector2I(16, 72);
+ DebugDraw2D.GetGraph("fps9").Enabled = graph_is_enabled;
+
+ if (!Engine.IsEditorHint())
+ {
+ DebugDraw2D.GetGraph("fps").Corner = DebugDraw2DGraph.GraphPosition.LeftTop;
+ }
+
+ // Just sending random data to the graph
+ DebugDraw2D.GraphUpdateData("randf", (float)random.NextDouble());
+ }
+
+ void _upd_graph_params()
+ {
+ DebugDraw2D.Config.GraphsBaseOffset = graph_offset;
+ foreach (var g in new string[] { "FPS", "fps5", "fps8" })
+ {
+ var graph = DebugDraw2D.GetGraph(g) as DebugDraw2DFPSGraph;
+ if (graph != null)
+ {
+
+ graph.Size = graph_size;
+ graph.TitleSize = graph_title_font_size;
+ graph.TextSize = graph_text_font_size;
+ graph.LineWidth = graph_line_width;
+ graph.TextPrecision = graph_text_precision;
+ graph.BufferSize = graph_buffer_size;
+ if (Engine.IsEditorHint() || g != "FPS")
+ {
+ graph.FrameTimeMode = graph_frame_time_mode;
+ }
+ }
+ }
+ }
+
+ float _get_sin_wave_for_graph()
+ {
+ var mul = Input.IsKeyPressed(Key.End) ? 4 : 2;
+ return (float)Mathf.Sin(Engine.GetFramesDrawn() * 0.5) * mul;
+ }
+
+ void _remove_graphs()
+ {
+ DebugDraw2D.RemoveGraph("randf");
+ DebugDraw2D.RemoveGraph("fps");
+ DebugDraw2D.RemoveGraph("fps2");
+ DebugDraw2D.RemoveGraph("Sin Wave!");
+ DebugDraw2D.RemoveGraph("fps5");
+ DebugDraw2D.RemoveGraph("fps6");
+ DebugDraw2D.RemoveGraph("fps7");
+ DebugDraw2D.RemoveGraph("fps8");
+ DebugDraw2D.RemoveGraph("fps9");
+ DebugDraw2D.RemoveGraph("fps10");
+ DebugDraw2D.RemoveGraph("fps11");
+ DebugDraw2D.RemoveGraph("fps12");
+ }
+
+ DebugDraw2DGraph _create_graph(string title, bool is_fps, bool show_title, DebugDraw2DGraph.TextFlags flags, string parent = "", DebugDraw2DGraph.GraphSide parent_side = DebugDraw2DGraph.GraphSide.Bottom, DebugDraw2DGraph.GraphPosition pos = DebugDraw2DGraph.GraphPosition.LeftBottom, Vector2I? size = null, Font font = null)
+ {
+ var graph = DebugDraw2D.GetGraph(title);
+ if (graph == null)
+ {
+ if (is_fps)
+ {
+ graph = DebugDraw2D.CreateFpsGraph(title);
+ }
+ else
+ {
+ graph = DebugDraw2D.CreateGraph(title);
+ }
+
+ if (graph != null)
+ {
+ graph.Size = size ?? new Vector2I(256, 60);
+ graph.BufferSize = 50;
+ graph.Corner = pos;
+ graph.ShowTitle = show_title;
+ graph.ShowTextFlags = flags;
+ graph.CustomFont = font;
+ graph.SetParent(parent, parent_side);
+ }
+ }
+ return graph;
+ }
+}
diff --git a/examples_dd3d/DebugDrawDemoSceneCS.tscn b/examples_dd3d/DebugDrawDemoSceneCS.tscn
new file mode 100644
index 0000000..140c74e
--- /dev/null
+++ b/examples_dd3d/DebugDrawDemoSceneCS.tscn
@@ -0,0 +1,16 @@
+[gd_scene load_steps=3 format=3 uid="uid://sxtw8fme7g63"]
+
+[ext_resource type="PackedScene" uid="uid://c3sccy6x0ht5j" path="res://examples_dd3d/DebugDrawDemoScene.tscn" id="2"]
+[ext_resource type="Script" path="res://examples_dd3d/DebugDrawDemoSceneCS.cs" id="2_ipqea"]
+
+[node name="DebugDrawDemoSceneCS" instance=ExtResource("2")]
+script = ExtResource("2_ipqea")
+
+[node name="Settings" parent="." index="21"]
+switch_to_scene = "res://examples_dd3d/DebugDrawDemoScene.tscn"
+
+[node name="Label" parent="Settings/HBox/VBoxContainer" index="1"]
+text = "C# example"
+
+[node name="SwitchLang" parent="Settings/HBox/PanelContainer/VBox" index="12"]
+text = "Switch to GDScript"
diff --git a/examples_dd3d/Roboto-Bold.ttf b/examples_dd3d/Roboto-Bold.ttf
new file mode 100644
index 0000000..d3f01ad
Binary files /dev/null and b/examples_dd3d/Roboto-Bold.ttf differ
diff --git a/examples_dd3d/Roboto-Bold.ttf.import b/examples_dd3d/Roboto-Bold.ttf.import
new file mode 100644
index 0000000..b440a9d
--- /dev/null
+++ b/examples_dd3d/Roboto-Bold.ttf.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="font_data_dynamic"
+type="FontFile"
+uid="uid://erdgllynwqkw"
+path="res://.godot/imported/Roboto-Bold.ttf-3674de3d9ad3ee757cd4b4a89f1e126d.fontdata"
+
+[deps]
+
+source_file="res://examples_dd3d/Roboto-Bold.ttf"
+dest_files=["res://.godot/imported/Roboto-Bold.ttf-3674de3d9ad3ee757cd4b4a89f1e126d.fontdata"]
+
+[params]
+
+Rendering=null
+antialiasing=1
+generate_mipmaps=false
+multichannel_signed_distance_field=false
+msdf_pixel_range=8
+msdf_size=48
+allow_system_fallback=true
+force_autohinter=false
+hinting=1
+subpixel_positioning=1
+oversampling=0.0
+Fallbacks=null
+fallbacks=[]
+Compress=null
+compress=true
+preload=[{
+"chars": [],
+"glyphs": [],
+"name": "New Configuration"
+}]
+language_support={}
+script_support={}
+opentype_features={}
diff --git a/examples_dd3d/VisualizerAudioBus.tres b/examples_dd3d/VisualizerAudioBus.tres
new file mode 100644
index 0000000..4c7b662
--- /dev/null
+++ b/examples_dd3d/VisualizerAudioBus.tres
@@ -0,0 +1,17 @@
+[gd_resource type="AudioBusLayout" load_steps=2 format=3 uid="uid://7sy4h4ibftrk"]
+
+[sub_resource type="AudioEffectSpectrumAnalyzer" id="AudioEffectSpectrumAnalyzer_odciy"]
+resource_name = "SpectrumAnalyzer"
+fft_size = 3
+
+[resource]
+bus/0/mute = true
+bus/0/volume_db = -20.0
+bus/1/name = &"MusicAnalyzer"
+bus/1/solo = false
+bus/1/mute = false
+bus/1/bypass_fx = false
+bus/1/volume_db = 0.0
+bus/1/send = &"Master"
+bus/1/effect/0/effect = SubResource("AudioEffectSpectrumAnalyzer_odciy")
+bus/1/effect/0/enabled = true
diff --git a/examples_dd3d/addon_icon.gd b/examples_dd3d/addon_icon.gd
new file mode 100644
index 0000000..4283024
--- /dev/null
+++ b/examples_dd3d/addon_icon.gd
@@ -0,0 +1,11 @@
+@tool
+extends Node3D
+
+func _process(delta: float) -> void:
+ var a = DebugDraw3D.new_scoped_config().set_thickness(0.015)
+ DebugDraw3D.draw_box_xf($box.global_transform, Color.GREEN)
+ DebugDraw3D.draw_gizmo($gizmo.global_transform)
+ DebugDraw3D.draw_grid_xf($gizmo/grid.global_transform, Vector2i(2,2), DebugDraw3D.empty_color, false)
+ DebugDraw3D.draw_sphere_xf($sphere.global_transform, Color.RED)
+ DebugDraw3D.draw_cylinder($cylinder.global_transform, Color.BLUE)
+ DebugDraw3D.draw_line_hit_offset($"line/1".global_transform.origin, $"line/2".global_transform.origin, true, 0.3, 0.1)
diff --git a/examples_dd3d/addon_icon.tscn b/examples_dd3d/addon_icon.tscn
new file mode 100644
index 0000000..b577312
--- /dev/null
+++ b/examples_dd3d/addon_icon.tscn
@@ -0,0 +1,37 @@
+[gd_scene load_steps=3 format=3 uid="uid://1lhiwf8tgleh"]
+
+[ext_resource type="Script" path="res://examples_dd3d/addon_icon.gd" id="1_bq18y"]
+
+[sub_resource type="Environment" id="1"]
+background_mode = 1
+
+[node name="icon" type="Node3D"]
+script = ExtResource("1_bq18y")
+
+[node name="Camera" type="Camera3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5.39732)
+environment = SubResource("1")
+current = true
+
+[node name="box" type="Node3D" parent="."]
+transform = Transform3D(0.316305, 0.0204714, -0.293415, -0.239575, 0.267896, -0.239575, 0.170631, 0.338191, 0.207538, -0.410294, 0.312541, 0.243199)
+
+[node name="gizmo" type="Node3D" parent="."]
+transform = Transform3D(0.707107, 0, -0.707107, -0.294265, 0.909294, -0.294265, 0.642968, 0.416154, 0.642968, 0, 0, 0)
+
+[node name="grid" type="Node3D" parent="gizmo"]
+transform = Transform3D(1, -2.98023e-08, 1.19209e-07, 0, 1, 0, 1.19209e-07, -2.98023e-08, 1, -0.0263093, -0.0170284, -0.0263093)
+
+[node name="sphere" type="Node3D" parent="."]
+transform = Transform3D(0.401341, 0.207831, -0.437109, -0.449118, 0.371584, -0.235691, 0.180418, 0.46267, 0.385639, 0.466197, 0.322665, 0.200436)
+
+[node name="cylinder" type="Node3D" parent="."]
+transform = Transform3D(0.155034, 0.231693, -0.112783, -0.160003, 0.264761, -0.0839674, 0.0232275, 0.277352, 0.174372, -0.0566943, -0.290515, 0.905274)
+
+[node name="line" type="Node3D" parent="."]
+
+[node name="1" type="Node3D" parent="line"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.568458, -0.615948, 0.653444)
+
+[node name="2" type="Node3D" parent="line"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0051975, 0.373791, 0.0974927)
diff --git a/examples_dd3d/demo_camera_movement.gd b/examples_dd3d/demo_camera_movement.gd
new file mode 100644
index 0000000..51f758d
--- /dev/null
+++ b/examples_dd3d/demo_camera_movement.gd
@@ -0,0 +1,60 @@
+extends Camera3D
+
+@export var mouse_sensitivity := 0.25
+@export var camera_speed := 10.0
+@export var camera_speed_fast := 30.0
+
+var btn_clicked := false
+const hPI := PI/2
+var rot_x := 0.0
+var rot_y := 0.0
+
+
+func _ready():
+ reset_input_rotation()
+
+
+func _unhandled_input(event) -> void:
+ if event is InputEventMouseButton:
+ btn_clicked = event.pressed
+
+
+func reset_input_rotation():
+ rot_x = rotation.y
+ rot_y = rotation.x
+
+
+func _input(event) -> void:
+ if btn_clicked:
+ if event is InputEventMouseMotion:
+ if event.button_mask == MOUSE_BUTTON_LEFT:
+ rot_x += -deg_to_rad(event.relative.x * mouse_sensitivity)
+ rot_y += -deg_to_rad(event.relative.y * mouse_sensitivity)
+ rot_y = clamp(rot_y, -hPI, hPI)
+
+ transform.basis = Basis()
+ rotate_object_local(Vector3.UP, rot_x)
+ rotate_object_local(Vector3.RIGHT, rot_y)
+
+
+func get_axis(neg : Array[Key], pos : Array[Key]) -> float:
+ var pressed = func (arr: Array[Key]):
+ var p: float = 0
+ for k in arr:
+ if Input.is_physical_key_pressed(k):
+ p = 1
+ break
+ return p
+
+ return pressed.call(pos) - pressed.call(neg)
+
+
+func _process(delta) -> void:
+ var motion := Vector2(get_axis([KEY_S], [KEY_W]), get_axis([KEY_A], [KEY_D]))
+ var lift := get_axis([KEY_Q, KEY_CTRL], [KEY_E, KEY_SPACE])
+ var speed := camera_speed_fast if Input.is_physical_key_pressed(KEY_SHIFT) else camera_speed
+ motion = motion.limit_length()
+
+ var b := global_transform.basis
+ var v := (-b.z * motion.x) + (b.x * motion.y) + (b.y * lift)
+ global_position += v.limit_length() * speed * delta
diff --git a/examples_dd3d/demo_music_visualizer.gd b/examples_dd3d/demo_music_visualizer.gd
new file mode 100644
index 0000000..d143205
--- /dev/null
+++ b/examples_dd3d/demo_music_visualizer.gd
@@ -0,0 +1,179 @@
+@tool
+extends VBoxContainer
+
+@export_range(1, 128) var bars_count := 32
+var transform: Transform3D:
+ get:
+ return %AudioVisualizer.global_transform
+@export_exp_easing("inout") var motion_smoothing := 0.025
+@export_range(0, 0.5) var bar_thickness := 0.065
+@export_range(0, 10) var bars_separation := 0.325
+@export_exp_easing("inout") var color_offset_speed := 0.4
+@export var colors: Gradient = null
+
+var MusicAnalyzerBus := &"MusicAnalyzer"
+var MasterBus := &"Master"
+var MAX_HZ := 16000.0
+var MIN_HZ := 20.0
+var MIN_DB := 60.0
+var spectrum: AudioEffectSpectrumAnalyzerInstance = null
+
+var smoothed_energy: Array[float] = []
+var color_offset := 0.0
+
+var _on_data_loaded_callback = null
+
+# TODO remove after moving to 4.2
+var is_4_2_and_higher = Engine.get_version_info()["major"] >= 4 && Engine.get_version_info()["minor"] >= 2
+
+
+func _ready():
+ var bus = AudioServer.get_bus_index(MusicAnalyzerBus)
+ if bus == -1:
+ print("'MusicVisualizer' audio bus not found.\nSet 'VisualizerAudioBus.tres' as the default bus to use the audio visualizer.")
+
+ spectrum = AudioServer.get_bus_effect_instance(bus, 0)
+ %MuteMaster.button_pressed = AudioServer.is_bus_mute(AudioServer.get_bus_index(MasterBus))
+ %VolumeSlider.value = db_to_linear(AudioServer.get_bus_volume_db(AudioServer.get_bus_index(MasterBus)))
+
+ if OS.has_feature('web'):
+ motion_smoothing = motion_smoothing * 1.5
+
+ _on_data_loaded_callback = JavaScriptBridge.create_callback(_on_data_loaded)
+ # Retrieve the 'gd_callbacks' object
+ var gdcallbacks: JavaScriptObject = JavaScriptBridge.get_interface("gd_callbacks")
+ # Assign the callbacks
+ gdcallbacks.dataLoaded = _on_data_loaded_callback
+
+
+func _process(_delta):
+ if %MusicPlayer.playing:
+ draw_spectrum()
+
+
+func _pressed():
+ var open_file = func(filepath: String):
+ print("Opening '%s'" % filepath)
+ var file = FileAccess.open(filepath, FileAccess.READ)
+ var data = file.get_buffer(file.get_length())
+ open_stream(filepath.get_extension(), data)
+
+ if is_4_2_and_higher and DisplayServer.has_feature(DisplayServer.FEATURE_NATIVE_DIALOG):
+ # TODO remove call() and get() after moving to 4.2
+ DisplayServer.call("file_dialog_show", "Select audio file", "", "", true, DisplayServer.get("FILE_DIALOG_MODE_OPEN_FILE"), ["*.mp3"],
+ func (status: bool, selected: PackedStringArray, _fileter: int):
+ if status and selected.size():
+ open_file.call(selected[0])
+ )
+ elif OS.has_feature('web'):
+ JavaScriptBridge.eval("loadData()")
+ else:
+ var fd := FileDialog.new()
+ add_child(fd)
+
+ fd.title = "Select audio file"
+ fd.access = FileDialog.ACCESS_FILESYSTEM
+ fd.file_mode = FileDialog.FILE_MODE_OPEN_FILE
+ fd.current_dir = OS.get_system_dir(OS.SYSTEM_DIR_DOWNLOADS)
+ fd.add_filter("*.mp3")
+ fd.popup_centered_ratio(0.8)
+
+ fd.file_selected.connect(func(path: String):
+ open_file.call(path)
+ )
+
+ fd.visibility_changed.connect(func():
+ if not fd.visible:
+ fd.queue_free()
+ )
+
+
+func _on_data_loaded(data: Array) -> void:
+ # Make sure there is something
+ if (data.size() == 0):
+ return
+
+ var file_name: String = data[0]
+ print("Opening '%s'" % file_name)
+
+ var arr: PackedByteArray = JavaScriptBridge.eval("gd_callbacks.dataLoadedResult;")
+ open_stream(file_name.get_extension(), arr)
+
+
+func open_stream(file_ext: String, data: PackedByteArray):
+ var stream: AudioStream = null
+ if file_ext == "mp3":
+ stream = AudioStreamMP3.new()
+ stream.data = data
+
+ if not stream.data:
+ print("Failed to load MP3!")
+ return
+
+ if not stream:
+ print("Failed to load music!")
+ return
+
+ %MusicPlayer.stream = stream
+ %MusicPlayer.bus = MusicAnalyzerBus
+ %MusicPlayer.play()
+
+ # Debugging frequencies
+ for ih in range(1, bars_count + 1):
+ var _hz: float = log_freq(ih / float(bars_count), MIN_HZ, MAX_HZ)
+ #print("%.0f hz %.2f" % [_hz, ih / float(bars_count)])
+
+
+func draw_spectrum():
+ var _s1 = DebugDraw3D.scoped_config().set_thickness(bar_thickness).set_center_brightness(0.9)
+ var prev_hz = MIN_HZ
+ smoothed_energy.resize(bars_count)
+
+ var xf := transform
+ var y := xf.basis.y
+ var h := y.length()
+ var x := xf.basis.x
+ var z := xf.basis.z
+ var origin := xf.origin - (x * bars_count + (x * bars_separation) * (bars_count - 1)) * 0.5
+ var sum := 0.0
+
+ for ih in range(1, bars_count + 1):
+ var i := ih - 1
+ var hz: float = log_freq(ih / float(bars_count), MIN_HZ, MAX_HZ)
+ var magnitude: float = spectrum.get_magnitude_for_frequency_range(prev_hz, hz, AudioEffectSpectrumAnalyzerInstance.MAGNITUDE_AVERAGE).length()
+ var energy: float = clampf((MIN_DB + linear_to_db(magnitude)) / MIN_DB, 0, 1)
+ var e: float = lerp(smoothed_energy[i], energy, clampf(get_process_delta_time() / motion_smoothing if motion_smoothing else 1.0, 0, 1))
+ smoothed_energy[i] = e
+ var height: float = e * h
+ sum += e
+
+ var s := x * bars_separation
+
+ var a := origin + x * i + s * i + (z * 0.5)
+ var b := origin + x * (i + 1) + s * i + (z * -0.5) + xf.basis.y.normalized() * clampf(height, 0.001, h)
+ var c := Color.HOT_PINK
+ if colors:
+ c = colors.sample(wrapf(float(ih) / bars_count + color_offset, 0, 1))
+ c.s = clamp(c.s - smoothed_energy[i] * 0.3, 0, 1.0)
+
+ DebugDraw3D.draw_box_ab(a, b, y, c)
+
+ prev_hz = hz
+
+ color_offset = wrapf(color_offset + sum / smoothed_energy.size() * clampf(get_process_delta_time() / color_offset_speed if color_offset_speed else 1.0, 0, 1), 0, 1)
+
+
+func log10(val: float) -> float:
+ return log(val) / 2.302585
+
+
+func log_freq(pos: float, min_hz: float, max_hz: float) -> float:
+ return pow(10, log10(min_hz) + (log10(max_hz) - log10(min_hz)) * pos)
+
+
+func _on_volume_slider_value_changed(value):
+ AudioServer.set_bus_volume_db(AudioServer.get_bus_index(MasterBus), linear_to_db(value))
+
+
+func _on_mute_master_toggled(toggled_on):
+ AudioServer.set_bus_mute(AudioServer.get_bus_index(MasterBus), toggled_on)
diff --git a/examples_dd3d/demo_settings_panel.gd b/examples_dd3d/demo_settings_panel.gd
new file mode 100644
index 0000000..894996a
--- /dev/null
+++ b/examples_dd3d/demo_settings_panel.gd
@@ -0,0 +1,112 @@
+@tool
+extends Control
+
+@export var switch_to_scene = ""
+var is_ready := false
+
+func _ready():
+ if Engine.is_editor_hint():
+ return
+
+ if ProjectSettings.has_setting("application/config/no_csharp_support"):
+ %SwitchLang.visible = false
+
+ %SwitchLang.disabled = true
+
+ var test := DebugDraw2D.get_graph(&"FPS")
+ if test:
+ %FPSEnabled.button_pressed = test.enabled
+ %FPSMS.button_pressed = test.frame_time_mode
+ %WidthSlider.value = test.size.x
+ %BufferSlider.value = test.buffer_size
+
+ %ThicknessSlider.value = get_parent().debug_thickness
+ %FrustumScaleSlider.value = get_parent().camera_frustum_scale
+ %UpdateInPhysics.text = "Update in physics (%d Ticks) *" % ProjectSettings.get_setting("physics/common/physics_ticks_per_second")
+ %UpdateInPhysics.button_pressed = get_parent().update_in_physics
+
+ %ShowStats.button_pressed = get_parent().text_groups_show_stats
+ %DrawBoxes.button_pressed = get_parent().draw_array_of_boxes
+ %Draw1MBoxes.button_pressed = get_parent().draw_1m_boxes
+
+ if get_tree():
+ await get_tree().create_timer(0.2).timeout
+
+ %SwitchLang.disabled = false
+ is_ready = true
+
+
+func _on_CheckBox_toggled(button_pressed: bool) -> void:
+ if not is_ready: return
+
+ var cfg = DebugDraw2D.get_graph(&"FPS")
+ if cfg:
+ cfg.enabled = button_pressed
+
+
+func _on_FPSMS_toggled(button_pressed: bool) -> void:
+ if not is_ready: return
+
+ var cfg = DebugDraw2D.get_graph(&"FPS")
+ if cfg:
+ cfg.frame_time_mode = button_pressed
+
+
+func _on_Button_pressed() -> void:
+ get_tree().call_deferred("change_scene_to_file", switch_to_scene)
+
+
+func _on_hide_show_panel_pressed():
+ if %SettingsPanel.visible:
+ %SettingsPanel.hide()
+ %HideShowPanelButton.text = "Show panel"
+ else:
+ %SettingsPanel.show()
+ %HideShowPanelButton.text = "Hide panel"
+
+
+func _on_width_slider_value_changed(value):
+ if not is_ready: return
+
+ get_parent().graph_size = Vector2i(int(value), get_parent().graph_size.y)
+
+
+func _on_buffer_slider_value_changed(value):
+ if not is_ready: return
+
+ get_parent().graph_buffer_size = int(value)
+
+
+func _on_thickness_slider_value_changed(value):
+ if not is_ready: return
+
+ get_parent().debug_thickness = value
+
+
+func _on_frustum_scale_slider_value_changed(value):
+ if not is_ready: return
+
+ get_parent().camera_frustum_scale = value
+
+
+func _on_update_in_physics_toggled(toggled_on):
+ get_parent().update_in_physics = toggled_on
+
+
+func _on_show_stats_toggled(toggled_on):
+ get_parent().text_groups_show_stats = toggled_on
+
+
+func _on_draw_boxes_toggled(toggled_on):
+ get_parent().draw_array_of_boxes = toggled_on
+
+ DebugDraw3D.clear_all()
+ get_parent().timer_cubes = 0
+
+
+func _on_draw_1m_boxes_toggled(toggled_on):
+ get_parent().draw_1m_boxes = toggled_on
+
+ if get_parent().draw_array_of_boxes:
+ DebugDraw3D.clear_all()
+ get_parent().timer_cubes = 0
diff --git a/examples_dd3d/demo_web_docs_version_select.gd b/examples_dd3d/demo_web_docs_version_select.gd
new file mode 100644
index 0000000..c63bc49
--- /dev/null
+++ b/examples_dd3d/demo_web_docs_version_select.gd
@@ -0,0 +1,42 @@
+extends HBoxContainer
+
+var _on_versions_loaded_callback = null
+@onready var btn: OptionButton = $OptionButton
+
+func _enter_tree():
+ hide()
+
+
+func _ready():
+ if OS.has_feature('web'):
+ _on_versions_loaded_callback = JavaScriptBridge.create_callback(_on_versions_loaded)
+ var versions_callbacks: JavaScriptObject = JavaScriptBridge.get_interface("versions_callbacks")
+ versions_callbacks.loaded = _on_versions_loaded_callback
+
+ JavaScriptBridge.eval("loadVersions()")
+
+
+func _on_versions_loaded(args: Array) -> void:
+ if (args.size() == 0):
+ return
+
+ var current_version: String = args[0]
+
+ var versions_str: String = JavaScriptBridge.eval("versions_callbacks.versions;")
+ var version_urls_str: String = JavaScriptBridge.eval("versions_callbacks.version_urls;")
+ var versions: PackedStringArray = versions_str.split(";", false)
+ var version_urls: PackedStringArray = version_urls_str.split(";", false)
+
+ if versions:
+ show()
+ btn.clear()
+ btn.item_selected.connect(func(idx):
+ # move to another version
+ JavaScriptBridge.eval("window.location.href = \"%s\"" % version_urls[idx])
+ )
+
+ for i in range(versions.size()):
+ btn.add_item(versions[i], i)
+
+ if versions[i] == current_version:
+ btn.select(i)
diff --git a/export_presets.cfg b/export_presets.cfg
old mode 100755
new mode 100644
index 7ac06b5..40b5bdb
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -13,13 +13,12 @@ encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
-script_encryption_key=""
[preset.0.options]
custom_template/debug=""
custom_template/release=""
-debug/export_console_script=1
+debug/export_console_wrapper=0
binary_format/embed_pck=true
texture_format/bptc=false
texture_format/s3tc=true
@@ -27,9 +26,6 @@ texture_format/etc=false
texture_format/etc2=false
binary_format/architecture="x86_64"
codesign/enable=false
-codesign/identity_type=0
-codesign/identity=""
-codesign/password=""
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
@@ -46,6 +42,7 @@ application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
+application/export_angle=0
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
@@ -63,6 +60,7 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"
+debug/export_console_script=1
[preset.1]
@@ -79,13 +77,12 @@ encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
-script_encryption_key=""
[preset.1.options]
custom_template/debug=""
custom_template/release=""
-debug/export_console_script=1
+debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/bptc=false
texture_format/s3tc=true
@@ -104,6 +101,7 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""
+debug/export_console_script=1
[preset.2]
@@ -120,14 +118,14 @@ encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
-script_encryption_key=""
[preset.2.options]
+export/distribution_type=1
binary_format/architecture="universal"
custom_template/debug=""
custom_template/release=""
-debug/export_console_script=1
+debug/export_console_wrapper=1
application/icon=""
application/icon_interpolation=4
application/bundle_identifier=""
@@ -137,11 +135,19 @@ application/short_version="1.0"
application/version="1.0"
application/copyright=""
application/copyright_localized={}
+application/min_macos_version="10.12"
+application/export_angle=0
display/high_res=true
+xcode/platform_build="14C18"
+xcode/sdk_version="13.1"
+xcode/sdk_build="22C55"
+xcode/sdk_name="macosx13.1"
+xcode/xcode_version="1420"
+xcode/xcode_build="14C18"
codesign/codesign=1
+codesign/installer_identity=""
+codesign/apple_team_id=""
codesign/identity=""
-codesign/certificate_file=""
-codesign/certificate_password=""
codesign/entitlements/custom_file=""
codesign/entitlements/allow_jit_code_execution=false
codesign/entitlements/allow_unsigned_executable_memory=false
@@ -164,15 +170,10 @@ codesign/entitlements/app_sandbox/files_downloads=0
codesign/entitlements/app_sandbox/files_pictures=0
codesign/entitlements/app_sandbox/files_music=0
codesign/entitlements/app_sandbox/files_movies=0
+codesign/entitlements/app_sandbox/files_user_selected=0
codesign/entitlements/app_sandbox/helper_executables=[]
codesign/custom_options=PackedStringArray()
notarization/notarization=0
-notarization/apple_id_name=""
-notarization/apple_id_password=""
-notarization/apple_team_id=""
-notarization/api_uuid=""
-notarization/api_key=""
-notarization/api_key_id=""
privacy/microphone_usage_description=""
privacy/microphone_usage_description_localized={}
privacy/camera_usage_description=""
@@ -206,3 +207,5 @@ open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""
+debug/export_console_script=1
+notarization/apple_team_id=""
diff --git a/project.godot b/project.godot
index 7748d80..5905962 100644
--- a/project.godot
+++ b/project.godot
@@ -12,7 +12,7 @@ config_version=5
config/name="AMSG"
run/main_scene="res://AMSG_Examples/Maps/MovementTestMap.tscn"
-config/features=PackedStringArray("4.2")
+config/features=PackedStringArray("4.3")
config/icon="res://AMSG_Examples/icon.png"
[autoload]
@@ -49,32 +49,32 @@ singletons_disabled=[]
forward={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
back={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
left={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
right={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
jump={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
sprint={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
aim={
@@ -84,32 +84,32 @@ aim={
}
crouch={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
interaction={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":70,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":70,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
switch_camera_view={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":67,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":67,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
ragdoll={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":88,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":88,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
flashlight={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":76,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":76,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
EnableSDFGI={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":71,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":71,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
fire={
@@ -119,12 +119,27 @@ fire={
}
exit={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
pause={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":80,"physical_keycode":0,"key_label":0,"unicode":112,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":80,"physical_keycode":0,"key_label":0,"unicode":112,"location":0,"echo":false,"script":null)
+]
+}
+show_panel={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":78,"key_label":0,"unicode":110,"location":0,"echo":false,"script":null)
+]
+}
+show_debug={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":73,"key_label":0,"unicode":105,"location":0,"echo":false,"script":null)
+]
+}
+switch_distance_matching={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":75,"key_label":0,"unicode":107,"location":0,"echo":false,"script":null)
]
}