3D Cameras with sweep and animation

This commit is contained in:
Marco 2025-06-27 15:06:33 +02:00
commit 7e76edc153
48 changed files with 3211 additions and 1511 deletions

View file

@ -0,0 +1,71 @@
extends PanelContainer
@export var vision_cone : VisionCone3D
@export var cameras : Array[Camera3D] = []
@onready var vision_test_center_checkbox : CheckBox = %VisionTestCenterCheckBox
@onready var vision_test_scatter_checkbox : CheckBox = %VisionTestScatterCheckBox
@onready var raycast_count_slider : Slider = %RaycastsPerFrameSlider
@onready var angle_slider : Slider = %AngleSlider
@onready var range_slider : Slider = %RangeSlider
@onready var rotation_slider : Slider = %ObserverRotationSlider
@onready var position_slider : Slider = %ObserverPositionSlider
@onready var max_bodies_slider : Slider = %MaxBodiesSlider
@onready var switch_camera_button : Button = %SwitchCameraButton
func _ready():
vision_test_center_checkbox.toggled.connect(_set_center)
vision_test_scatter_checkbox.toggled.connect(_set_scatter)
raycast_count_slider.value_changed.connect(func(value: float): vision_cone.vision_test_shape_max_probe_count = value)
angle_slider.value_changed.connect(func(value: float): vision_cone.angle = value)
range_slider.value_changed.connect(func(value: float): vision_cone.range = value)
rotation_slider.value_changed.connect(func(value: float): vision_cone.get_parent().rotation_degrees.y = -value)
position_slider.value_changed.connect(func(value: float): vision_cone.get_parent().position.x = value)
max_bodies_slider.value_changed.connect(func(value: float): vision_cone.vision_test_max_body_count = value)
if cameras.is_empty():
switch_camera_button.hide()
else:
cameras[0].current = true
switch_camera_button.text = "Current Camera: " + cameras[0].name
switch_camera_button.pressed.connect(
func():
for i in cameras.size():
var cam := cameras[i]
if cam.current:
cam.current = false
var next_cam : Camera3D
if (i + 1) < cameras.size():
next_cam = cameras[i + 1]
else:
next_cam = cameras[0]
next_cam.current = true
switch_camera_button.text = "Current Camera: " + next_cam.name
return
)
angle_slider.value = vision_cone.angle
range_slider.value = vision_cone.range
max_bodies_slider.value = vision_cone.vision_test_max_body_count
raycast_count_slider.value = vision_cone.vision_test_shape_max_probe_count
if vision_cone.get_parent() is CharacterBody3D:
vision_cone.get_parent().rotation_degrees.y = -rotation_slider.value
vision_cone.get_parent().position.x = position_slider.value
else:
rotation_slider.get_parent().hide()
position_slider.get_parent().hide()
_set_center(vision_test_center_checkbox.button_pressed)
_set_scatter(vision_test_scatter_checkbox.button_pressed)
size.y = 0
func _set_center(value: bool):
if !value:
return
vision_cone.vision_test_mode = VisionCone3D.VisionTestMode.SAMPLE_CENTER
func _set_scatter(value: bool):
if !value:
return
vision_cone.vision_test_mode = VisionCone3D.VisionTestMode.SAMPLE_RANDOM_VERTICES

View file

@ -0,0 +1 @@
uid://dof1xi7gcbq7s

View file

@ -0,0 +1,16 @@
[gd_scene load_steps=3 format=3 uid="uid://mqvpirrmppob"]
[sub_resource type="BoxShape3D" id="BoxShape3D_da376"]
size = Vector3(1, 3, 1)
[sub_resource type="BoxMesh" id="BoxMesh_mb6rt"]
size = Vector3(1, 3, 1)
[node name="Blocker" type="StaticBody3D"]
collision_layer = 2
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("BoxShape3D_da376")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
mesh = SubResource("BoxMesh_mb6rt")

View file

@ -0,0 +1,39 @@
[gd_scene load_steps=5 format=3 uid="uid://batptfh4cwpfb"]
[ext_resource type="PackedScene" uid="uid://cmgl8607thxgg" path="res://addons/tattomoosa.vision_cone_3d/examples/example_src/observable.tscn" id="1_p0bro"]
[sub_resource type="Animation" id="Animation_c3q4w"]
length = 0.001
tracks/0/type = "position_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, -0.195181, 0, -1.77211)
[sub_resource type="Animation" id="Animation_jctf1"]
resource_name = "back_and_forth"
length = 8.0
loop_mode = 1
tracks/0/type = "position_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 0, 0, 0, 2.03333, 1, 4, 0, 0, 6.03333, 1, -4, 0, 0, 8, 1, 0, 0, 0)
[sub_resource type="AnimationLibrary" id="AnimationLibrary_al81f"]
_data = {
&"RESET": SubResource("Animation_c3q4w"),
&"back_and_forth": SubResource("Animation_jctf1")
}
[node name="MovingObservable" instance=ExtResource("1_p0bro")]
transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, -0.195181, 0, -1.77211)
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="2"]
libraries = {
"": SubResource("AnimationLibrary_al81f")
}

