Dump project so far

This commit is contained in:
Rodolphe Houdas 2023-10-05 22:49:04 +01:00
commit 957d6f97f1
21 changed files with 785 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Godot 4+ specific ignores
.godot/
android/
builds/

Binary file not shown.

View File

@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://bqu3h3gaj6eqr"
path="res://.godot/imported/263786__steaq__seagull-single-call.ogg-b5ba7a89fd68ec1083d6e14132014866.oggvorbisstr"
[deps]
source_file="res://audio/263786__steaq__seagull-single-call.ogg"
dest_files=["res://.godot/imported/263786__steaq__seagull-single-call.ogg-b5ba7a89fd68ec1083d6e14132014866.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://cqetbevo485vt"
path="res://.godot/imported/468245__christianand__1_1_gaviota.wav-3e3a11453f0d4f55c9940cba021d8af8.sample"
[deps]
source_file="res://audio/468245__christianand__1_1_gaviota.wav"
dest_files=["res://.godot/imported/468245__christianand__1_1_gaviota.wav-3e3a11453f0d4f55c9940cba021d8af8.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=0

201
export_presets.cfg Normal file
View File

@ -0,0 +1,201 @@
[preset.0]
name="Android"
platform="Android"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="builds/Boids.apk"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.0.options]
custom_template/debug=""
custom_template/release=""
gradle_build/use_gradle_build=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
version/code=1
version/name=""
package/unique_name="com.example.$genname"
package/name=""
package/signed=true
package/app_category=2
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
package/show_in_android_tv=false
package/show_in_app_library=true
package/show_as_launcher_app=false
launcher_icons/main_192x192=""
launcher_icons/adaptive_foreground_432x432=""
launcher_icons/adaptive_background_432x432=""
graphics/opengl_debug=false
xr_features/xr_mode=0
screen/immersive_mode=true
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
user_data_backup/allow=false
command_line/extra_args=""
apk_expansion/enable=false
apk_expansion/SALT=""
apk_expansion/public_key=""
permissions/custom_permissions=PackedStringArray()
permissions/access_checkin_properties=false
permissions/access_coarse_location=false
permissions/access_fine_location=false
permissions/access_location_extra_commands=false
permissions/access_mock_location=false
permissions/access_network_state=false
permissions/access_surface_flinger=false
permissions/access_wifi_state=false
permissions/account_manager=false
permissions/add_voicemail=false
permissions/authenticate_accounts=false
permissions/battery_stats=false
permissions/bind_accessibility_service=false
permissions/bind_appwidget=false
permissions/bind_device_admin=false
permissions/bind_input_method=false
permissions/bind_nfc_service=false
permissions/bind_notification_listener_service=false
permissions/bind_print_service=false
permissions/bind_remoteviews=false
permissions/bind_text_service=false
permissions/bind_vpn_service=false
permissions/bind_wallpaper=false
permissions/bluetooth=false
permissions/bluetooth_admin=false
permissions/bluetooth_privileged=false
permissions/brick=false
permissions/broadcast_package_removed=false
permissions/broadcast_sms=false
permissions/broadcast_sticky=false
permissions/broadcast_wap_push=false
permissions/call_phone=false
permissions/call_privileged=false
permissions/camera=false
permissions/capture_audio_output=false
permissions/capture_secure_video_output=false
permissions/capture_video_output=false
permissions/change_component_enabled_state=false
permissions/change_configuration=false
permissions/change_network_state=false
permissions/change_wifi_multicast_state=false
permissions/change_wifi_state=false
permissions/clear_app_cache=false
permissions/clear_app_user_data=false
permissions/control_location_updates=false
permissions/delete_cache_files=false
permissions/delete_packages=false
permissions/device_power=false
permissions/diagnostic=false
permissions/disable_keyguard=false
permissions/dump=false
permissions/expand_status_bar=false
permissions/factory_test=false
permissions/flashlight=false
permissions/force_back=false
permissions/get_accounts=false
permissions/get_package_size=false
permissions/get_tasks=false
permissions/get_top_activity_info=false
permissions/global_search=false
permissions/hardware_test=false
permissions/inject_events=false
permissions/install_location_provider=false
permissions/install_packages=false
permissions/install_shortcut=false
permissions/internal_system_window=false
permissions/internet=false
permissions/kill_background_processes=false
permissions/location_hardware=false
permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/manage_external_storage=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
permissions/modify_phone_state=false
permissions/mount_format_filesystems=false
permissions/mount_unmount_filesystems=false
permissions/nfc=false
permissions/persistent_activity=false
permissions/process_outgoing_calls=false
permissions/read_calendar=false
permissions/read_call_log=false
permissions/read_contacts=false
permissions/read_external_storage=false
permissions/read_frame_buffer=false
permissions/read_history_bookmarks=false
permissions/read_input_state=false
permissions/read_logs=false
permissions/read_phone_state=false
permissions/read_profile=false
permissions/read_sms=false
permissions/read_social_stream=false
permissions/read_sync_settings=false
permissions/read_sync_stats=false
permissions/read_user_dictionary=false
permissions/reboot=false
permissions/receive_boot_completed=false
permissions/receive_mms=false
permissions/receive_sms=false
permissions/receive_wap_push=false
permissions/record_audio=false
permissions/reorder_tasks=false
permissions/restart_packages=false
permissions/send_respond_via_message=false
permissions/send_sms=false
permissions/set_activity_watcher=false
permissions/set_alarm=false
permissions/set_always_finish=false
permissions/set_animation_scale=false
permissions/set_debug_app=false
permissions/set_orientation=false
permissions/set_pointer_speed=false
permissions/set_preferred_applications=false
permissions/set_process_limit=false
permissions/set_time=false
permissions/set_time_zone=false
permissions/set_wallpaper=false
permissions/set_wallpaper_hints=false
permissions/signal_persistent_processes=false
permissions/status_bar=false
permissions/subscribed_feeds_read=false
permissions/subscribed_feeds_write=false
permissions/system_alert_window=false
permissions/transmit_ir=false
permissions/uninstall_shortcut=false
permissions/update_device_stats=false
permissions/use_credentials=false
permissions/use_sip=false
permissions/vibrate=false
permissions/wake_lock=false
permissions/write_apn_settings=false
permissions/write_calendar=false
permissions/write_call_log=false
permissions/write_contacts=false
permissions/write_external_storage=false
permissions/write_gservices=false
permissions/write_history_bookmarks=false
permissions/write_profile=false
permissions/write_secure_settings=false
permissions/write_settings=false
permissions/write_sms=false
permissions/write_social_stream=false
permissions/write_sync_settings=false
permissions/write_user_dictionary=false

1
icon.svg Normal file
View File

@ -0,0 +1 @@
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>

After

Width:  |  Height:  |  Size: 950 B

37
icon.svg.import Normal file
View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://fd8hv8pnk3yh"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

16
materials/Floor.tres Normal file
View File

@ -0,0 +1,16 @@
[gd_resource type="StandardMaterial3D" load_steps=3 format=3 uid="uid://bstu27rlas6p3"]
[sub_resource type="Gradient" id="Gradient_xinc1"]
offsets = PackedFloat32Array(0, 0.673759, 1)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_ufltb"]
gradient = SubResource("Gradient_xinc1")
width = 1080
height = 1080
fill = 1
fill_from = Vector2(0.5, 0.5)
[resource]
transparency = 1
albedo_texture = SubResource("GradientTexture2D_ufltb")

BIN
models/Flying gull.glb Normal file

Binary file not shown.

View File

@ -0,0 +1,32 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cqxgihqmydjne"
path="res://.godot/imported/Flying gull.glb-506646a523b2aedea32925cfeeaf86f8.scn"
[deps]
source_file="res://models/Flying gull.glb"
dest_files=["res://.godot/imported/Flying gull.glb-506646a523b2aedea32925cfeeaf86f8.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=0.01
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/embedded_image_handling=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cdg8likswgkmq"
path.s3tc="res://.godot/imported/Flying gull_Gull tex1.png-a95c50707d425b143a8393cd99cc0da3.s3tc.ctex"
path.etc2="res://.godot/imported/Flying gull_Gull tex1.png-a95c50707d425b143a8393cd99cc0da3.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
generator_parameters={}
[deps]
source_file="res://models/Flying gull_Gull tex1.png"
dest_files=["res://.godot/imported/Flying gull_Gull tex1.png-a95c50707d425b143a8393cd99cc0da3.s3tc.ctex", "res://.godot/imported/Flying gull_Gull tex1.png-a95c50707d425b143a8393cd99cc0da3.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

24
project.godot Normal file
View File

@ -0,0 +1,24 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Boids"
run/main_scene="res://scenes/Main.tscn"
config/features=PackedStringArray("4.1", "Forward Plus")
config/icon="res://icon.svg"
[input_devices]
pointing/emulate_touch_from_mouse=true
[rendering]
textures/vram_compression/import_etc2_astc=true

24
scenes/Boid.tscn Normal file
View File

@ -0,0 +1,24 @@
[gd_scene load_steps=5 format=3 uid="uid://bi3r8vqt5ykrt"]
[ext_resource type="PackedScene" uid="uid://cqxgihqmydjne" path="res://models/Flying gull.glb" id="1_4clbi"]
[ext_resource type="Script" path="res://scripts/Boid.gd" id="1_vg173"]
[ext_resource type="AudioStream" uid="uid://bqu3h3gaj6eqr" path="res://audio/263786__steaq__seagull-single-call.ogg" id="3_tean7"]
[ext_resource type="AudioStream" uid="uid://cqetbevo485vt" path="res://audio/468245__christianand__1_1_gaviota.wav" id="4_pieko"]
[node name="Boid" type="Node3D"]
script = ExtResource("1_vg173")
max_timer = 30.0
min_timer = 10.0
[node name="Flying gull" parent="." instance=ExtResource("1_4clbi")]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 0, 0)
[node name="SeagullSound1" type="AudioStreamPlayer3D" parent="."]
stream = ExtResource("3_tean7")
[node name="SeagullSound2" type="AudioStreamPlayer3D" parent="."]
stream = ExtResource("4_pieko")
[node name="Timer" type="Timer" parent="."]
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]

88
scenes/Main.tscn Normal file
View File

@ -0,0 +1,88 @@
[gd_scene load_steps=12 format=3 uid="uid://p2vvd6l1rose"]
[ext_resource type="Script" path="res://scripts/CameraControl.gd" id="1_tck22"]
[ext_resource type="Script" path="res://scripts/BoidsManager.gd" id="1_v84o5"]
[ext_resource type="PackedScene" uid="uid://bi3r8vqt5ykrt" path="res://scenes/Boid.tscn" id="2_did81"]
[ext_resource type="AudioStream" uid="uid://bqu3h3gaj6eqr" path="res://audio/263786__steaq__seagull-single-call.ogg" id="3_4pkn6"]
[ext_resource type="AudioStream" uid="uid://cqetbevo485vt" path="res://audio/468245__christianand__1_1_gaviota.wav" id="4_4rbpg"]
[ext_resource type="Material" uid="uid://bstu27rlas6p3" path="res://materials/Floor.tres" id="6_7a1uq"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_d6oc0"]
sky_top_color = Color(1, 1, 1, 1)
sky_horizon_color = Color(0.835294, 0.839216, 0.847059, 1)
ground_bottom_color = Color(0.898039, 0.898039, 0.898039, 1)
ground_horizon_color = Color(0.835355, 0.839277, 0.847089, 1)
[sub_resource type="Sky" id="Sky_ggc3l"]
sky_material = SubResource("ProceduralSkyMaterial_d6oc0")
[sub_resource type="Environment" id="Environment_ptyca"]
background_mode = 2
sky = SubResource("Sky_ggc3l")
[sub_resource type="CylinderShape3D" id="CylinderShape3D_s5kna"]
radius = 5.0
[sub_resource type="PlaneMesh" id="PlaneMesh_usmhe"]
size = Vector2(25, 25)
[node name="Node3D" type="Node3D"]
[node name="Pan" type="Node3D" parent="." node_paths=PackedStringArray("events_label", "drag_label")]
script = ExtResource("1_tck22")
events_label = NodePath("../Panel/VBoxContainer/Count")
drag_label = NodePath("../Panel/VBoxContainer/Drag")
[node name="Tilt" type="Node3D" parent="Pan"]
transform = Transform3D(1, 0, 0, 0, 0.996195, 0.0871557, 0, -0.0871557, 0.996195, 0, 0, 0)
[node name="Camera3D" type="Camera3D" parent="Pan/Tilt"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10)
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 2, 0)
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_ptyca")
[node name="Boids" type="Node3D" parent="." node_paths=PackedStringArray("resources")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, 0)
script = ExtResource("1_v84o5")
resources = NodePath("../ResourcePreloader")
start_count = 20
spawn_volume = Vector3(10, 5, 10)
protected_range = 2.0
visual_range = 3.0
avoid_factor = 1.0
matching_factor = 0.02
min_speed = 5.0
max_speed = 10.0
shape = SubResource("CylinderShape3D_s5kna")
[node name="ResourcePreloader" type="ResourcePreloader" parent="."]
resources = [PackedStringArray("Boid", "Seagull", "SeagullTwo"), [ExtResource("2_did81"), ExtResource("3_4pkn6"), ExtResource("4_4rbpg")]]
[node name="Panel" type="Panel" parent="."]
visible = false
offset_right = 301.0
offset_bottom = 157.0
[node name="VBoxContainer" type="VBoxContainer" parent="Panel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Count" type="Label" parent="Panel/VBoxContainer"]
layout_mode = 2
text = "Touch events:"
[node name="Drag" type="Label" parent="Panel/VBoxContainer"]
layout_mode = 2
text = "Touch events:"
[node name="CSGMesh3D" type="CSGMesh3D" parent="."]
material_override = ExtResource("6_7a1uq")
mesh = SubResource("PlaneMesh_usmhe")

20
scripts/Boid.gd Normal file
View File

@ -0,0 +1,20 @@
extends Node3D
class_name Boid
@export var max_timer : float = 10
@export var min_timer : float = 5
var velocity : Vector3 = Vector3(0, 0, 0)
func _ready():
$Timer.wait_time = randf_range(min_timer, max_timer)
$Timer.start()
func _on_timer_timeout():
$Timer.wait_time = randf_range(min_timer, max_timer)
var dice : int = (randi() % 6) + 1
if dice == 6:
$SeagullSound2.play()
else:
$SeagullSound1.play()

202
scripts/BoidsManager.gd Normal file
View File

@ -0,0 +1,202 @@
extends Node3D
@export var resources : ResourcePreloader
@export_subgroup("Initialisation")
@export var start_count : int = 10
@export var spawn_volume : Vector3 = Vector3.ONE
@export_subgroup("Boid settings")
@export var protected_range : float = 1.0
@export var visual_range : float = 2.0
@export var centering_factor : float = 0.0005
@export var avoid_factor : float = 0.05
@export var matching_factor : float = 0.05
@export var min_speed : float = 2.0
@export var max_speed : float = 3.0
@export var turn_factor : float = 0.2
@export var margin : float = 0.3
@export_subgroup("Edges")
@export var shape : Shape3D
@export_subgroup("Gravity")
@export var use_gravity : bool = true
@export var gravity_vector : Vector3 = Vector3(0, -9.807, 0)
@export var gravity_factor : float = 0.1
var boids : Array[Boid]
var boid_scene : PackedScene
var protected_range_squared : float
var visual_range_squared : float
# Called when the node enters the scene tree for the first time.
func _ready():
protected_range_squared = pow(protected_range, 2)
visual_range_squared = pow(visual_range, 2)
boid_scene = resources.get_resource("Boid")
for i in range(start_count):
var boid : Boid = boid_scene.instantiate()
boid.position = random_pos()
boid.velocity = random_vel()
add_child(boid)
boids.push_back(boid)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
for boid in boids:
var neighboring_boids : int = 0
var close : Vector3 = Vector3.ZERO
var position_avg : Vector3 = Vector3.ZERO
var velocity_avg : Vector3 = Vector3.ZERO
for other_boid in boids.filter(func(cur): return cur != boid):
# Micro optimization, don't compute distance yet, just check if it's in the range by checking
# individual dimension distances
var diff : Vector3 = other_boid.position - boid.position
if abs(diff.x) < visual_range and abs(diff.y) < visual_range and abs(diff.z) < visual_range:
# Using the squared distance so it performs better
var squared_distance : float = boid.position.distance_squared_to(other_boid.position)
# If other boid too close, add the difference (if multiple boids too close, it should average naturally)
if squared_distance < protected_range_squared:
close -= diff
# If other boid in visual range, we add its position and velocity
elif squared_distance < visual_range_squared:
position_avg += other_boid.position
velocity_avg += other_boid.velocity
neighboring_boids += 1
# We collected all data related to neighboring boids
# Let's change our boid behavior
if neighboring_boids > 0:
position_avg /= neighboring_boids
velocity_avg /= neighboring_boids
boid.velocity = (boid.velocity +
(position_avg - boid.position) * centering_factor +
(velocity_avg - boid.velocity) * matching_factor
)
# Add avoidance contribution to velocity
boid.velocity = boid.velocity + (close * avoid_factor)
# Edge avoidance
boid.velocity = apply_edge_avoidance(boid.position, boid.velocity)
boid.velocity = apply_gravity(boid.velocity, delta)
boid.velocity = apply_speed_limits(boid.velocity)
# Update position, finally!
boid.position += boid.velocity * delta
boid.look_at(boid.global_position + boid.velocity.normalized())
func apply_edge_avoidance(position : Vector3, velocity : Vector3) -> Vector3:
if shape is BoxShape3D:
velocity = apply_cube_edge_avoidance(position, velocity, shape as BoxShape3D)
elif shape is CylinderShape3D:
velocity = apply_cylinder_edge_avoidance(position, velocity, shape as CylinderShape3D)
elif shape is SphereShape3D:
velocity = apply_sphere_edge_avoidance(position, velocity, shape as SphereShape3D)
else:
print("Shape not implemented!")
return velocity
func apply_cube_edge_avoidance(position : Vector3, velocity : Vector3, box : BoxShape3D) -> Vector3:
if position.x < (-box.size.x / 2.0) + margin:
velocity.x += turn_factor
if position.x > (box.size.x / 2.0) - margin:
velocity.x -= turn_factor
if position.y < (-box.size.y / 2.0) + margin:
velocity.y += turn_factor
if position.y > (box.size.y / 2.0) - margin:
velocity.y -= turn_factor
if position.z < (-box.size.z / 2.0) + margin:
velocity.z += turn_factor
if position.z > (box.size.z / 2.0) - margin:
velocity.z -= turn_factor
return velocity
func apply_cylinder_edge_avoidance(position : Vector3, velocity : Vector3, cylinder : CylinderShape3D) -> Vector3:
if position.y < (-cylinder.height / 2.0) + margin:
velocity.y += turn_factor
if position.y > (cylinder.height / 2.0) - margin:
velocity.y -= turn_factor
# We're centering around zero so let's take the position as direction
var direction : Vector2 = Vector2(position.x, position.z)
if direction.length() > cylinder.radius - margin:
var turn : Vector2 = -direction.normalized() * turn_factor
velocity.x += turn.x
velocity.z += turn.y
return velocity
func apply_sphere_edge_avoidance(position : Vector3, velocity : Vector3, sphere : SphereShape3D) -> Vector3:
var direction : Vector3 = position
if direction.length() > sphere.radius - margin:
velocity = -direction.normalized() * turn_factor
return velocity
func apply_gravity(velocity : Vector3, delta : float) -> Vector3:
if use_gravity:
velocity += gravity_vector * gravity_factor * delta
return velocity
func apply_speed_limits(velocity : Vector3) -> Vector3:
# Boid's speed
var speed : float = velocity.length()
# Enforce max and min speed
if speed < min_speed:
velocity = (velocity / speed) * min_speed
if speed > max_speed:
velocity = (velocity / speed) * max_speed
return velocity
func random_pos() -> Vector3:
var x_range : Vector2 = Vector2(-spawn_volume.x / 2.0, spawn_volume.x / 2.0)
var y_range : Vector2 = Vector2(-spawn_volume.y / 2.0, spawn_volume.y / 2.0)
var z_range : Vector2 = Vector2(-spawn_volume.z / 2.0, spawn_volume.z / 2.0)
return Vector3(
randf_range(x_range.x, x_range.y),
randf_range(y_range.x, y_range.y),
randf_range(z_range.x, z_range.y)
)
func random_vel() -> Vector3:
var speed : float = pow(randf_range(min_speed, max_speed), 2)
var x : float = randf_range(0, speed)
speed -= x
var y : float = randf_range(0, speed)
speed -= y
var z : float = randf_range(0, speed)
return Vector3(sqrt(x), sqrt(y), sqrt(z))

47
scripts/CameraControl.gd Normal file
View File

@ -0,0 +1,47 @@
extends Node3D
@export var pan_factor : float = 0.1
@export var events_label : Label
@export var drag_label : Label
var events = {}
var last_drag_distance : float = 0
var min_zoom = 0
var max_zoom = 20
var zoom_sensitivity = 10
var zoom_speed = 0.5
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
events_label.text = "Touch events: {no}".format({"no": events.size()})
func _unhandled_input(event):
if event is InputEventScreenTouch:
if event.pressed:
events[event.index] = event
else:
events.erase(event.index)
if event is InputEventScreenDrag:
events[event.index] = event
if events.size() == 1:
var relative : Vector2 = event.relative * pan_factor
rotation_degrees.y += relative.x
$Tilt.rotation_degrees.x += relative.y
$Tilt.rotation_degrees.x = clamp($Tilt.rotation_degrees.x, -90, -5)
elif events.size() == 2:
var drag_distance = events[0].position.distance_to(events[1].position)
drag_label.text = "Drag distance: {dist}".format({"dist": drag_distance})
if abs(drag_distance - last_drag_distance) > zoom_sensitivity:
var new_zoom = zoom_speed if drag_distance < last_drag_distance else zoom_speed
new_zoom = clamp($Camera3D.position.z + new_zoom, min_zoom, max_zoom)
$Camera3D.position.z = new_zoom
last_drag_distance = drag_distance

View File

@ -0,0 +1,7 @@
shader_type spatial;
uniform float max_radius;
void fragment() {
// Place fragment code here.
}