This commit is contained in:
2026-02-10 06:09:33 +01:00
commit 2fa0d1da53
49 changed files with 1341 additions and 0 deletions

4
.editorconfig Normal file
View File

@@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

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

3
.gitignore vendored Normal file
View File

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

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://dbkywo0y7ikkn"
path="res://.godot/imported/Animal Crossing City Folk Music_ Town Hall Day.mp3-76ff970cdf4ea2158c465540e8f9f379.mp3str"
[deps]
source_file="res://Animal Crossing City Folk Music_ Town Hall Day.mp3"
dest_files=["res://.godot/imported/Animal Crossing City Folk Music_ Town Hall Day.mp3-76ff970cdf4ea2158c465540e8f9f379.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

BIN
Cow.fbx Normal file

Binary file not shown.

44
Cow.fbx.import Normal file
View File

@@ -0,0 +1,44 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cuqfqhof8keuv"
path="res://.godot/imported/Cow.fbx-c7edb1cd4e2bb11b200d7463329342d9.scn"
[deps]
source_file="res://Cow.fbx"
dest_files=["res://.godot/imported/Cow.fbx-c7edb1cd4e2bb11b200d7463329342d9.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=true
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
fbx/importer=0
fbx/allow_geometry_helper_nodes=false
fbx/embedded_image_handling=1
fbx/naming_version=2

BIN
CowGathering.fbx Normal file

Binary file not shown.

44
CowGathering.fbx.import Normal file
View File

@@ -0,0 +1,44 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bi833wheu4osu"
path="res://.godot/imported/CowGathering.fbx-cf0b87ecded15d6dc729bc467302182a.scn"
[deps]
source_file="res://CowGathering.fbx"
dest_files=["res://.godot/imported/CowGathering.fbx-cf0b87ecded15d6dc729bc467302182a.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=true
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
fbx/importer=0
fbx/allow_geometry_helper_nodes=false
fbx/embedded_image_handling=1
fbx/naming_version=2

BIN
Cow_D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

41
Cow_D.png.import Normal file
View File

@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c31fag3mikc5l"
path.s3tc="res://.godot/imported/Cow_D.png-2f0e0a4180571d004afd183cb882faf0.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://Cow_D.png"
dest_files=["res://.godot/imported/Cow_D.png-2f0e0a4180571d004afd183cb882faf0.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

110
Main.tscn Normal file

File diff suppressed because one or more lines are too long

104
Main.tscn201589096.tmp Normal file

File diff suppressed because one or more lines are too long

95
Main.tscn2526284158.tmp Normal file

File diff suppressed because one or more lines are too long

152
MusicVisualizor.gd Normal file
View File

@@ -0,0 +1,152 @@
extends Control
# === User-tweakable exports ===
@export var music_bus := "MusicBus"
@export var num_points := 128 # base samples taken from analyzer
@export var samples_per_segment := 3 # higher -> smoother interpolation
@export var line_width := 3.0
@export var line_color := Color(0.2, 0.8, 1.0)
@export var fill_color := Color(0.2, 0.8, 1.0, 0.18)
@export var base_amplitude_scale := 0.8 # baseline (fraction of Control height)
@export var auto_scale := true # automatically adjust scale to avoid clipping
@export var auto_target_fraction := 0.85 # fraction of half-height we want peak to occupy
@export var auto_max_multiplier := 3.0
@export var scale_smoothness := 0.08 # smoothing for auto scale changes
@export var value_smoothness := 0.18 # smoothing for spectrum magnitudes
@export var spectrum_gain := 5.0 # multiplier on analyzer magnitude
@export var baseline_smoothness := 0.05 # smoothing for baseline centering
# === Internal ===
@onready var analyzer = AudioServer.get_bus_effect_instance(
AudioServer.get_bus_index(music_bus), 0
)
var values: Array = []
var current_amplitude_scale: float = base_amplitude_scale
var baseline: float = 0.0
func _ready() -> void:
values.resize(num_points)
for i in range(num_points):
values[i] = 0.0
func _process(delta: float) -> void:
if not analyzer:
return
# --- sample spectrum and smooth values ---
for i in range(num_points):
var freq_low: float = lerp(20.0, 20000.0, float(i) / num_points)
var freq_high: float = lerp(20.0, 20000.0, float(i + 1) / num_points)
var mag_v: float = analyzer.get_magnitude_for_frequency_range(freq_low, freq_high).length() * spectrum_gain
values[i] = lerp(values[i], mag_v, value_smoothness)
# --- update auto scale (smoothed) ---
_update_auto_scale()
# --- update dynamic baseline for centering ---
_update_baseline()
queue_redraw()
func _update_auto_scale() -> void:
if not auto_scale:
current_amplitude_scale = lerp(current_amplitude_scale, base_amplitude_scale, scale_smoothness)
return
var peak: float = 0.0
for v in values:
if v > peak:
peak = v
var eps: float = 1e-6
var half_h: float = size.y * 0.5
var peak_pixels: float = peak * size.y * base_amplitude_scale
var target_pixels: float = half_h * auto_target_fraction
var required_mul: float = (target_pixels / (peak_pixels + eps))
required_mul = clamp(required_mul, 1.0 / auto_max_multiplier, auto_max_multiplier)
var new_scale: float = base_amplitude_scale * required_mul
current_amplitude_scale = lerp(current_amplitude_scale, new_scale, scale_smoothness)
func _update_baseline() -> void:
var avg_mag: float = 0.0
for v in values:
avg_mag += v
avg_mag /= num_points
baseline = lerp(baseline, avg_mag, baseline_smoothness)
# --- Catmull-Rom interpolation for smooth curves ---
func _catmull_rom_interpolate(raw_points: PackedVector2Array, samples_per_segment: int) -> PackedVector2Array:
var n: int = raw_points.size()
if n < 2:
return raw_points.duplicate()
var out := PackedVector2Array()
for i in range(n - 1):
var p0: Vector2 = raw_points[clamp(i - 1, 0, n - 1)]
var p1: Vector2 = raw_points[i]
var p2: Vector2 = raw_points[i + 1]
var p3: Vector2 = raw_points[clamp(i + 2, 0, n - 1)]
for s in range(samples_per_segment):
var t: float = float(s) / samples_per_segment
var t2: float = t * t
var t3: float = t2 * t
var x: float = 0.5 * ( (2.0 * p1.x) +
(-p0.x + p2.x) * t +
(2.0*p0.x - 5.0*p1.x + 4.0*p2.x - p3.x) * t2 +
(-p0.x + 3.0*p1.x - 3.0*p2.x + p3.x) * t3 )
var y: float = 0.5 * ( (2.0 * p1.y) +
(-p0.y + p2.y) * t +
(2.0*p0.y - 5.0*p1.y + 4.0*p2.y - p3.y) * t2 +
(-p0.y + 3.0*p1.y - 3.0*p2.y + p3.y) * t3 )
out.append(Vector2(x, y))
out.append(raw_points[n - 1])
return out
func _draw() -> void:
if values.is_empty():
return
var mid_y: float = size.y * 0.5
var step_x: float = size.x / float(num_points - 1)
# raw top points (before interpolation)
var raw := PackedVector2Array()
for i in range(num_points):
var x: float = i * step_x
var y: float = mid_y - (values[i] - baseline) * size.y * current_amplitude_scale
raw.append(Vector2(x, y))
# smooth the curve
var top_points: PackedVector2Array = _catmull_rom_interpolate(raw, samples_per_segment)
# mirrored bottom points (reverse order)
var bottom_points: PackedVector2Array = PackedVector2Array()
for i in range(top_points.size() - 1, -1, -1):
var p: Vector2 = top_points[i]
bottom_points.append(Vector2(p.x, 2.0 * mid_y - p.y))
# build filled polygon
var poly: PackedVector2Array = PackedVector2Array()
poly.append(Vector2(0, mid_y))
for p in top_points:
poly.append(p)
poly.append(Vector2(size.x, mid_y))
for p in bottom_points:
poly.append(p)
# draw filled area
draw_polygon(poly, [fill_color])
# draw top and bottom outlines
if top_points.size() >= 2:
draw_polyline(top_points, line_color, line_width, true)
draw_polyline(bottom_points, line_color, line_width, true)

1
MusicVisualizor.gd.uid Normal file
View File

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

52
Sky/sky_sphere_spinner.gd Normal file
View File

@@ -0,0 +1,52 @@
extends Node3D
@export var base_spin_speed := 0.05 # Slow ambient rotation
@export var beat_boost := 0.2 # How much faster it spins with bass
@export var smoothness := 0.05 # Controls smoothing of the beat signal
@export var music_bus := "MusicBus" # Audio bus with the SpectrumAnalyzer
@onready var analyzer = AudioServer.get_bus_effect_instance(
AudioServer.get_bus_index(music_bus), 0
)
# Reference to your mesh
@onready var mesh: MeshInstance3D = $Sketchfab_model/SphereTest_fbx/RootNode/pSphere1/pSphere1_lambert2_0
var smoothed_bass := 0.0
var mat: Material = null
func _ready() -> void:
if mesh:
# Duplicate the material so its safe to modify
var original_mat = mesh.get_active_material(0)
if original_mat:
mat = original_mat.duplicate()
mesh.set_surface_override_material(0, mat)
else:
push_warning("Mesh has no material!")
else:
push_error("Mesh path is incorrect!")
func _process(delta: float) -> void:
if not analyzer:
return
# Measure low frequencies for the "beat"
var bass = analyzer.get_magnitude_for_frequency_range(20, 200)
var bass_strength = bass.length() * 5.0
# Smooth out the data
smoothed_bass = lerp(smoothed_bass, bass_strength, smoothness)
# Determine final spin speed
var spin_speed = base_spin_speed + smoothed_bass * beat_boost
# Apply slow rotation around Y axis (typical for skyboxes)
rotation.y += spin_speed * delta
# Optionally, adjust shader/material color or parameter
if mat and mat is StandardMaterial3D:
var brightness = 0.6 + smoothed_bass * 0.3
mat.albedo_color = Color(brightness, brightness, brightness)
elif mat and mat is ShaderMaterial:
mat.set_shader_parameter("intensity", 1.0 + smoothed_bass * 0.5)

View File

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

BIN
Sky/sky_sphere_test.glb Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c58bpp6oc5ffy"
path="res://.godot/imported/sky_sphere_test.glb-a13f0a40180ef627fba27ab893bf5c48.scn"
[deps]
source_file="res://Sky/sky_sphere_test.glb"
dest_files=["res://.godot/imported/sky_sphere_test.glb-a13f0a40180ef627fba27ab893bf5c48.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

BIN
Sky/sky_sphere_test_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

View File

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cdaervqwdwon"
path.s3tc="res://.godot/imported/sky_sphere_test_0.png-d3f1a99dcb68be6ef5feb664efae02b8.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
generator_parameters={
"md5": "738f338442a0cab90196205043e2038b"
}
[deps]
source_file="res://Sky/sky_sphere_test_0.png"
dest_files=["res://.godot/imported/sky_sphere_test_0.png-d3f1a99dcb68be6ef5feb664efae02b8.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

5
base_hat.tscn Normal file
View File

@@ -0,0 +1,5 @@
[gd_scene format=3 uid="uid://dsmlk07yei0ac"]
[node name="BaseHat" type="Node3D"]
[node name="OffsetNode" type="Marker3D" parent="."]

29
cow.gd Normal file
View File

@@ -0,0 +1,29 @@
extends Node3D
@export var base_spin_speed := 0.5 # Constant slow spin speed
@export var beat_boost := 2.0 # How much faster it spins on the beat
@export var smoothness := 0.1 # Lower = smoother response
@export var music_bus := "MusicBus" # Bus name where analyzer is added
@onready var analyzer = AudioServer.get_bus_effect_instance(
AudioServer.get_bus_index(music_bus), 0
)
var smoothed_bass := 0.0
func _process(delta: float) -> void:
if not analyzer:
return
# Analyze low frequencies (20200Hz) for beat detection
var bass = analyzer.get_magnitude_for_frequency_range(20, 200)
var bass_strength = bass.length() * 10.0
# Smooth the value to avoid jitter
smoothed_bass = lerp(smoothed_bass, bass_strength, smoothness)
# Spin speed: base + a small boost from the beat
var spin_speed = base_spin_speed + smoothed_bass * beat_boost
# Apply rotation (e.g. around Y-axis)
rotation.y += spin_speed * delta

1
cow.gd.uid Normal file
View File

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

20
default_bus_layout.tres Normal file
View File

@@ -0,0 +1,20 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://cx2levligq17l"]
[sub_resource type="AudioEffectSpectrumAnalyzer" id="AudioEffectSpectrumAnalyzer_j3pel"]
resource_name = "SpectrumAnalyzer"
[resource]
bus/1/name = &"MusicBus"
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_j3pel")
bus/1/effect/0/enabled = true
bus/2/name = &"New Bus"
bus/2/solo = false
bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = &"Master"

71
export_presets.cfg Normal file
View File

@@ -0,0 +1,71 @@
[preset.0]
name="Windows"
platform="Windows Desktop"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../music-spinner.exe"
patches=PackedStringArray()
patch_delta_encoding=false
patch_delta_compression_level_zstd=19
patch_delta_min_reduction=0.1
patch_delta_include_filters="*"
patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
shader_baker/enabled=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
application/export_d3d12=0
application/d3d12_agility_sdk_multiarch=true
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
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}'"

59
hat_cycler.gd Normal file
View File

@@ -0,0 +1,59 @@
extends Marker3D
@onready var hat_anchor = self
var current_hat: Node3D
var hat_index := 0
var hat_scenes: Array[PackedScene] = []
@export var hats_folder := "res://hat_scenes/"
@export var cycle_interval := 3.0
func _ready():
load_hat_scenes(hats_folder)
if hat_scenes.size() > 0:
equip_hat(hat_scenes[hat_index])
start_cycling()
else:
push_warning("No hat scenes found in: " + hats_folder)
func load_hat_scenes(path: String):
var dir := DirAccess.open(path)
if dir == null:
push_error("Could not open hat folder: " + path)
return
dir.list_dir_begin()
while true:
var file_name = dir.get_next()
if file_name == "":
break
if dir.current_is_dir():
continue
if file_name.ends_with(".tscn"):
var scene_path = path.path_join(file_name)
var hat_scene = load(scene_path)
if hat_scene is PackedScene:
hat_scenes.append(hat_scene)
dir.list_dir_end()
hat_scenes.sort_custom(func(a, b): return a.resource_path < b.resource_path)
func start_cycling():
var timer = Timer.new()
timer.wait_time = cycle_interval
timer.autostart = true
timer.one_shot = false
timer.timeout.connect(_on_cycle_timeout)
add_child(timer)
func _on_cycle_timeout():
if hat_scenes.size() == 0:
return
hat_index = (hat_index + 1) % hat_scenes.size()
equip_hat(hat_scenes[hat_index])
func equip_hat(scene: PackedScene):
if current_hat:
current_hat.queue_free()
var hat = scene.instantiate()
hat_anchor.add_child(hat)
current_hat = hat

1
hat_cycler.gd.uid Normal file
View File

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

BIN
hat_models/Baseball cap.glb Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c5inh1g30fakl"
path="res://.godot/imported/Baseball cap.glb-a684f6325efc0c6e3b05c61fa99270bf.scn"
[deps]
source_file="res://hat_models/Baseball cap.glb"
dest_files=["res://.godot/imported/Baseball cap.glb-a684f6325efc0c6e3b05c61fa99270bf.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

BIN
hat_models/Cowboy Hat.glb Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://drf7v2ka523kj"
path="res://.godot/imported/Cowboy Hat.glb-c3a50a87412f84c0559cf6a1d5f73250.scn"
[deps]
source_file="res://hat_models/Cowboy Hat.glb"
dest_files=["res://.godot/imported/Cowboy Hat.glb-c3a50a87412f84c0559cf6a1d5f73250.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

BIN
hat_models/Fox Hat.glb Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dyyt8ss20bmf8"
path="res://.godot/imported/Fox Hat.glb-a04cd599ce7b3442c466b217e3e7abbb.scn"
[deps]
source_file="res://hat_models/Fox Hat.glb"
dest_files=["res://.godot/imported/Fox Hat.glb-a04cd599ce7b3442c466b217e3e7abbb.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

BIN
hat_models/Santa Hat.glb Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c06eg0b3f8a6o"
path="res://.godot/imported/Santa Hat.glb-29e28beddc7dfca34b88b496cdeb4aa4.scn"
[deps]
source_file="res://hat_models/Santa Hat.glb"
dest_files=["res://.godot/imported/Santa Hat.glb-29e28beddc7dfca34b88b496cdeb4aa4.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

BIN
hat_models/Top hat.glb Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dloabnqy24a2f"
path="res://.godot/imported/Top hat.glb-6c35e38e93d6a585fdf4b8d4f808898d.scn"
[deps]
source_file="res://hat_models/Top hat.glb"
dest_files=["res://.godot/imported/Top hat.glb-6c35e38e93d6a585fdf4b8d4f808898d.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

BIN
hat_models/Witch Hat.glb Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c840id57xeg0u"
path="res://.godot/imported/Witch Hat.glb-4ceab11a487c5de89ccd7aa5289eb464.scn"
[deps]
source_file="res://hat_models/Witch Hat.glb"
dest_files=["res://.godot/imported/Witch Hat.glb-4ceab11a487c5de89ccd7aa5289eb464.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

View File

@@ -0,0 +1,11 @@
[gd_scene load_steps=3 format=3 uid="uid://meimhcbpg0js"]
[ext_resource type="PackedScene" uid="uid://dsmlk07yei0ac" path="res://base_hat.tscn" id="1_c7ka6"]
[ext_resource type="PackedScene" uid="uid://drf7v2ka523kj" path="res://hat_models/Cowboy Hat.glb" id="2_ila6p"]
[node name="BaseHat" instance=ExtResource("1_c7ka6")]
[node name="OffsetNode" parent="." index="0"]
transform = Transform3D(0.605215, 0, 0, 0, 0.605215, 0, 0, 0, 0.605215, 0, -0.125406, 0)
[node name="Cowboy Hat" parent="OffsetNode" index="0" instance=ExtResource("2_ila6p")]

1
icon.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><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 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 995 B

43
icon.svg.import Normal file
View File

@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cx3e25i8ovcxx"
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/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

21
main.gd Normal file
View File

@@ -0,0 +1,21 @@
extends Node
@onready var audio_player: AudioStreamPlayer = $AudioStreamPlayer
var is_fullscreen = false
var is_muted = false
func _input(event):
if event is InputEventKey and event.pressed:
# Toggle fullscreen with F
if event.keycode == KEY_F:
is_fullscreen = !is_fullscreen
if is_fullscreen:
DisplayServer.window_set_mode(DisplayServer.WindowMode.WINDOW_MODE_FULLSCREEN)
else:
DisplayServer.window_set_mode(DisplayServer.WindowMode.WINDOW_MODE_WINDOWED)
# Toggle mute with M
elif event.keycode == KEY_M:
is_muted = !is_muted
audio_player.stream_paused = is_muted

1
main.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://8j47gjkxfl5a

27
project.godot Normal file
View File

@@ -0,0 +1,27 @@
; 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
[animation]
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
[application]
config/name="music-spinner"
run/main_scene="uid://xuxudk7073fo"
config/features=PackedStringArray("4.6", "Forward Plus")
boot_splash/show_image=false
boot_splash/stretch_mode=0
boot_splash/use_filter=false
config/icon="res://icon.svg"
[rendering]
renderer/rendering_method="mobile"

BIN
sky_34_2k.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 KiB

41
sky_34_2k.png.import Normal file
View File

@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dy60diov2gwlv"
path.s3tc="res://.godot/imported/sky_34_2k.png-1476235f155bc8886eda2914206697e4.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://sky_34_2k.png"
dest_files=["res://.godot/imported/sky_34_2k.png-1476235f155bc8886eda2914206697e4.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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