View file

@ -0,0 +1,31 @@
[gd_scene load_steps=6 format=3 uid="uid://cmgl8607thxgg"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_dnr2f"]
albedo_color = Color(0, 0, 0, 1)
[sub_resource type="CapsuleMesh" id="CapsuleMesh_nj3xo"]
material = SubResource("StandardMaterial3D_dnr2f")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ecabg"]
albedo_color = Color(1, 0.635294, 1, 1)
[sub_resource type="CapsuleMesh" id="CapsuleMesh_5i4ah"]
material = SubResource("StandardMaterial3D_ecabg")
radius = 0.25
height = 0.75
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_cf0b5"]
[node name="Observable" type="CharacterBody3D"]
transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0, 0, 0)
metadata/_edit_group_ = true
[node name="Body" type="MeshInstance3D" parent="."]
mesh = SubResource("CapsuleMesh_nj3xo")
[node name="Face" type="MeshInstance3D" parent="Body"]
transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0.386695, -0.364832)
mesh = SubResource("CapsuleMesh_5i4ah")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_cf0b5")

View file

@ -0,0 +1,34 @@
[gd_scene load_steps=6 format=3 uid="uid://brqivkckug8uc"]
[ext_resource type="Script" uid="uid://cmgcelj1qxg8o" path="res://addons/tattomoosa.vision_cone_3d/src/VisionCone3D.gd" id="1_t4wly"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_td2ym"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ecabg"]
albedo_color = Color(1, 0.635294, 1, 1)
[sub_resource type="CapsuleMesh" id="CapsuleMesh_5i4ah"]
material = SubResource("StandardMaterial3D_ecabg")
radius = 0.25
height = 0.75
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_cf0b5"]
[node name="Observer" type="CharacterBody3D"]
metadata/_edit_group_ = true
[node name="VisionCone3D" type="Area3D" parent="." node_paths=PackedStringArray("vision_test_ignore_bodies")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.41062, -0.023833)
script = ExtResource("1_t4wly")
debug_draw = true
vision_test_ignore_bodies = [NodePath("..")]
[node name="Body" type="MeshInstance3D" parent="."]
mesh = SubResource("CapsuleMesh_td2ym")
[node name="Face" type="MeshInstance3D" parent="Body"]
transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0.386695, -0.364832)
mesh = SubResource("CapsuleMesh_5i4ah")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_cf0b5")

View file

@ -0,0 +1,10 @@
extends Label
@export var range_control : Range
func _ready():
range_control.value_changed.connect(_set_displayed_value)
_set_displayed_value(range_control.value)
func _set_displayed_value(_value: float):
text = str(_value)

View file

@ -0,0 +1 @@
uid://be67a8jv24c5o

View file

@ -0,0 +1,186 @@
[gd_scene load_steps=4 format=3 uid="uid://cdbsstpvtrvhd"]
[ext_resource type="Script" uid="uid://dof1xi7gcbq7s" path="res://addons/tattomoosa.vision_cone_3d/examples/example_src/VisionConeDemoControls.gd" id="1_vf8s6"]
[ext_resource type="Script" uid="uid://be67a8jv24c5o" path="res://addons/tattomoosa.vision_cone_3d/examples/example_src/ui/ValueLabel.gd" id="2_8lgvy"]
[sub_resource type="ButtonGroup" id="ButtonGroup_dqtte"]
[node name="VisionConeControls" type="PanelContainer"]
offset_left = 13.0
offset_top = 14.0
offset_right = 308.0
offset_bottom = 24.0
script = ExtResource("1_vf8s6")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
theme_override_constants/separation = 20
[node name="Range" type="VBoxContainer" parent="VBoxContainer"]
layout_mode = 2
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/Range"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Range/HBoxContainer2"]
layout_mode = 2
text = "Range:"
[node name="RangeValueLabel" type="Label" parent="VBoxContainer/Range/HBoxContainer2" node_paths=PackedStringArray("range_control")]
layout_mode = 2
script = ExtResource("2_8lgvy")
range_control = NodePath("../../RangeSlider")
[node name="RangeSlider" type="HSlider" parent="VBoxContainer/Range"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
min_value = 1.0
max_value = 40.0
step = 0.5
value = 20.0
[node name="Angle" type="VBoxContainer" parent="VBoxContainer"]
layout_mode = 2
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/Angle"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/Angle/HBoxContainer2"]
layout_mode = 2
text = "Angle:"
[node name="AngleValueLabel" type="Label" parent="VBoxContainer/Angle/HBoxContainer2" node_paths=PackedStringArray("range_control")]
layout_mode = 2
script = ExtResource("2_8lgvy")
range_control = NodePath("../../AngleSlider")
[node name="AngleSlider" type="HSlider" parent="VBoxContainer/Angle"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
min_value = 0.1
max_value = 90.0
step = 0.1
value = 45.0
[node name="VisionTestModeControls" type="VBoxContainer" parent="VBoxContainer"]
layout_mode = 2
[node name="Label2" type="Label" parent="VBoxContainer/VisionTestModeControls"]
layout_mode = 2
text = "Vision Test Mode"
[node name="VisionTestMode" type="HBoxContainer" parent="VBoxContainer/VisionTestModeControls"]
layout_mode = 2
[node name="VisionTestCenterCheckBox" type="CheckBox" parent="VBoxContainer/VisionTestModeControls/VisionTestMode"]
unique_name_in_owner = true
layout_mode = 2
button_group = SubResource("ButtonGroup_dqtte")
text = "Center"
[node name="VisionTestScatterCheckBox" type="CheckBox" parent="VBoxContainer/VisionTestModeControls/VisionTestMode"]
unique_name_in_owner = true
layout_mode = 2
button_pressed = true
button_group = SubResource("ButtonGroup_dqtte")
text = "Scatter"
[node name="ProbesPerFrame" type="VBoxContainer" parent="VBoxContainer/VisionTestModeControls"]
layout_mode = 2
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/VisionTestModeControls/ProbesPerFrame"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/VisionTestModeControls/ProbesPerFrame/HBoxContainer2"]
layout_mode = 2
text = "Max Probes Per Shape:"
[node name="RaycastPerFrameValueLabel" type="Label" parent="VBoxContainer/VisionTestModeControls/ProbesPerFrame/HBoxContainer2" node_paths=PackedStringArray("range_control")]
layout_mode = 2
script = ExtResource("2_8lgvy")
range_control = NodePath("../../RaycastsPerFrameSlider")
[node name="RaycastsPerFrameSlider" type="HSlider" parent="VBoxContainer/VisionTestModeControls/ProbesPerFrame"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
min_value = 1.0
value = 10.0
[node name="MaxBodies" type="VBoxContainer" parent="VBoxContainer/VisionTestModeControls"]
layout_mode = 2
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/VisionTestModeControls/MaxBodies"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/VisionTestModeControls/MaxBodies/HBoxContainer2"]
layout_mode = 2
text = "Max Bodies Per Frame:"
[node name="MaxBodiesFrameValueLabel" type="Label" parent="VBoxContainer/VisionTestModeControls/MaxBodies/HBoxContainer2" node_paths=PackedStringArray("range_control")]
layout_mode = 2
script = ExtResource("2_8lgvy")
range_control = NodePath("../../MaxBodiesSlider")
[node name="MaxBodiesSlider" type="HSlider" parent="VBoxContainer/VisionTestModeControls/MaxBodies"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
min_value = 1.0
max_value = 500.0
value = 11.0
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer"]
layout_mode = 2
[node name="SwitchCameraButton" type="Button" parent="VBoxContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Switch Camera"
[node name="ObserverRotation" type="VBoxContainer" parent="VBoxContainer/VBoxContainer"]
layout_mode = 2
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/VBoxContainer/ObserverRotation"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/VBoxContainer/ObserverRotation/HBoxContainer2"]
layout_mode = 2
text = "Observer Rotation:"
[node name="ObserverRotationValueLabel" type="Label" parent="VBoxContainer/VBoxContainer/ObserverRotation/HBoxContainer2" node_paths=PackedStringArray("range_control")]
layout_mode = 2
script = ExtResource("2_8lgvy")
range_control = NodePath("../../ObserverRotationSlider")
[node name="ObserverRotationSlider" type="HSlider" parent="VBoxContainer/VBoxContainer/ObserverRotation"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
min_value = -90.0
max_value = 90.0
[node name="ObserverPosition" type="VBoxContainer" parent="VBoxContainer/VBoxContainer"]
layout_mode = 2
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/VBoxContainer/ObserverPosition"]
layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/VBoxContainer/ObserverPosition/HBoxContainer2"]
layout_mode = 2
text = "Observer Position:"
[node name="ObserverPositionValueLabel" type="Label" parent="VBoxContainer/VBoxContainer/ObserverPosition/HBoxContainer2" node_paths=PackedStringArray("range_control")]
layout_mode = 2
script = ExtResource("2_8lgvy")
range_control = NodePath("../../ObserverPositionSlider")
[node name="ObserverPositionSlider" type="HSlider" parent="VBoxContainer/VBoxContainer/ObserverPosition"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
min_value = -8.0
max_value = 8.0
step = 0.1