Commit before damnger

This commit is contained in:
kevadesu 2025-06-07 19:10:56 +02:00
parent fe1eb58626
commit 14f0200b50
101 changed files with 8087 additions and 15 deletions

View file

@ -0,0 +1,116 @@
[gd_scene load_steps=5 format=3 uid="uid://cpp7g0af4m0ed"]
[ext_resource type="Script" path="res://AudioMixerVisualizer/AudioMixerDebugVisualization.gd" id="1"]
[ext_resource type="Script" path="res://AudioMixerVisualizer/AudioMixerMeterDrawer.gd" id="2"]
[ext_resource type="Script" path="res://AudioMixerVisualizer/AudioMixerVolumeDrawer.gd" id="3"]
[ext_resource type="FontFile" uid="uid://yewopnpud14o" path="res://AudioMixerVisualizer/AudioMixerDebugFont.tres" id="4"]
[node name="AudioDebugVisualizer" type="CanvasLayer"]
process_mode = 3
layer = 128
[node name="Mixer" type="Control" parent="."]
custom_minimum_size = Vector2(2.08165e-12, 100)
layout_mode = 3
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -500.0
offset_top = -140.0
offset_right = 500.0
offset_bottom = -10.0
grow_horizontal = 2
grow_vertical = 0
mouse_filter = 2
script = ExtResource("1")
font_fx = ExtResource("4")
[node name="Container" type="HBoxContainer" parent="Mixer"]
layout_mode = 0
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
mouse_filter = 2
alignment = 1
[node name="Bus" type="PanelContainer" parent="Mixer/Container"]
custom_minimum_size = Vector2(60, 0)
layout_mode = 2
size_flags_vertical = 3
mouse_filter = 2
[node name="VBox" type="VBoxContainer" parent="Mixer/Container/Bus"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
mouse_filter = 2
alignment = 1
[node name="label_name" type="Label" parent="Mixer/Container/Bus/VBox"]
layout_mode = 2
text = "Bus"
horizontal_alignment = 1
vertical_alignment = 1
clip_text = true
[node name="label_peak" type="Label" parent="Mixer/Container/Bus/VBox"]
modulate = Color(0.521569, 0.521569, 0.521569, 1)
layout_mode = 2
text = "-0.1"
horizontal_alignment = 1
vertical_alignment = 1
[node name="HBox" type="HBoxContainer" parent="Mixer/Container/Bus/VBox"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
mouse_filter = 2
[node name="Meter" type="Panel" parent="Mixer/Container/Bus/VBox/HBox"]
custom_minimum_size = Vector2(20, 0)
layout_mode = 2
mouse_filter = 2
script = ExtResource("2")
[node name="HBox" type="HBoxContainer" parent="Mixer/Container/Bus/VBox/HBox/Meter"]
clip_contents = true
layout_mode = 0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 1.0
offset_top = 1.0
offset_right = -1.0
offset_bottom = -1.0
size_flags_horizontal = 3
size_flags_vertical = 3
mouse_filter = 2
[node name="fill_left" type="ColorRect" parent="Mixer/Container/Bus/VBox/HBox/Meter/HBox"]
modulate = Color(0.0784314, 0.737255, 0.309804, 1)
layout_mode = 2
size_flags_horizontal = 3
mouse_filter = 2
[node name="fill_right" type="ColorRect" parent="Mixer/Container/Bus/VBox/HBox/Meter/HBox"]
modulate = Color(0.0784314, 0.737255, 0.309804, 1)
layout_mode = 2
size_flags_horizontal = 3
mouse_filter = 2
[node name="Volume" type="Panel" parent="Mixer/Container/Bus/VBox/HBox"]
custom_minimum_size = Vector2(5, 0)
layout_mode = 2
size_flags_vertical = 3
mouse_filter = 2
script = ExtResource("3")
[node name="VBox_fx" type="VBoxContainer" parent="Mixer/Container/Bus/VBox/HBox"]
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[connection signal="mouse_entered" from="Mixer" to="Mixer" method="_on_mouse_entered"]
[connection signal="mouse_exited" from="Mixer" to="Mixer" method="_on_mouse_exited"]

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,162 @@
extends Control
@export var font_fx : FontFile
class bus:
var index
var ui : Control
var max_peak : float
var fx : Array
var timer
func _init(bus_index, _ui, _fx):
timer = 0
max_peak = -200
self.index = bus_index
self.ui = _ui
self.fx = _fx
func update(delta, peak):
if peak > max_peak:
max_peak = peak
timer = 0
timer += delta
if timer > 3:
max_peak = peak
@onready var container = $Container
@onready var bus_template = $Container/Bus
var buses : Array
func _ready():
# Add bus panels
for i in AudioServer.bus_count:
var bus_panel = bus_template.duplicate()
container.add_child(bus_panel)
var label : Label = bus_panel.get_node("VBox/label_name")
label.text = AudioServer.get_bus_name(i)
# Add effect labels
var vbox = bus_panel.get_node("VBox/HBox/VBox_fx")
var fx = Array()
for n in AudioServer.get_bus_effect_count(i):
var effect : AudioEffect = AudioServer.get_bus_effect(i, n)
fx.append(effect)
var fx_label = Label.new()
fx_label.text = effect.resource_name
fx_label.add_theme_font_override("font", font_fx)
vbox.add_child(fx_label)
vbox.visible = true
vbox.set_anchors_preset(Control.PRESET_TOP_LEFT)
vbox.pivot_offset = Vector2(0, 300)
var b = bus.new(i, bus_panel, fx)
bus_panel.get_node("VBox/HBox/Meter").assign_bus(b)
bus_panel.get_node("VBox/HBox/Volume").assign_bus(b)
buses.append(b)
bus_template.queue_free()
func _process(delta):
var mouse_pos = get_viewport().get_mouse_position()
if mouse_pos.y > get_viewport_rect().size.y - 150:
_hide()
else:
_show()
# Update bus panels
for b in buses:
var peak_l = AudioServer.get_bus_peak_volume_left_db(b.index, 0)
var peak_r = AudioServer.get_bus_peak_volume_right_db(b.index, 0)
var peak_max = max(peak_l, peak_r)
b.update(delta, peak_max)
# Mute/Solo
var label_name : Label = b.ui.get_node("VBox/label_name")
label_name.modulate = Color.WHITE
if AudioServer.is_bus_mute(b.index):
label_name.modulate = Color.CRIMSON
if AudioServer.is_bus_solo(b.index):
label_name.modulate = Color.YELLOW
# Meter fill
var fill : ColorRect = b.ui.get_node("VBox/HBox/Meter/HBox/fill_left")
fill.anchor_top = 1.0 - normalize_peak(peak_l)
fill = b.ui.get_node("VBox/HBox/Meter/HBox/fill_right")
fill.anchor_top = 1.0 - normalize_peak(peak_r)
# Peak label
var label_peak : Label = b.ui.get_node("VBox/label_peak")
var peak_text = ""
if b.max_peak > -200:
peak_text = str(ceil(b.max_peak * 10) / 10.0)
if b.max_peak > 0:
peak_text = "+" + peak_text
label_peak.text = peak_text
# Peak label color
if b.max_peak > 0.0:
label_peak.modulate = Color.CRIMSON
else:
label_peak.modulate = Color(1.0, 1.0, 1.0, 0.5)
update_fx_labels()
func update_fx_labels():
for b in buses:
var fx_vbox = b.ui.get_node("VBox/HBox/VBox_fx")
for i in b.fx.size():
var label = fx_vbox.get_child(i)
if AudioServer.is_bus_effect_enabled(b.index, i):
label.modulate = Color.WHITE
else:
label.modulate = Color.DIM_GRAY
var fx = b.fx[i]
var s = fx.resource_name
# Name
if fx.get_class() == "AudioEffectLowPassFilter":
s = "LPF"
if fx.get_class() == "AudioEffectBandPassFilter":
s = "BPF"
if fx.get_class() == "AudioEffectReverb":
s = "Verb"
if fx.get_class() == "AudioEffectAmplify":
s = "Amp"
if fx.get_class() == "AudioEffectCompressor":
s = "Comp"
if fx.get_class() == "AudioEffectLimiter":
s = "Lim"
if fx.get_class() == "AudioEffectStereoEnhance":
s = "StEnh"
# Settings
if "volume_db" in fx:
s = s + ", vol " + str(snapped(fx.volume_db, 0.01))
if "resonance" in fx:
s = s + ", res " + str(snapped(fx.resonance, 0.01))
if "cutoff_hz" in fx:
s = s + ", hz " + str(snapped(fx.cutoff_hz, 0.01))
if "room_size" in fx:
s = s + ", size " + str(snapped(fx.room_size, 0.01))
if "wet" in fx:
s = s + ", wet " + str(snapped(fx.wet, 0.01))
label.text = s
# Takes a peak in db, and spits out a normalized 0 to 1 value
func normalize_peak(peak_db):
var p = (peak_db + 200) / 200.0
return p * p * p * p * p * p
func _hide():
modulate = Color(1.0, 1.0, 1.0, 0.25)
func _show():
modulate = Color(1.0, 1.0, 1.0, 0.8)

View file

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

View file

@ -0,0 +1,35 @@
extends Control
var bus
func assign_bus(_bus):
self.bus = _bus
func _process(_delta):
queue_redraw()
func _draw():
if bus == null:
return
var meter_ui = bus.ui.get_node("VBox/HBox/Meter/HBox")
var pos = meter_ui.global_position - global_position
var _size = meter_ui.size
# Draw db-markings
var db_mark_color = Color(1.0, 1.0, 1.0, 0.03)
for i in 12:
draw_db_mark(pos, _size, i * -6, db_mark_color)
# Draw max-peak line
draw_db_mark(pos, _size, bus.max_peak, Color(0.1, 0.8, 0.1, normalize_peak(bus.max_peak)))
func draw_db_mark(pos, _size, db, color):
var db_norm = 1 - normalize_peak(db)
var y_offset = Vector2(0, db_norm * _size.y)
draw_line(pos + y_offset, pos + y_offset + Vector2(_size.x, 0), color)
# Takes a peak in db, and spits out a normalized 0 to 1 value
func normalize_peak(peak_db):
var p = (peak_db + 200) / 200.0
return p * p * p * p * p * p

View file

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

View file

@ -0,0 +1,27 @@
extends Control
var bus
func assign_bus(_bus):
self.bus = _bus
func process(_delta):
queue_redraw()
func _draw():
if bus == null:
return
var pos = Vector2(-1, 0)
var _size = Vector2(size.x + 2, size.y)
draw_volume_mark(pos, _size, AudioServer.get_bus_volume_db(bus.index), Color(1.0, 1.0, 1.0, 0.5))
func draw_volume_mark(pos, _size, db, color):
var db_norm = 1 - normalize_peak(db)
var y_offset = Vector2(0, db_norm * (_size.y - 10) + 10)
draw_line(pos + y_offset, pos + y_offset + Vector2(_size.x, 0), color, 2.0)
# Takes a peak in db, and spits out a normalized 0 to 1 value
func normalize_peak(peak_db):
var p = (peak_db + 200) / 200.0
return p * p * p * p * p * p

View file

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

Binary file not shown.

View file

@ -0,0 +1,35 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://djsydx7kqwa0k"
path="res://.godot/imported/BarlowCondensed-Regular.ttf-973b5bd97605c53120c8d42add219b73.fontdata"
[deps]
source_file="res://AudioMixerVisualizer/BarlowCondensed-Regular.ttf"
dest_files=["res://.godot/imported/BarlowCondensed-Regular.ttf-973b5bd97605c53120c8d42add219b73.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

13
Demo/example.tscn Normal file
View file

@ -0,0 +1,13 @@
[gd_scene load_steps=3 format=3 uid="uid://cacmio2fg7klb"]
[ext_resource type="PackedScene" uid="uid://cpp7g0af4m0ed" path="res://AudioMixerVisualizer/AudioDebugVisualizer.tscn" id="1"]
[ext_resource type="AudioStream" uid="uid://bvpyheijtxjes" path="res://Demo/example.wav" id="2"]
[node name="Node3D" type="Node3D"]
[node name="AudioDebugVisualizer" parent="." instance=ExtResource("1")]
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource("2")
autoplay = true
bus = &"Example Bus"

BIN
Demo/example.wav Normal file

Binary file not shown.

24
Demo/example.wav.import Normal file
View file

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://bvpyheijtxjes"
path="res://.godot/imported/example.wav-0a036c25aae6ac44b63679fdbaee4561.sample"
[deps]
source_file="res://Demo/example.wav"
dest_files=["res://.godot/imported/example.wav-0a036c25aae6ac44b63679fdbaee4561.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=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=0

0
Screenshots/.gdignore Normal file
View file

BIN
Screenshots/Screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

21
addons/vizpath/LICENSE Normal file
View file

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

90
addons/vizpath/README.md Normal file
View file

@ -0,0 +1,90 @@
# Visualized Path plugin
A plugin for Godot 4 to visualize a path
## Overview
This plugin is designed to create a 3D mesh to visualize a path. It generates that mesh using
an array of spots, where each spot has a normal defining the mesh face at that spot.
The path created will be directly between each spot and in the order specified. The direction
between the spots is direct but the path can be bent based on the normals at each spot.
An optional tail and head can be placed at the beginning and ending of the path, to provide a
decoration.
## Installation
The plugin is written in 100% GDScript so no compilation is required and should work on any
platform.
To install it from the Godot Asset Library, within your project:
- Select the AssetLib tab
- Search for "3D Visualized Path"
- Click Download button
- After the dialog is presented with files, at least include the "addons" directory
- From Project -> Project Settings...
- Go to Plugins tab and enable vizpath plugin (not doing this will not let the path be selectable
in the 3D view and will not present the spot control points
There are 3 main directories
- addons/vizpath
- examples/vizpath
- source/vizpath
When loading as an asset in another project (as opposed to working on this asset) the following files
should NOT be imported, they will likely conflict with your project
- README.md
- LICENSE
- icon.svg
- icon.svg.import
- project.godot
After using this asset, the examples/vizpath and source/vizpath folders can be removed so as not
to pollute your project.
## Usage
The typical use of this asset is to create the path from an array of VisualizationSpot resources
in response to user input or actions by the AI during game play. The plugin does support manually
creating a path in the editor and editing in the 3D view.
### Programatically through a script
To change the path, simply construct an array of VisualizationSpot objects (which define the
point in local space to the VisualizedPath and the normal in local space). There are changed signals
that detect the resource being updated and the path will be reconstructed.
#### Handling errors
If the path cannot be constructed (because the spots are too close to create a bend with the curve
specified), the underlying mesh will not be created and the error list will be updated. To retrieve
these errors a call to get_errors() can be made.
Based on the properties and how close the spots are allowed to be, you can guarantee that the path will
always be constructed. If you allow unrestrained movement of the spots and the normals, you will
need to report the error (which is what is done when using the Godot Editor)
### Directly in the editor
The VisualizedPath class will appear in the list of nodes when adding a node to a scene. The VisualizedPath
class supports editing all the properties through the Inspector and updating
the view immediately. It also allows a VisualizationSpot to be moved and its normal rotated using
a subgizmo. At least 2 spots must be added. If the path is not valid, a warning will be presented
on the VisualizedPath instance.
### Using subgizmo
To use the subgizmo, click on the VisualizedPath and in the 3D view click on the yellow cone for
one of the spots. The manipulation gizmo changes to that spot and then it can be moved (changing
the position of the spot), or rotated (changing the normal at that spot)
## Examples
Examples of using the plugin can be found in the "example/vizpath" directory. Feel free to
delete this directory for your project.
## Source
Blender and Inkscape files used to create the meshes and the icon are included in the "source/vizpath"
directory, which can also be removed without impacting its usage.

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d0ljaahn5bykd"
path="res://.godot/imported/path.png-9af8c406cc1948c301cd69299f1231f1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/vizpath/images/path.png"
dest_files=["res://.godot/imported/path.png-9af8c406cc1948c301cd69299f1231f1.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

View file

@ -0,0 +1,12 @@
# Blender 3.5.0 MTL File: 'spot.blend'
# www.blender.org
newmtl Material
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2

View file

@ -0,0 +1,66 @@
# Blender 3.5.0
# www.blender.org
mtllib spot.mtl
o Cube
v 0.250000 -0.250000 -0.056205
v 0.250000 -0.250000 -0.000000
v 0.250000 0.250000 -0.056205
v 0.250000 0.250000 0.000000
v -0.250000 -0.250000 -0.056205
v -0.250000 -0.250000 -0.000000
v -0.250000 0.250000 -0.056205
v -0.250000 0.250000 0.000000
v 0.095182 -0.095182 -0.071294
v 0.095182 0.095182 -0.071294
v -0.095182 -0.095182 -0.071294
v -0.095182 0.095182 -0.071294
v 0.000000 0.000000 -0.500000
vn -0.0970 -0.0000 -0.9953
vn -0.0000 1.0000 -0.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn -0.9762 -0.0000 -0.2167
vn 0.0970 -0.0000 -0.9953
vn -0.0000 -0.0970 -0.9953
vn -0.0000 0.0970 -0.9953
vn -0.0000 0.9762 -0.2167
vn -0.0000 -0.9762 -0.2167
vn 0.9762 -0.0000 -0.2167
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.250000
vt 0.625000 0.000000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.125000 0.750000
vt 0.625000 0.500000
vt 0.625000 0.750000
vt 0.625000 0.250000
vt 0.625000 0.000000
vt 0.625000 1.000000
vt 0.625000 0.250000
vt 0.625000 1.000000
vt 0.625000 0.500000
vt 0.625000 0.750000
s 0
usemtl Material
f 5/5/1 7/8/1 12/16/1 11/15/1
f 4/4/2 3/3/2 7/9/2 8/10/2
f 8/11/3 7/8/3 5/5/3 6/7/3
f 6/6/4 2/2/4 4/4/4 8/12/4
f 2/2/5 1/1/5 3/3/5 4/4/5
f 6/7/6 5/5/6 1/1/6 2/2/6
f 11/15/7 12/16/7 13/18/7
f 3/3/8 1/1/8 9/13/8 10/14/8
f 1/1/9 5/5/9 11/15/9 9/13/9
f 7/9/10 3/3/10 10/14/10 12/17/10
f 12/17/11 10/14/11 13/19/11
f 9/13/12 11/15/12 13/20/12
f 10/14/13 9/13/13 13/21/13

View file

@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://b2tsm0h3jdgvy"
path="res://.godot/imported/spot.obj-f00a82a9756945bf04ad3b38eae5a1b4.mesh"
[deps]
files=["res://.godot/imported/spot.obj-f00a82a9756945bf04ad3b38eae5a1b4.mesh"]
source_file="res://addons/vizpath/mesh/spot.obj"
dest_files=["res://.godot/imported/spot.obj-f00a82a9756945bf04ad3b38eae5a1b4.mesh", "res://.godot/imported/spot.obj-f00a82a9756945bf04ad3b38eae5a1b4.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false

View file

@ -0,0 +1,7 @@
[plugin]
name="vizpath"
description=""
author="markeel"
version="1.0.2"
script="vizpath.gd"

View file

@ -0,0 +1,36 @@
@tool
extends Resource
class_name VisualizationSpot
## The VisualizationSpot class is a resource that allows the definition
## of a spot for a VisualizedPath.
##
## A VisualizationSpot contains a point (local space) and a normal (local space)
## that identifies where the path starts, ends, or turns.
## The point in local space where the path originates, terminates, or turns
@export var point : Vector3 :
set(p):
point = p
emit_changed()
## The normal defining the up direction of the plane this path will be in at this
## point.
@export var normal : Vector3 :
set(n):
normal = n
emit_changed()
func _init():
point = Vector3.ZERO
normal = Vector3.FORWARD
func is_equal(other):
if not point.is_equal_approx(other.point):
return false
if not normal.is_equal_approx(other.normal):
return false
return true
func _to_string():
return "%s/%s" % [point, normal]

View file

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

View file

@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="VisualizationSpot" load_steps=2 format=3 uid="uid://xujlcvwtxkk8"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="1_yfhm3"]
[resource]
script = ExtResource("1_yfhm3")
point = Vector3(0, 0, 0)
normal = Vector3(0, 0, -1)

View file

@ -0,0 +1,87 @@
@tool
extends Resource
class_name VizHead
# The VizHead class is a resource that allows the creation
# of a simple arrow head at the end of the path showing the
# final destination of the path.
#
# It is designed to be used interchangeably with any resource
# that defines an apply method with the signature defined
# below.
## The width of the arrow head as a percentage of the
## path width it is associated with.
@export var width_factor : float = 2.0 :
set(w):
width_factor = w
emit_changed()
## The length of the arrow head as a percentage of the
## path width it is associated with
@export var length_factor : float = 1.20 :
set(l):
length_factor = l
emit_changed()
## The get_offset function will be called to shift the end of the last
## segment to accomodate the head mesh
##
## This class can be overridden to provide a custom head to the path
## by defining a resource that has an apply method with the following
## definition:
##
## The [code]left[/code] and [code]right[/code] positions at the end of the path, where the
## V texture coordinate is 0.0 for [code]left[/code] and 1.0 for [code]right[/code].
## The [code]normal[/code] and the [code]direction[/code] define the position of the face and the
## direction that the path is going.
func get_offset(left : Vector3, right : Vector3, normal : Vector3, direction : Vector3) -> float:
var segment := right - left
var segment_len := segment.length()
var arrow_point_len := segment_len * length_factor
return arrow_point_len
## The apply function will be called when the path
## mesh is created.
##
## This class can be overridden to provide a custom head to the path
## by defining a resource that has an apply method with the following
## definition:
##
## The [code]mesh_node[/code] parameter is the mesh instance of the visualized path.
## Its interior mesh can be updated (typically with [SurfaceTool]).
## The [code]u[/code] parameter is the U texture coordinate of the [code]left[/code] and
## [code]right[/code] positions at the end of the path, where the V texture coordinate
## is 0.0 for [code]left[/code] and 1.0 for [code]right[/code]. The [code]normal[/code] and
## the [code]direction[/code] define the position of the face and the direction that the
## path is going. The [code]path_mat[/code] is the material that was used
## in the original path definition [member VisualizedPath.path_mat].
func apply(mesh_node : MeshInstance3D, u : float, left : Vector3, right : Vector3, normal : Vector3, direction : Vector3, path_mat : Material):
var segment := right - left
var mid_segment := segment / 2.0
var binormal := direction.cross(normal).normalized()
var segment_len := segment.length()
var arrow_base_len := segment_len * width_factor
var extent_len := (arrow_base_len - segment_len)/2.0
var arrow_left_extent := left - extent_len * binormal
var arrow_right_extent := right + extent_len * binormal
var arrow_point_len := segment_len * length_factor
var arrow_fwd_extent := left + mid_segment + arrow_point_len * direction
var v_extent = width_factor * 0.5
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_color(Color(1, 0, 0))
st.set_normal(normal)
st.set_material(path_mat)
st.set_uv(Vector2(u, 0.5 + v_extent))
st.add_vertex(arrow_right_extent)
st.set_uv(Vector2(u, 0.5 - v_extent))
st.add_vertex(arrow_left_extent)
st.set_uv(Vector2(u+arrow_point_len, 0.5))
st.add_vertex(arrow_fwd_extent)
mesh_node.mesh = st.commit(mesh_node.mesh)

View file

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

View file

@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="VizHead" load_steps=2 format=3 uid="uid://ca6a3fjxcmbhc"]
[ext_resource type="Script" path="res://addons/vizpath/resources/viz_head.gd" id="1_7yqvb"]
[resource]
script = ExtResource("1_7yqvb")
width_factor = 2.0
length_factor = 1.2

View file

@ -0,0 +1,80 @@
@tool
extends Resource
class_name VizTail
# The VizTail class is a resource that allows the creation
# of a simple rounded tail at the beginning of the path showing the
# start of the path.
#
# It is designed to be used interchangeably with any resource
# that defines an apply method with the signature defined
# below.
## The number of segments in the semi-sphere of tail
@export var num_segs := 16 :
set(s):
num_segs = s
emit_changed()
## The get_offset function will be called to shift the beginning of the first
## segment to accomodate the tail mesh
##
## This class can be overridden to provide a custom head to the path
## by defining a resource that has an apply method with the following
## definition:
##
## The [code]left[/code] and [code]right[/code] positions at the start of the path, where the
## V texture coordinate is 0.0 for [code]left[/code] and 1.0 for [code]right[/code].
## The [code]normal[/code] and the [code]direction[/code] define the position of the face and the
## direction that the path is going.
func get_offset(left : Vector3, right : Vector3, normal : Vector3, direction : Vector3) -> float:
return 0.0
## The apply function will be called when the path
## mesh is created.
##
## This class can be overridden to provide a custom tail to the path
## by defining a resource that has an apply method with the following
## definition:
##
## The [code]mesh_node[/code] parameter is the mesh instance of the visualized path.
## Its interior mesh can be updated (typically with [SurfaceTool]).
## The [code]u[/code] parameter is the U texture coordinate of the [code]left[/code] and
## [code]right[/code] positions at the end of the path, where the V texture coordinate
## is 0.0 for [code]left[/code] and 1.0 for [code]right[/code]. The [code]normal[/code] and
## the [code]direction[/code] define the position of the face and the direction that the
## path is going. The [code]path_mat[/code] is the material that was used
## in the original path definition [member VisualizedPath.path_mat].
func apply(mesh_node : MeshInstance3D, u : float, left : Vector3, right : Vector3, normal : Vector3, direction : Vector3, path_mat : Material):
var segment := right - left
var mid_segment := segment / 2.0
var mid_point := left + mid_segment
var binormal := direction.cross(normal).normalized()
var segment_len := segment.length()
var mid_segment_len := mid_segment.length()
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_color(Color(1, 0, 0))
st.set_normal(normal)
var rotation_dir := -signf(direction.dot(mid_segment.rotated(normal, PI/2.0)))
var last_pos := right
var last_pu := u
var last_pv := 1.0
for i in range(num_segs):
var weight := rotation_dir * float(i+1) / float(num_segs)
var angle := weight * PI
var pv := (1.0 + cos(angle))/2.0
var pu := u - rotation_dir * mid_segment_len * sin(angle)
var pos := mid_point + mid_segment.rotated(normal, angle)
st.set_uv(Vector2(u, 0.5))
st.add_vertex(mid_point)
st.set_uv(Vector2(last_pu, last_pv))
st.add_vertex(last_pos)
st.set_uv(Vector2(pu, pv))
st.add_vertex(pos)
last_pos = pos
last_pu = pu
last_pv = pv
st.set_material(path_mat)
mesh_node.mesh = st.commit(mesh_node.mesh)

View file

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

View file

@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="VizTail" load_steps=2 format=3 uid="uid://dnaxoh1d4t82c"]
[ext_resource type="Script" path="res://addons/vizpath/resources/viz_tail.gd" id="1_npnpb"]
[resource]
script = ExtResource("1_npnpb")
num_segs = 12

View file

@ -0,0 +1,202 @@
extends RefCounted
class_name VizBend
var _error : String
var _bend_normal : Vector3
var _bend_plane : Plane
var _begin_on_bend_plane : Vector3
var _end_on_bend_plane : Vector3
var _intersect_data : OptVector3
var _plane_join_point : Vector3
var _bend_side : float
var _curve_side : float
var _bend_begin_triangle : VizTriangle
var _bend_end_triangle : VizTriangle
var _arc_begin_mid : Vector3
var _arc_end_mid : Vector3
var _begin : Vector3
var _begin_dir : Vector3
var _end : Vector3
var _end_dir : Vector3
class OptVector3:
var vector : Vector3
func _init(p_data : Vector3):
vector = p_data
func _init(p_begin : VisualizationSpot, p_end : VisualizationSpot, p_width : float, p_bend_lip : float):
if not _is_bendable(p_begin, p_end):
return
_calc_bend_normal(p_begin, p_end)
if not _calc_intersection_point(p_begin, p_end):
return
_calc_join_point(p_begin, p_end)
_calc_bend_side(p_begin, p_end)
_calc_triangles(p_begin, p_end, p_width, p_bend_lip)
_calc_arc_plane()
_begin = _bend_begin_triangle.get_leg_mid()
if not _is_in_order(p_begin.point, _begin, _plane_join_point):
_error = "bend point is too close to beginning for %s to %s with lip %s" % [p_begin.point, p_end.point, p_bend_lip]
return
_end = _bend_end_triangle.get_leg_mid()
if not _is_in_order(_plane_join_point, _end, p_end.point):
_error = "bend point is too close to end for %s to %s with lip %s" % [p_begin.point, p_end.point, p_bend_lip]
return
func _to_string():
return "%s->%s->%s" % [_begin, _plane_join_point, _end]
# ---------------------------------------------
# Public Methoeds
func get_error() -> String:
return _error
func is_invalid() -> bool:
if _error != "":
return true
return false
func get_begin() -> Vector3:
return _begin
func get_end() -> Vector3:
return _end
func is_angled() -> bool:
return not is_zero_approx(_bend_side)
func is_angled_against_curve() -> bool:
if _bend_side * _curve_side < 0:
return true
return false
func get_half_leg_width() -> Vector3:
return (_bend_begin_triangle.leg_left - _bend_begin_triangle.leg_right) / 2.0
func get_half_bend_width() -> Vector3:
return (_bend_begin_triangle.bend_left - _bend_begin_triangle.bend_right) / 2.0
func get_begin_triangle() -> VizTriangle:
return _bend_begin_triangle
func get_end_triangle() -> VizTriangle:
return _bend_end_triangle
func get_shift_width() -> Vector3:
return _arc_begin_mid - _bend_begin_triangle.get_bend_mid() + _bend_end_triangle.get_bend_mid() - _arc_end_mid
func get_shift_offset() -> Vector3:
return _arc_begin_mid - _bend_begin_triangle.get_bend_mid()
func get_arc_begin_point() -> Vector3:
return _arc_begin_mid
func get_arc_end_point() -> Vector3:
return _arc_end_mid
func get_arc_point(weight : float, sharpness : float) -> Vector3:
return _curve_point(_arc_begin_mid, _plane_join_point, _arc_end_mid, weight, sharpness)
# ---------------------------------------------
# Private Methods
func _curve_point(p0 : Vector3, p1 : Vector3, p2 : Vector3, t : float, s : float) -> Vector3:
var p := p1 + pow(1-t, 2.0) * s * (p0-p1) + pow(t, 2.0) * s * (p2-p1)
return p
func _is_in_order(b : Vector3, m : Vector3, e : Vector3) -> bool:
return (e-m).normalized().dot((m-b).normalized()) > 0
func _is_bendable(p_begin : VisualizationSpot, p_end : VisualizationSpot) -> bool:
var dir := (p_end.point - p_begin.point).normalized()
var begin_norm_sign := signf(dir.dot(p_begin.normal))
var end_norm_sign := signf(dir.dot(p_end.normal))
if begin_norm_sign == end_norm_sign:
_error = "%s cannot be twisted into %s" % [ p_begin.normal, p_end.normal ]
return false
_curve_side = end_norm_sign
return true
func _calc_bend_normal(p_begin : VisualizationSpot, p_end : VisualizationSpot):
var middle = p_begin.point + (p_end.point - p_begin.point) / 2.0
_bend_normal = p_begin.normal.cross(p_end.normal).normalized()
_bend_plane = Plane(_bend_normal, middle)
func _calc_intersection_point(p_begin : VisualizationSpot, p_end : VisualizationSpot) -> bool:
_begin_on_bend_plane = _bend_plane.project(p_begin.point)
_end_on_bend_plane = _bend_plane.project(p_end.point)
var dir := _end_on_bend_plane - _begin_on_bend_plane
var begin_normal_on_bend_plane := _bend_plane.project(p_begin.point + p_begin.normal) - _begin_on_bend_plane
var end_normal_on_bend_plane := _bend_plane.project(p_end.point + p_end.normal) - _end_on_bend_plane
var begin_bend_binormal := begin_normal_on_bend_plane.cross(dir)
var begin_bend_tangent := begin_bend_binormal.cross(begin_normal_on_bend_plane).normalized()
var end_bend_binormal := end_normal_on_bend_plane.cross(dir)
var end_bend_tangent := end_bend_binormal.cross(end_normal_on_bend_plane).normalized()
_intersect_data = _intersect(_begin_on_bend_plane, begin_bend_tangent, _end_on_bend_plane, end_bend_tangent, _bend_normal)
if _intersect_data == null:
_error = "intersection failed unexpectedly: normal %s at %s is parallel with normal %s at %s" % [ begin_normal_on_bend_plane, _begin_on_bend_plane, end_normal_on_bend_plane, _end_on_bend_plane ]
return false
return true
func _calc_join_point(p_begin : VisualizationSpot, p_end : VisualizationSpot):
var begin_bend_from_intersect := p_begin.point + _intersect_data.vector - _begin_on_bend_plane
var end_bend_from_intersect := p_end.point + _intersect_data.vector - _end_on_bend_plane
var begin_intersect_distance := begin_bend_from_intersect.distance_to(p_begin.point)
var end_intersect_distance := end_bend_from_intersect.distance_to(p_end.point)
var begin_to_end_on_bend_distance := end_bend_from_intersect.distance_to(begin_bend_from_intersect)
var begin_to_end_intersect_join_numerator := begin_to_end_on_bend_distance * begin_intersect_distance / end_intersect_distance
var begin_to_end_intersect_join_denominator := 1.0 + begin_intersect_distance / end_intersect_distance
var begin_on_end_intersect_join_distance := begin_to_end_intersect_join_numerator / begin_to_end_intersect_join_denominator
var begin_bend_dir := begin_bend_from_intersect - p_begin.point
var end_bend_dir := end_bend_from_intersect - p_begin.point
var begin_to_end_normal := begin_bend_dir.cross(end_bend_dir)
var begin_to_end_binormal := begin_to_end_normal.cross(_bend_normal)
var begin_on_end_intersect_side = signf(end_bend_dir.dot(begin_to_end_binormal))
_plane_join_point = begin_bend_from_intersect - begin_on_end_intersect_side * begin_on_end_intersect_join_distance * _bend_normal
func _calc_bend_side(p_begin : VisualizationSpot, p_end : VisualizationSpot):
_begin_dir = Vector3(_plane_join_point - p_begin.point).normalized()
_end_dir = Vector3(p_end.point - _plane_join_point).normalized()
_bend_side = signf(_bend_normal.dot(_end_dir))
func _calc_triangles(p_begin : VisualizationSpot, p_end : VisualizationSpot, p_width : float, p_bend_lip : float):
var begin_binormal := _begin_dir.cross(p_begin.normal).normalized()
var end_binormal := _end_dir.cross(p_end.normal).normalized()
_bend_begin_triangle = VizTriangle.new()
_bend_begin_triangle.update(_begin_dir, _plane_join_point, begin_binormal, p_width, p_bend_lip, _bend_normal, _bend_side, _curve_side)
_bend_end_triangle = VizTriangle.new()
_bend_end_triangle.update(-_end_dir, _plane_join_point, end_binormal, p_width, p_bend_lip, _bend_normal, -_bend_side, _curve_side)
func _calc_arc_plane():
var begin_mid := _bend_begin_triangle.get_leg_mid()
var end_mid := _bend_end_triangle.get_leg_mid()
var arc_center := _plane_join_point - (_plane_join_point - begin_mid) - (_plane_join_point - end_mid)
var arc_plane := Plane(_bend_normal, arc_center)
_arc_begin_mid = arc_plane.project(_bend_begin_triangle.get_bend_mid())
_arc_end_mid = arc_plane.project(_bend_end_triangle.get_bend_mid())
func _intersect(a : Vector3, a_norm : Vector3, b : Vector3, b_norm : Vector3, plane_norm : Vector3) -> OptVector3:
var seg := b - a
var seg_len := seg.length()
var seg_norm := seg.normalized()
var alpha_sign := signf(b_norm.cross(a_norm).dot(plane_norm))
var cos_alpha := b_norm.dot(a_norm)
var beta_sign := signf(seg_norm.cross(b_norm).dot(plane_norm))
var cos_beta := seg_norm.dot(b_norm)
var intersect_side := alpha_sign * beta_sign
var sin_alpha := sqrt(1 - cos_alpha*cos_alpha)
var sin_beta := sqrt(1 - cos_beta*cos_beta)
if is_equal_approx(sin_alpha, 0.0):
return null
var q := seg_len * sin_beta / sin_alpha
var p := a - intersect_side * q * a_norm
return OptVector3.new(p)

View file

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

View file

@ -0,0 +1,120 @@
extends RefCounted
class_name VizCompoundLeg
var _error : String = ""
var _begin : VisualizationSpot
var _end : VisualizationSpot
var _width : float
var _bend_lip : float
var _intermediate_spot : VisualizationSpot = null
var _norm_distance : float
var _max_join_point_on_begin : Vector3
var _max_join_point_on_end : Vector3
func _init(p_begin : VisualizationSpot, p_end : VisualizationSpot, p_width : float, p_bend_lip : float):
_begin = p_begin
_end = p_end
_width = p_width
_bend_lip = p_bend_lip
_calc_intermediate_point()
# _calc_max_offset()
_calc_intermediate_normal()
func _to_string():
return "CLEG(%s to %s through %s)" % [_begin, _end, _intermediate_spot]
# ---------------------------------------------
# Public Methoeds
func is_invalid() -> bool:
return _error != ""
func get_error() -> String:
return _error
func get_begin() -> VisualizationSpot:
return _begin
func get_begin_ray() -> Vector3:
return (_max_join_point_on_begin - _begin.point).normalized()
func adjust_begin(distance : float):
var new_begin := VisualizationSpot.new()
new_begin.point = _begin.point + distance * get_begin_ray()
new_begin.normal = _begin.normal
_begin = new_begin
_calc_intermediate_normal()
func get_end() -> VisualizationSpot:
return _end
func get_end_ray() -> Vector3:
return (_end.point - _max_join_point_on_end).normalized()
func adjust_end(distance : float):
var new_end := VisualizationSpot.new()
new_end.point = _end.point - distance * get_end_ray()
new_end.normal = _end.normal
_end = new_end
_calc_intermediate_normal()
var test_mat : Material = load("res://example/common/materials/white.tres")
func update_mesh(mesh_node : Node3D, u : float, segs : int, sharpness : float, mat : Material) -> float:
var leg1 := VizSimpleLeg.new(_begin, _intermediate_spot, _width, _bend_lip)
if leg1.is_invalid():
print("leg1=%s: error=%s" % [ leg1, leg1.get_error() ])
assert(!leg1.is_invalid())
var leg2 := VizSimpleLeg.new(_intermediate_spot, _end, _width, _bend_lip)
if leg2.is_invalid():
print("leg2: error=%s" % leg2.get_error())
assert(!leg2.is_invalid())
u = leg1.update_mesh(mesh_node, u, segs, sharpness, mat)
var left := leg1.get_end_left()
var right := leg1.get_end_right()
u = leg2.extend_mesh(mesh_node, u, left, right, segs, sharpness, mat)
return u
# ---------------------------------------------
# Local Methods
func _calc_intermediate_point():
_intermediate_spot = VisualizationSpot.new()
var intermediate_segment := _end.point - _begin.point
_intermediate_spot.point = _begin.point + intermediate_segment / 2.0
func _calc_intermediate_normal():
var begin_plane := Plane(_begin.normal, _begin.point)
var max_point := begin_plane.project(_intermediate_spot.point)
# var mid_point_distance := _intermediate_spot.point.distance_to(max_point)
var mid_point_distance := _begin.point.distance_to(max_point)
var cur_norm_distance = _bend_lip + VizSimpleLeg.MIN_SEGMENT_LENGTH
var dir := (max_point - _begin.point).normalized()
var valid := false
while cur_norm_distance < mid_point_distance:
var data := _check_normal(dir, cur_norm_distance)
if data.size() == 3:
_max_join_point_on_begin = data[0]
_max_join_point_on_end = data[1]
_intermediate_spot.normal = data[2]
valid = true
break
cur_norm_distance += 0.01
if not valid:
_error = "%s is too close to %s to make compund leg with lip %s" % [ _begin.point, _end.point, _bend_lip ]
func _check_normal(dir : Vector3, norm_distance : float) -> Array:
var candidate_segment := _intermediate_spot.point - (_begin.point + norm_distance * dir)
var candidate_segment_dir := candidate_segment.normalized()
var candidate_normal := ((_begin.normal + _end.normal)/2.0).normalized()
var candidate_binormal := candidate_normal.cross(candidate_segment_dir).normalized()
var candidate_mid := VisualizationSpot.new()
candidate_mid.point = _intermediate_spot.point
candidate_mid.normal = candidate_segment_dir.cross(candidate_binormal).normalized()
var leg1 := VizSimpleLeg.new(_begin, candidate_mid, _width, _bend_lip)
if not leg1.is_invalid():
var leg2 := VizSimpleLeg.new(candidate_mid, _end, _width, _bend_lip)
if not leg2.is_invalid():
return [ leg1.get_leg_bend_begin(), leg2.get_leg_bend_end(), candidate_mid.normal ]
return []

View file

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

View file

@ -0,0 +1,102 @@
extends RefCounted
class_name VizMid
var _seg1 : VizSegment
var _seg2 : VizSegment
var _width : float
var _inner_radius : float
var _rotation_point : VisualizationSpot
var _angle : float
var _error : String
func _init(p_seg1 : VizSegment, p_seg2 : VizSegment, p_stroke_width : float, p_inner_radius : float):
_seg1 = p_seg1
_seg2 = p_seg2
_width = p_stroke_width
_inner_radius = p_inner_radius
assert(p_seg1.get_end().is_equal(p_seg2.get_begin()))
_calc_rotation_point()
var center_distance := calc_center_distance(p_stroke_width, p_inner_radius)
var turn_distance := calc_turn_distance(center_distance, _angle)
p_seg1.adjust_end(turn_distance)
if p_seg1.is_invalid():
return
p_seg2.adjust_begin(turn_distance)
if p_seg2.is_invalid():
return
# ---------------------------------------------
# Public Methoeds
func is_invalid() -> bool:
return _error != ""
func get_error() -> String:
return _error
func update_mesh(_mesh_instance : MeshInstance3D, u : float, num_segs : int, mat : Material):
return _create_fan(_mesh_instance, u, num_segs, mat)
# ---------------------------------------------
# Private Methods
func _calc_rotation_point():
var seg1_ray := _seg1.get_end_ray()
var seg2_ray := _seg2.get_begin_ray()
_angle = seg1_ray.angle_to(seg2_ray)
var join_point := _seg1.get_end()
var plane_normal := seg1_ray.cross(seg2_ray).normalized()
if plane_normal == Vector3.ZERO:
plane_normal = join_point.normal
var binormal = plane_normal.cross(seg1_ray).normalized()
var d := calc_center_distance(_width, _inner_radius)
var e := calc_turn_distance(d, _angle)
_rotation_point = VisualizationSpot.new()
_rotation_point.point = join_point.point - e * seg1_ray + d * binormal
_rotation_point.normal = plane_normal
func _create_fan(mesh_node : Node3D, u : float, num_segs : int, mat : Material) -> float:
var radius := _width/2.0 + _inner_radius
var arc_len := absf(_angle) * radius
var begin_half_width := _seg1.get_end_binormal() * _width/2.0
var end_half_width := _seg2.get_begin_binormal() * _width/2.0
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
st.set_color(Color(1, 0, 0))
st.set_normal(_seg1.get_end().normal)
st.set_uv(Vector2(u, 1))
st.add_vertex(_seg1.get_end().point + begin_half_width)
st.set_uv(Vector2(u, 0))
st.add_vertex(_seg1.get_end().point - begin_half_width)
var outer_base := _seg1.get_end().point + begin_half_width - _rotation_point.point
var inner_base := _seg1.get_end().point - begin_half_width - _rotation_point.point
for i in range(1, num_segs-1):
var cur_angle : float = _angle * float(i) / float(num_segs-1)
var cur_arc_len = absf(cur_angle) * radius
var inner := _rotation_point.point + inner_base.rotated(_rotation_point.normal, cur_angle)
var outer := _rotation_point.point + outer_base.rotated(_rotation_point.normal, cur_angle)
st.set_uv(Vector2(u+cur_arc_len, 1))
st.add_vertex(outer)
st.set_uv(Vector2(u+cur_arc_len, 0))
st.add_vertex(inner)
st.set_uv(Vector2(u+arc_len, 1))
st.add_vertex(_seg2.get_begin().point + end_half_width)
st.set_uv(Vector2(u+arc_len, 0))
st.add_vertex(_seg2.get_begin().point - end_half_width)
st.set_material(mat)
mesh_node.mesh = st.commit(mesh_node.mesh)
return u + arc_len
static func calc_center_distance(stroke_width : float, inner_radius : float) -> float:
return stroke_width / 2.0 + inner_radius
static func calc_turn_distance(center_distance : float, angle : float) -> float:
return center_distance * tan(abs(angle)/2.0)

View file

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

View file

@ -0,0 +1,86 @@
extends RefCounted
class_name VizSegment
var _simple_leg : VizSimpleLeg = null
var _compound_leg : VizCompoundLeg = null
func _init(p_begin : VisualizationSpot, p_end : VisualizationSpot, p_width : float, p_bend_lip : float):
_simple_leg = VizSimpleLeg.new(p_begin, p_end, p_width, p_bend_lip)
if _simple_leg.is_invalid():
_compound_leg = VizCompoundLeg.new(p_begin, p_end, p_width, p_bend_lip)
func is_invalid() -> bool:
if _simple_leg.is_invalid():
if _compound_leg.is_invalid():
return true
return false
func get_error() -> String:
if _simple_leg.is_invalid():
if _compound_leg.is_invalid():
return _compound_leg.get_error()
return _simple_leg.get_error()
return ""
func get_begin() -> VisualizationSpot:
if not _simple_leg.is_invalid():
return _simple_leg.get_begin()
return _compound_leg.get_begin()
func get_begin_ray() -> Vector3:
if not _simple_leg.is_invalid():
return _simple_leg.get_begin_ray()
return _compound_leg.get_begin_ray()
func get_begin_binormal() -> Vector3:
if not _simple_leg.is_invalid():
return _simple_leg.get_begin_ray().cross(_simple_leg.get_begin().normal)
return _compound_leg.get_begin_ray().cross(_compound_leg.get_begin().normal)
func adjust_begin(distance : float):
if not _simple_leg.is_invalid():
_simple_leg.adjust_begin(distance)
if _simple_leg.is_invalid():
_compound_leg = VizCompoundLeg.new(_simple_leg.get_begin(), _simple_leg.get_end(), _simple_leg._width, _simple_leg._bend_lip)
else:
_compound_leg.adjust_begin(distance)
func get_end() -> VisualizationSpot:
if not _simple_leg.is_invalid():
return _simple_leg.get_end()
return _compound_leg.get_end()
func get_end_ray() -> Vector3:
if not _simple_leg.is_invalid():
return _simple_leg.get_end_ray()
return _compound_leg.get_end_ray()
func get_end_binormal() -> Vector3:
if not _simple_leg.is_invalid():
return _simple_leg.get_end_ray().cross(_simple_leg.get_end().normal)
return _compound_leg.get_end_ray().cross(_compound_leg.get_end().normal)
func adjust_end(distance : float):
if not _simple_leg.is_invalid():
_simple_leg.adjust_end(distance)
if _simple_leg.is_invalid():
_compound_leg = VizCompoundLeg.new(_simple_leg.get_begin(), _simple_leg.get_end(), _simple_leg._width, _simple_leg._bend_lip)
else:
_compound_leg.adjust_end(distance)
func update_mesh(mesh_instance : MeshInstance3D, u : float, segs : int, sharpness : float, mat : Material) -> float:
if _simple_leg.is_invalid():
if _compound_leg.is_invalid():
return u
u = _compound_leg.update_mesh(mesh_instance, u, segs, sharpness, mat)
else:
u = _simple_leg.update_mesh(mesh_instance, u, segs, sharpness, mat)
return u
func _to_string():
if not _simple_leg.is_invalid():
return _simple_leg._to_string()
if not _compound_leg.is_invalid():
return _compound_leg._to_string()
return "invalid segment"

View file

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

View file

@ -0,0 +1,307 @@
extends RefCounted
class_name VizSimpleLeg
var _error : String = ""
var _begin : VisualizationSpot
var _end : VisualizationSpot
var _width : float
var _bend_lip : float
var _bend : VizBend
const MIN_SEGMENT_LENGTH=0.01
const EPSILON=0.00001
func _init(p_begin : VisualizationSpot, p_end : VisualizationSpot, p_width : float, p_bend_lip : float):
_begin = p_begin
_end = p_end
_width = p_width
_bend_lip = p_bend_lip
if not _has_valid_normal():
return
if _is_straight():
return
_bend = VizBend.new(_begin, _end, p_width, p_bend_lip)
if not _bend.is_invalid():
_check_offsets(_begin, _end)
# ---------------------------------------------
# Public Methods
func get_error() -> String:
if _error != "":
return _error
if _bend != null:
return _bend.get_error()
return ""
func is_invalid() -> bool:
if _error != "":
return true
if _bend != null:
return _bend.is_invalid()
return false
func extend_mesh(mesh_node : Node3D, u : float, left : Vector3, right : Vector3, segs : int, sharpness : float, mat : Material) -> float:
if _bend == null:
u = _extend_straight_leg(mesh_node, u, left, right, _begin.point, _end.point, _begin.normal, mat)
else:
u = _extend_straight_leg(mesh_node, u, left, right, _begin.point, _bend.get_begin(), _begin.normal, mat)
if _bend.is_angled():
u = _create_begin_triangle(mesh_node, u, _begin.normal, _bend.get_begin_triangle(), mat)
u = _create_bend(mesh_node, u, segs, sharpness, mat)
if _bend.is_angled():
u = _create_end_triangle(mesh_node, u, _end.normal, _bend.get_end_triangle(), mat)
u = _create_straight_leg(mesh_node, u, _bend.get_end(), _end.point, _end.normal, mat)
return u
func update_mesh(mesh_node : Node3D, u : float, segs : int, sharpness : float, mat : Material) -> float:
if _bend == null:
u = _create_straight_leg(mesh_node, u, _begin.point, _end.point, _begin.normal, mat)
else:
u = _create_straight_leg(mesh_node, u, _begin.point, _bend.get_begin(), _begin.normal, mat)
if _bend.is_angled():
u = _create_begin_triangle(mesh_node, u, _begin.normal, _bend.get_begin_triangle(), mat)
u = _create_bend(mesh_node, u, segs, sharpness, mat)
if _bend.is_angled():
u = _create_end_triangle(mesh_node, u, _end.normal, _bend.get_end_triangle(), mat)
u = _create_straight_leg(mesh_node, u, _bend.get_end(), _end.point, _end.normal, mat)
return u
func get_begin() -> VisualizationSpot:
return _begin
func get_leg_bend_begin() -> Vector3:
if _bend == null:
return (_end.point - _begin.point)/2.0
return _bend.get_begin_triangle().get_leg_mid()
func get_begin_ray() -> Vector3:
if _bend == null:
return (_end.point - _begin.point).normalized()
return (_bend.get_begin() - _begin.point).normalized()
func adjust_begin(distance : float):
var new_begin := VisualizationSpot.new()
new_begin.point = _begin.point + distance * get_begin_ray()
new_begin.normal = _begin.normal
if _check_offsets(new_begin, _end):
_begin = new_begin
func get_end() -> VisualizationSpot:
return _end
func get_leg_bend_end() -> Vector3:
if _bend == null:
return (_end.point - _begin.point)/2.0
return _bend.get_end_triangle().get_leg_mid()
func get_end_left() -> Vector3:
var segment := _end.point - get_leg_bend_end()
var binormal := segment.cross(_end.normal).normalized()
var half_width = binormal*_width/2.0
return _end.point - half_width
func get_end_right() -> Vector3:
var segment := _end.point - get_leg_bend_end()
var binormal := segment.cross(_end.normal).normalized()
var half_width = binormal*_width/2.0
return _end.point + half_width
func get_end_ray() -> Vector3:
if _bend == null:
return (_end.point - _begin.point).normalized()
return (_end.point - _bend.get_end()).normalized()
func adjust_end(distance : float):
var new_end := VisualizationSpot.new()
new_end.point = _end.point - distance * get_end_ray()
new_end.normal = _end.normal
if _check_offsets(_begin, new_end):
_end = new_end
# ---------------------------------------------
# Local Methods
func _check_offsets(p_begin : VisualizationSpot, p_end : VisualizationSpot) -> bool:
var dir := (_end.point - _begin.point).normalized()
var min_len := MIN_SEGMENT_LENGTH + EPSILON
var max_begin := _end.point - dir * min_len
var max_end := _begin.point + dir * min_len
if _bend != null:
max_begin = _bend.get_begin() - dir * min_len
max_end = _bend.get_end() + dir * min_len
var new_begin_dir := (max_begin - p_begin.point).normalized()
var new_end_dir := (p_end.point - max_end).normalized()
if new_begin_dir.dot(dir) <= 0.0:
_error = "bend start %s is too near %s to be bent with this width and lip" % [ _begin.point, _end.point ]
return false
if new_end_dir.dot(dir) <= 0.0:
_error = "bend end %s is too near %s to be bent with this width and lip" % [ _end.point, _begin.point ]
return false
return true
func _has_valid_normal() -> bool:
var segment = _end.point - _begin.point
var binormal = segment.cross(_begin.normal).normalized()
if not binormal.is_normalized():
_error = "%s to %s is parallel to normal %s" % [ _begin.point, _end.point, _begin.normal ]
return false
return true
func _is_straight() -> bool:
if _begin.normal.is_equal_approx(_end.normal):
var segment = _end.point - _begin.point
if is_equal_approx(segment.dot(_begin.normal), 0.0):
return true
_error = "%s to %s have same normal but are not in same plane" % [ _begin.point, _end.point ]
return false
func _extend_straight_leg(mesh_node : Node3D, u : float, left : Vector3, right : Vector3, begin : Vector3, end : Vector3, normal : Vector3, mat : Material):
var segment := end - begin
var binormal := segment.cross(normal).normalized()
var half_width = binormal*_width/2.0
var seg := begin - end
var seg_len := seg.length()
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
st.set_color(Color(1, 0, 0))
st.set_normal(normal)
st.set_uv(Vector2(u, 1))
st.add_vertex(right)
st.set_uv(Vector2(u, 0))
st.add_vertex(left)
st.set_uv(Vector2(u+seg_len, 1))
st.add_vertex(end+half_width)
st.set_uv(Vector2(u+seg_len, 0))
st.add_vertex(end-half_width)
st.set_material(mat)
mesh_node.mesh = st.commit(mesh_node.mesh)
return u + seg_len
func _create_straight_leg(mesh_node : Node3D, u : float, begin : Vector3, end : Vector3, normal : Vector3, mat : Material):
var segment := end - begin
var binormal := segment.cross(normal).normalized()
var half_width = binormal*_width/2.0
var seg := begin - end
var seg_len := seg.length()
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
st.set_color(Color(1, 0, 0))
st.set_normal(normal)
st.set_uv(Vector2(u, 1))
st.add_vertex(begin+half_width)
st.set_uv(Vector2(u, 0))
st.add_vertex(begin-half_width)
st.set_uv(Vector2(u+seg_len, 1))
st.add_vertex(end+half_width)
st.set_uv(Vector2(u+seg_len, 0))
st.add_vertex(end-half_width)
st.set_material(mat)
mesh_node.mesh = st.commit(mesh_node.mesh)
return u + seg_len
func _create_begin_triangle(mesh_node : Node3D, u : float, normal : Vector3, triangle : VizTriangle, mat : Material):
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_color(Color(1, 0, 0))
st.set_normal(normal)
st.set_uv(Vector2(u, 0))
st.add_vertex(triangle.leg_left)
st.set_uv(Vector2(u + triangle.distance, triangle.get_fwd_side()))
st.add_vertex(triangle.leg_fwd)
st.set_uv(Vector2(u, 1))
st.add_vertex(triangle.leg_right)
st.set_material(mat)
mesh_node.mesh = st.commit(mesh_node.mesh)
return u + triangle.distance
func _create_end_triangle(mesh_node : Node3D, u : float, normal : Vector3, triangle : VizTriangle, mat : Material):
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_color(Color(1, 0, 0))
st.set_normal(normal)
st.set_uv(Vector2(u + triangle.distance, 0))
st.add_vertex(triangle.leg_left)
st.set_uv(Vector2(u + triangle.distance, 1))
st.add_vertex(triangle.leg_right)
st.set_uv(Vector2(u, triangle.get_fwd_side()))
st.add_vertex(triangle.leg_fwd)
st.set_material(mat)
mesh_node.mesh = st.commit(mesh_node.mesh)
return u + triangle.distance
func _create_bend(mesh_node : Node3D, u : float, segs : int, sharpness : float, mat : Material):
var right_u := u - _bend.get_begin_triangle().distance
var left_u := u
if _bend.is_angled_against_curve():
right_u = u
left_u = u - _bend.get_begin_triangle().distance
var arc_len := 0.0
var segment := _bend.get_begin() - _begin.point
var binormal := segment.cross(_begin.normal).normalized()
var half_width = _bend.get_half_bend_width()
var half_width_normal := half_width.normalized()
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
st.set_normal(_begin.normal)
st.set_uv(Vector2(right_u, 1))
st.add_vertex(_bend.get_begin_triangle().bend_right)
st.set_uv(Vector2(left_u, 0))
st.add_vertex(_bend.get_begin_triangle().bend_left)
var shift_width := _bend.get_shift_width()
var last_point := _bend.get_arc_begin_point()
var total_len := 0.0
for i in range(0, segs):
var weight := float(i) / float(segs-1)
var cur_point := _bend.get_arc_point(weight, sharpness)
total_len += cur_point.distance_to(last_point)
last_point = cur_point
total_len += _bend.get_arc_end_point().distance_to(last_point)
last_point = _bend.get_arc_begin_point()
for i in range(1, segs-1):
var weight := float(i) / float(segs-1)
var cur_point := _bend.get_arc_point(weight, sharpness)
arc_len += cur_point.distance_to(last_point)
var shift := shift_width * (arc_len / total_len)
var pos := cur_point + shift - _bend.get_shift_offset()
var cur_normal := Vector3(cur_point - last_point).normalized().cross(half_width_normal)
last_point = cur_point
st.set_normal(cur_normal)
st.set_uv(Vector2(right_u + arc_len, 1))
st.add_vertex(pos-half_width)
st.set_uv(Vector2(left_u + arc_len, 0))
st.add_vertex(pos+half_width)
st.set_normal(_end.normal)
st.set_uv(Vector2(right_u + total_len, 1))
st.add_vertex(_bend.get_end_triangle().bend_right)
st.set_uv(Vector2(left_u + total_len, 0))
st.add_vertex(_bend.get_end_triangle().bend_left)
st.set_material(mat)
mesh_node.mesh = st.commit(mesh_node.mesh)
u = right_u + total_len
if _bend.is_angled_against_curve():
u = left_u + total_len
return u
func _to_string():
if _bend != null:
return "SLEG(%s->%s through %s)" % [ _begin, _end, _bend ]
return "SLEG(%s->%s)" % [ _begin, _end ]

View file

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

View file

@ -0,0 +1,46 @@
extends RefCounted
class_name VizTriangle
var leg_right : Vector3
var leg_left : Vector3
var leg_fwd : Vector3
var bend_right : Vector3
var bend_left : Vector3
var distance : float
var fwd_side : float
func update(dir : Vector3, join_point : Vector3, binormal : Vector3, p_width : float, p_bend_lip : float, bend_normal : Vector3, bend_side : float, curve_side : float):
var half_width := p_width / 2.0
if bend_side == 0:
leg_left = join_point - half_width * binormal - p_bend_lip * dir
leg_right = join_point + half_width * binormal - p_bend_lip * dir
bend_left = leg_left
bend_right = leg_right
distance = 0.0
else:
var cos_theta := dir.dot(bend_side * bend_normal)
var sin_theta := sqrt(1-cos_theta*cos_theta)
var width := half_width / sin_theta
var lip_distance := p_bend_lip / sin_theta
var bend_width = width * cos_theta
leg_left = join_point - half_width * binormal - bend_width * dir - lip_distance * dir
leg_right = join_point + half_width * binormal - bend_width * dir - lip_distance * dir
leg_fwd = join_point - curve_side * bend_side * half_width * binormal + bend_width * dir - lip_distance * dir
distance = bend_width * 2.0
if bend_side * curve_side < 0:
bend_left = leg_left
bend_right = leg_fwd
fwd_side = 1.0
else:
bend_left = leg_fwd
bend_right = leg_right
fwd_side = 0.0
func get_fwd_side():
return fwd_side
func get_leg_mid() -> Vector3:
return leg_left - (leg_left - leg_right) / 2.0
func get_bend_mid() -> Vector3:
return bend_left - (bend_left - bend_right) / 2.0

View file

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

View file

@ -0,0 +1,200 @@
## Ths class is designed to create a mesh that
## will display a path between pairs of VisualizationSpots.
##
## To use a VisualizedPath it must be populated with an array
## of spots which define the local object space positions and
## normals for the path at that point.
##
## The spots array can be defined programmatically such as by
## user action (such as clicking) or defined in the editor using
## the VizPath gizmo.
##
## Not all paths are valid. Putting the spots too close together
## or with normals that do not leave enough room for bends to be
## created with the defined path characteristics (width, inner radius,
## etc.), will result in the path not being displayed and the "error"
## attribute being set to the underlying problem.
##
@tool
@icon("res://addons/vizpath/images/path.png")
extends Node3D
class_name VisualizedPath
signal changed_layout
## The spots array defines where the path will go between.
## See [VisualizationSpot]
@export var spots : Array[VisualizationSpot] :
set(p_spots):
spots = p_spots
for spot in spots:
if not spot.changed.is_connected(_rebuild):
spot.changed.connect(_rebuild)
_rebuild()
## The path_width defines the width of the path, which indirectly
## determines how tight the path can turn at a midpoint spot.
@export_range(0.005, 100, 0.001) var path_width := 0.1 :
set(w):
path_width = w
_rebuild()
## The inner_curve_radius defines how tight a turn can be made
## at a midpoint spot within the path.
@export_range(0.005, 100, 0.001) var inner_curve_radius := 0.1 :
set(r):
inner_curve_radius = r
_rebuild()
## The num_curve_segs defines how many points will be defined in the
## arc that are used to create a turn. More segments will
## make a smoother UV mapping and therefore the display of associated material
## more accurate.
@export_range(4, 128) var num_curve_segs := 32 :
set(r):
num_curve_segs = r
_rebuild()
## The bend_segs defines the segments in a bend of the path when transitioning
## between two spots with normals not in the same plane.
@export_range(4, 128) var bend_segs := 6 :
set(r):
bend_segs = r
_rebuild()
## The bend_lip defines the distance that a segment extends from the intersection
## of the planes defined by the beginning and ending normals when those normals
## are not in the same plane. Making this a smaller value will make the
## segment flatter for more of its length.
@export_range(0.005, 100, 0.001) var bend_lip := 0.1 :
set(r):
bend_lip = r
_rebuild()
## The bend_sharpness defines how sharp the bend in a path. Making this
## smaller will result in a tighter bend.
@export var bend_sharpness := 1.0 :
set(r):
bend_sharpness = r
_rebuild()
## The path_mat is the material that will be applied to the underlying mesh
## that displays the path. The initial spot in the path will have texture coordinates
## that start with U equal to 0.0 and ending at the value calculated as the actual length of the path
## in local space. The V will range between 0.0 at the left side of the path, and 1.0 at the
## right side of the path.
@export var path_mat : Material :
set(m):
path_mat = m
_rebuild()
## The path_head is a resource (optional) that defines the end of the path by
## providing an "apply" method. The provided [VizHead] resource is an example
## that draws an arrow head on the end.
@export var path_head : VizHead :
set(m):
path_head = m
path_head.changed.connect(_rebuild)
_rebuild()
## The path_tail is a resource (optional) that defines the start of the path by
## providing an "apply" method. The provided [VizTail] resource is an example
## that draws a rounded cap on the end.
@export var path_tail : VizTail :
set(m):
path_tail = m
path_tail.changed.connect(_rebuild)
_rebuild()
@export var suppress_warnings := false :
set(s):
suppress_warnings = s
_rebuild()
var _mesh_instance : MeshInstance3D
var _errors : Array[String]
func get_triangle_mesh() -> TriangleMesh:
if _mesh_instance.mesh != null:
return _mesh_instance.mesh.generate_triangle_mesh()
return null
func _ready():
_mesh_instance = MeshInstance3D.new()
add_child(_mesh_instance)
_rebuild()
func _get_configuration_warnings():
if not suppress_warnings:
return PackedStringArray(_errors)
return PackedStringArray()
func get_errors() -> Array[String]:
return _errors
func _rebuild():
_errors = []
if _mesh_instance == null:
return
if spots.size() < 2:
_errors.append("the spots array must have at least 2 entries")
_mesh_instance.mesh = null
var u := 0.0
var segments : Array[VizSegment] = []
for idx in range(1, spots.size()):
segments.push_back(VizSegment.new(spots[idx-1], spots[idx], path_width, bend_lip))
for idx in range(1, segments.size()):
if segments[idx-1].is_invalid():
_errors.push_back(segments[idx-1].get_error())
break
var midpoint := VizMid.new(segments[idx-1], segments[idx], path_width, inner_curve_radius)
if midpoint.is_invalid():
_errors.push_back(midpoint.get_error())
break
# Creating midpoint may invalidate prior segment
if segments[idx-1].is_invalid():
_errors.push_back(segments[idx-1].get_error())
break
if idx == 1:
u = _add_tail(segments[idx-1], u)
u = segments[idx-1].update_mesh(_mesh_instance, u, bend_segs, bend_sharpness, path_mat)
u = midpoint.update_mesh(_mesh_instance, u, num_curve_segs, path_mat)
if _errors.size() == 0:
if segments[segments.size()-1].is_invalid():
_errors.push_back(segments[segments.size()-1].get_error())
else:
if segments.size() == 1:
u = _add_tail(segments[0], u)
_add_head(segments[segments.size()-1], u)
update_configuration_warnings()
changed_layout.emit()
func _add_head(head : VizSegment, u : float):
if path_head != null:
var end := head.get_end().point
var binormal := head.get_end_binormal()
var left := end - binormal * path_width / 2.0
var right := end + binormal * path_width / 2.0
var normal := head.get_end().normal
var direction := head.get_end_ray()
var offset := path_head.get_offset(left, right, normal, direction)
head.adjust_end(offset)
u = head.update_mesh(_mesh_instance, u, bend_segs, bend_sharpness, path_mat)
path_head.apply(_mesh_instance, u, left - direction * offset, right - direction * offset, normal, direction, path_mat)
else:
head.update_mesh(_mesh_instance, u, bend_segs, bend_sharpness, path_mat)
func _add_tail(tail : VizSegment, u : float) -> float:
if path_tail != null:
var begin := tail.get_begin().point
var binormal := tail.get_begin_binormal()
var left := begin - binormal * path_width / 2.0
var right := begin + binormal * path_width / 2.0
var normal := tail.get_begin().normal
var direction := tail.get_begin_ray()
var offset := path_tail.get_offset(left, right, normal, direction)
tail.adjust_begin(offset)
path_tail.apply(_mesh_instance, u, left - direction * offset, right - direction * offset, normal, direction, path_mat)
return u + offset
return u

View file

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

View file

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://b01j6blghusie"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_7md1l"]
[node name="visualized_path" type="Node3D"]
script = ExtResource("1_7md1l")
bend_sharpness = 0.0

15
addons/vizpath/vizpath.gd Normal file
View file

@ -0,0 +1,15 @@
@tool
extends EditorPlugin
const VizpathGizmoPlugin = preload("res://addons/vizpath/vizpath_gizmo_plugin.gd")
var gizmo_plugin = VizpathGizmoPlugin.new()
func _enter_tree():
gizmo_plugin.set_editor_plugin(self)
add_node_3d_gizmo_plugin(gizmo_plugin)
func _exit_tree():
remove_node_3d_gizmo_plugin(gizmo_plugin)

View file

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

View file

@ -0,0 +1,80 @@
extends EditorNode3DGizmo
func _redraw():
clear()
var path := get_node_3d() as VisualizedPath
if not path.changed_layout.is_connected(_redraw):
path.changed_layout.connect(_redraw)
var lines = PackedVector3Array()
for i in range(path.spots.size()):
lines.push_back(path.spots[i].point)
lines.push_back(path.spots[i].point + path.spots[i].normal * path.path_width * 2.0)
var line_material = get_plugin().get_material("line", self)
add_lines(lines, line_material, false)
for i in range(path.spots.size()):
var rotation := Quaternion(Vector3.FORWARD, path.spots[i].normal)
var basis := Basis(rotation)
basis = basis.scaled(Vector3(path.path_width,path.path_width,path.path_width))
var transform := Transform3D(basis, path.spots[i].point)
add_mesh(get_plugin().spot_mesh, line_material, transform)
var triangle_mesh := path.get_triangle_mesh()
if triangle_mesh != null:
add_collision_triangles(triangle_mesh)
func _subgizmos_intersect_frustum(camera : Camera3D, frustrum : Array[Plane]) -> PackedInt32Array:
var path := get_node_3d() as VisualizedPath
var gizmos := PackedInt32Array()
for i in range(path.spots.size()):
var origin := path.global_transform * path.spots[i].point
var any_out := false
for plane in frustrum:
if plane.is_point_over(origin):
any_out = true
if not any_out:
gizmos.push_back(i)
return gizmos
func _subgizmos_intersect_ray(camera : Camera3D, point : Vector2) -> int:
var path := get_node_3d() as VisualizedPath
for i in range(path.spots.size()):
var origin := path.global_transform * path.spots[i].point
var p := camera.unproject_position(origin)
if p.distance_to(point) < 20:
return i
return -1
func _get_subgizmo_transform(id : int) -> Transform3D:
var path := get_node_3d() as VisualizedPath
var rotation := Quaternion(Vector3.FORWARD, path.spots[id].normal)
var basis := Basis(rotation)
var transform := Transform3D(basis, path.spots[id].point)
return transform
func _set_subgizmo_transform(id : int, transform : Transform3D):
var path := get_node_3d() as VisualizedPath
path.spots[id].point = transform.origin
path.spots[id].normal = transform.basis * Vector3.FORWARD
func _commit_subgizmos( ids : PackedInt32Array, restores : Array[Transform3D], cancel : bool):
var path := get_node_3d() as VisualizedPath
if cancel:
for idx in range(ids.size()):
var spot := path.spots[ids[idx]]
spot.point = restores[idx].origin
spot.normal = restores[idx].basis * Vector3.FORWARD
else:
var vizpath_gizmo_plugin := get_plugin() as EditorNode3DGizmoPlugin
var undo_redo = vizpath_gizmo_plugin.editor_plugin.get_undo_redo()
undo_redo.create_action("Modify spots")
for idx in range(ids.size()):
var spot := path.spots[ids[idx]]
undo_redo.add_do_property(spot, "point", spot.point)
undo_redo.add_undo_property(spot, "point", restores[idx].origin)
undo_redo.add_do_property(spot, "normal", spot.normal)
undo_redo.add_undo_property(spot, "normal", restores[idx].basis * Vector3.FORWARD)
undo_redo.commit_action()

View file

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

View file

@ -0,0 +1,24 @@
extends EditorNode3DGizmoPlugin
const vizpath_gizmo = preload("res://addons/vizpath/vizpath_gizmo.gd")
const spot_mesh = preload("res://addons/vizpath/mesh/spot.obj")
var editor_plugin : EditorPlugin
func _init():
create_material("line", Color(1, 1, 0))
create_handle_material("handles")
func _create_gizmo(node):
if node is VisualizedPath:
var viz_path_node := node as VisualizedPath
var gizmo = vizpath_gizmo.new()
return gizmo
else:
return null
func _get_gizmo_name():
return "VizPath Gizmo"
func set_editor_plugin(p_plugin : EditorPlugin):
editor_plugin = p_plugin

View file

@ -0,0 +1 @@
uid://28ida0ysqdac

27
default_bus_layout.tres Normal file
View file

@ -0,0 +1,27 @@
[gd_resource type="AudioBusLayout" load_steps=4 format=3 uid="uid://cjoxo61mhrs7k"]
[sub_resource type="AudioEffectCompressor" id="1"]
resource_name = "Compressor"
threshold = -6.0
ratio = 3.0
[sub_resource type="AudioEffectDelay" id="2"]
resource_name = "Delay"
[sub_resource type="AudioEffectChorus" id="3"]
resource_name = "Chorus"
wet = 0.2
[resource]
bus/1/name = &"Example Bus"
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("1")
bus/1/effect/0/enabled = true
bus/1/effect/1/effect = SubResource("2")
bus/1/effect/1/enabled = true
bus/1/effect/2/effect = SubResource("3")
bus/1/effect/2/enabled = false

7
default_env.tres Normal file
View file

@ -0,0 +1,7 @@
[gd_resource type="Environment" load_steps=2 format=3 uid="uid://bp13sdq75jfyy"]
[sub_resource type="Sky" id="1"]
[resource]
background_mode = 2
sky = SubResource("1")

View file

@ -0,0 +1,76 @@
[gd_scene load_steps=12 format=3 uid="uid://cjl5544idple4"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_jrlnd"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_4hfv6"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/common/materials/move.tres" id="3_hf8la"]
[sub_resource type="Resource" id="Resource_s8kkd"]
script = ExtResource("2_4hfv6")
point = Vector3(0, 0, 0)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_7ts2q"]
script = ExtResource("2_4hfv6")
point = Vector3(-0.121931, 0.5, -0.144112)
normal = Vector3(0, 0.397131, 0.917762)
[sub_resource type="Resource" id="Resource_gt1gn"]
script = ExtResource("2_4hfv6")
point = Vector3(0, 0, 0)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_g7sew"]
script = ExtResource("2_4hfv6")
point = Vector3(0.104292, 0.5, -0.144112)
normal = Vector3(0, 0.369583, 0.929198)
[sub_resource type="Resource" id="Resource_in6um"]
script = ExtResource("2_4hfv6")
point = Vector3(0, 0, 0)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_prkqv"]
script = ExtResource("2_4hfv6")
point = Vector3(0.138177, 0.5, 0.0752829)
normal = Vector3(0, -0.390349, 0.920667)
[sub_resource type="Resource" id="Resource_gsc4k"]
script = ExtResource("2_4hfv6")
point = Vector3(-0.00201809, 0, 0)
normal = Vector3(0.230778, 0.15166, 0.961114)
[sub_resource type="Resource" id="Resource_jodll"]
script = ExtResource("2_4hfv6")
point = Vector3(-0.104844, 0.5, 0.0752829)
normal = Vector3(0, -0.629649, 0.776879)
[node name="bend_modes" type="Node3D"]
[node name="pos_bend_pos_curve" type="Node3D" parent="."]
script = ExtResource("1_jrlnd")
spots = Array[ExtResource("2_4hfv6")]([SubResource("Resource_s8kkd"), SubResource("Resource_7ts2q")])
path_mat = ExtResource("3_hf8la")
[node name="neg_bend_pos_curve" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.215276, 0, 0)
script = ExtResource("1_jrlnd")
spots = Array[ExtResource("2_4hfv6")]([SubResource("Resource_gt1gn"), SubResource("Resource_g7sew")])
path_mat = ExtResource("3_hf8la")
[node name="pos_bend_neg_curve" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.444013, 0, 0)
script = ExtResource("1_jrlnd")
spots = Array[ExtResource("2_4hfv6")]([SubResource("Resource_in6um"), SubResource("Resource_prkqv")])
path_mat = ExtResource("3_hf8la")
[node name="neg_bend_neg_curve" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.852877, 0, 0)
script = ExtResource("1_jrlnd")
spots = Array[ExtResource("2_4hfv6")]([SubResource("Resource_gsc4k"), SubResource("Resource_jodll")])
path_mat = ExtResource("3_hf8la")
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(0.981132, -0.0697522, 0.180319, 0, 0.932653, 0.360776, -0.193339, -0.353969, 0.915055, 0.718682, 0.603321, 0.999084)
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.74374, 0.668469, 0, -0.668469, 0.74374, 0, 1.44215, 1.63761)

View file

@ -0,0 +1,33 @@
[gd_scene load_steps=7 format=3 uid="uid://cgalf6c17i3u5"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_bfmfh"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_rhyv7"]
[ext_resource type="Material" uid="uid://bb6vecpbvsco2" path="res://example/common/materials/green.tres" id="3_0i5gn"]
[ext_resource type="Resource" uid="uid://ca6a3fjxcmbhc" path="res://addons/vizpath/resources/viz_head.tres" id="4_iru8o"]
[sub_resource type="Resource" id="Resource_fbtus"]
script = ExtResource("2_rhyv7")
point = Vector3(0, 0.094, -0.171)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_o2yh3"]
script = ExtResource("2_rhyv7")
point = Vector3(0.271296, 0.508832, -0.373052)
normal = Vector3(0.564135, -0.105104, 0.818965)
[node name="bend_modes" type="Node3D"]
[node name="one_leg2" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0116525, -0.0119494, 0.00156734)
script = ExtResource("1_bfmfh")
spots = Array[ExtResource("2_rhyv7")]([SubResource("Resource_fbtus"), SubResource("Resource_o2yh3")])
path_width = 0.08
bend_lip = 0.01
path_mat = ExtResource("3_0i5gn")
path_head = ExtResource("4_iru8o")
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(0.866918, -0.0684906, 0.493722, 0, 0.990515, 0.137407, -0.49845, -0.119121, 0.858696, 0.397118, 0.326159, 0.203121)
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.74374, 0.668469, 0, -0.668469, 0.74374, 0, 1.44215, 1.63761)

View file

@ -0,0 +1,7 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://bb6vecpbvsco2"]
[resource]
transparency = 1
cull_mode = 2
albedo_color = Color(0, 1, 0.00392157, 0.631373)
emission = Color(0, 1, 0, 1)

View file

@ -0,0 +1,7 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://c4qytbc7juuoa"]
[ext_resource type="Shader" path="res://example/vizpath/common/shaders/move.gdshader" id="1_obwa6"]
[resource]
render_priority = 0
shader = ExtResource("1_obwa6")

View file

@ -0,0 +1,7 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://cioqoqh7f8l87"]
[resource]
transparency = 1
cull_mode = 2
albedo_color = Color(1, 0, 0.00392157, 0.631373)
emission = Color(0, 1, 0, 1)

View file

@ -0,0 +1,3 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://p3gog0gxawyp"]
[resource]

View file

@ -0,0 +1,22 @@
# Blender 3.5.0 MTL File: 'hex-tile.blend'
# www.blender.org
newmtl Face
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.078428 0.800000 0.056291
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
newmtl Hex
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.000000 0.000000 0.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2

View file

@ -0,0 +1,83 @@
# Blender 3.5.0
# www.blender.org
mtllib hex-tile.mtl
o Circle
v 0.000000 0.000000 -1.000000
v -0.866025 0.000000 -0.500000
v -0.866025 0.000000 0.500000
v 0.000000 0.000000 1.000000
v 0.866025 0.000000 0.500000
v 0.866025 0.000000 -0.500000
v 0.000000 0.499561 -0.907686
v -0.786079 0.499561 -0.453843
v -0.786079 0.499561 0.453843
v 0.000000 0.499561 0.907686
v 0.786079 0.499561 0.453843
v 0.786079 0.499561 -0.453843
v -0.866025 0.499561 -0.500000
v 0.000000 0.499561 -1.000000
v -0.866025 0.499561 0.500000
v 0.000000 0.499561 1.000000
v 0.866025 0.499561 0.500000
v 0.866025 0.499561 -0.500000
v -0.000000 0.458301 -0.907686
v -0.786079 0.458301 -0.453843
v -0.786079 0.458301 0.453843
v -0.000000 0.458301 0.907686
v 0.786079 0.458301 0.453843
v 0.786079 0.458301 -0.453843
vn 0.5000 -0.0000 -0.8660
vn 0.5000 -0.0000 0.8660
vn -1.0000 -0.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.5000 -0.0000 0.8660
vn -0.5000 -0.0000 -0.8660
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
s 0
usemtl Face
f 20/20/8 21/21/8 22/22/8 23/23/8 24/24/8 19/19/8
usemtl Hex
f 1/1/1 14/14/1 18/18/1 6/6/1
f 5/5/2 17/17/2 16/16/2 4/4/2
f 3/3/3 15/15/3 13/13/3 2/2/3
f 6/6/4 18/18/4 17/17/4 5/5/4
f 4/4/5 16/16/5 15/15/5 3/3/5
f 2/2/6 13/13/6 14/14/6 1/1/6
f 9/9/4 21/21/4 20/20/4 8/8/4
f 2/2/7 1/1/7 6/6/7 5/5/7 4/4/7 3/3/7
f 7/7/8 14/14/8 13/13/8 8/8/8
f 8/8/8 13/13/8 15/15/8 9/9/8
f 9/9/8 15/15/8 16/16/8 10/10/8
f 10/10/8 16/16/8 17/17/8 11/11/8
f 11/11/8 17/17/8 18/18/8 12/12/8
f 12/12/8 18/18/8 14/14/8 7/7/8
f 12/12/3 24/24/3 23/23/3 11/11/3
f 10/10/1 22/22/1 21/21/1 9/9/1
f 8/8/2 20/20/2 19/19/2 7/7/2
f 7/7/5 19/19/5 24/24/5 12/12/5
f 11/11/6 23/23/6 22/22/6 10/10/6

View file

@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://burem3qbp7oti"
path="res://.godot/imported/hex-tile.obj-ffebd078b94c8039e36db52918aaa2d8.mesh"
[deps]
files=["res://.godot/imported/hex-tile.obj-ffebd078b94c8039e36db52918aaa2d8.mesh"]
source_file="res://example/vizpath/common/mesh/hex-tile.obj"
dest_files=["res://.godot/imported/hex-tile.obj-ffebd078b94c8039e36db52918aaa2d8.mesh", "res://.godot/imported/hex-tile.obj-ffebd078b94c8039e36db52918aaa2d8.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false

View file

@ -0,0 +1,12 @@
# Blender 3.5.0 MTL File: 'hex-tile.blend'
# www.blender.org
newmtl piece
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.046634 0.034524
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://brfhulgwa6r66"
path="res://.godot/imported/piece.obj-248a7c726ba7f768f252db36a9d151af.mesh"
[deps]
files=["res://.godot/imported/piece.obj-248a7c726ba7f768f252db36a9d151af.mesh"]
source_file="res://example/vizpath/common/mesh/piece.obj"
dest_files=["res://.godot/imported/piece.obj-248a7c726ba7f768f252db36a9d151af.mesh", "res://.godot/imported/piece.obj-248a7c726ba7f768f252db36a9d151af.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false

View file

@ -0,0 +1,26 @@
shader_type spatial;
render_mode blend_mix,cull_back,diffuse_burley,specular_schlick_ggx,depth_draw_opaque;
const vec3 color = vec3(0.000000000, 0.415686011, 1.000000000);
varying float elapsed_time;
float gradient_fct(float x, float y) {
if ((y > 0.1) && (y < 0.9)) {
if (x < 0.4) {
return 0.0;
}
}
return 0.5;
}
void vertex() {
elapsed_time = TIME;
}
void fragment() {
vec2 uv = UV;
// float alpha = gradient_fct(fract(uv.x*30.0), uv.y);
float alpha = gradient_fct(fract(uv.x*10.0 - elapsed_time*1.5), uv.y);
ALBEDO = color;
ALPHA = alpha;
}

View file

@ -0,0 +1 @@
uid://7b467fbb45fx

View file

@ -0,0 +1,139 @@
[gd_scene load_steps=15 format=3 uid="uid://c7ir0cihwsbdf"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_1yvne"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_6erg5"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/vizpath/common/materials/move.tres" id="3_1vu2e"]
[ext_resource type="Resource" uid="uid://ca6a3fjxcmbhc" path="res://addons/vizpath/resources/viz_head.tres" id="4_g20v5"]
[ext_resource type="ArrayMesh" uid="uid://burem3qbp7oti" path="res://example/vizpath/common/mesh/hex-tile.obj" id="4_kooas"]
[ext_resource type="Resource" uid="uid://dnaxoh1d4t82c" path="res://addons/vizpath/resources/viz_tail.tres" id="5_ty3ba"]
[ext_resource type="ArrayMesh" uid="uid://brfhulgwa6r66" path="res://example/vizpath/common/mesh/piece.obj" id="5_w2ftf"]
[sub_resource type="Resource" id="Resource_qgkxi"]
script = ExtResource("2_6erg5")
point = Vector3(0.12001, 0, 1.24569)
normal = Vector3(0, 1, 0)
[sub_resource type="Resource" id="Resource_s7b42"]
script = ExtResource("2_6erg5")
point = Vector3(1.0056, 0, -0.279287)
normal = Vector3(0, 1, 0)
[sub_resource type="Resource" id="Resource_lfmsk"]
script = ExtResource("2_6erg5")
point = Vector3(0.110618, 0.512924, -1.88396)
normal = Vector3(0, 1, 0)
[sub_resource type="Resource" id="Resource_8kju7"]
script = ExtResource("2_6erg5")
point = Vector3(-1.47883, 0.0551448, -1.76383)
normal = Vector3(0, 1, 0)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tygq4"]
albedo_color = Color(0.678431, 0.486275, 0.27451, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1lbs8"]
albedo_color = Color(0.670588, 0.658824, 0, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4bfck"]
[node name="hex" type="Node3D"]
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(0.992762, -0.0669817, 0.0996872, 0, 0.830033, 0.557714, -0.1201, -0.553677, 0.824025, 1.35237, 2.1656, 3.18067)
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.840718, 0.541473, 0, -0.541473, 0.840718, 0, 2.14547, 0)
[node name="path" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.63023, -0.203269, -1.17328)
script = ExtResource("1_1yvne")
spots = Array[ExtResource("2_6erg5")]([SubResource("Resource_qgkxi"), SubResource("Resource_s7b42"), SubResource("Resource_lfmsk"), SubResource("Resource_8kju7")])
path_width = 0.3
path_mat = ExtResource("3_1vu2e")
path_head = ExtResource("4_g20v5")
path_tail = ExtResource("5_ty3ba")
[node name="map" type="Node3D" parent="."]
[node name="hex1" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.4682, 0)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex2" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.72963, -1.4682, 0)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex3" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.835999, -1.4682, -1.45365)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex4" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.56511, -1.4682, -1.45365)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex5" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.933231, -1.4682, -1.46365)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex6" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0469695, -1.4682, -2.96501)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex7" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.71215, -1.20709, -2.97501)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_tygq4")
[node name="hex8" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.75632, -1.4682, -2.96501)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex9" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.48265, -1.4682, -2.96501)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex10" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.846, -1.4682, -4.47957)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex11" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.59512, -1.4682, -4.50046)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex12" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.903228, -1.33035, -4.49046)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_1lbs8")
[node name="hex13" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0200016, -1.4682, -6.00538)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="hex14" type="MeshInstance3D" parent="map"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.71963, -1.4682, -6.00538)
mesh = ExtResource("4_kooas")
skeleton = NodePath("../..")
[node name="piece1" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1.06485, 0, 0, 0, 1.06485, 1.72758, -0.95635, 0.0769689)
mesh = ExtResource("5_w2ftf")
metadata/_edit_group_ = true
[node name="piece2" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1.06485, 0, 0, 0, 1.06485, -0.0146859, -0.95635, -2.9499)
mesh = ExtResource("5_w2ftf")
surface_material_override/0 = SubResource("StandardMaterial3D_4bfck")
metadata/_edit_group_ = true

View file

@ -0,0 +1,37 @@
[gd_scene load_steps=7 format=3 uid="uid://j7iynhxho7c0"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_61koq"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_8om43"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/common/materials/move.tres" id="3_dlu5u"]
[sub_resource type="Resource" id="Resource_rlmvv"]
script = ExtResource("2_8om43")
point = Vector3(-0.019576, 0.330117, 0.308354)
normal = Vector3(-0.232683, 0, 0.972552)
[sub_resource type="Resource" id="Resource_4ssj4"]
script = ExtResource("2_8om43")
point = Vector3(0.353746, 0.567193, 0.0288121)
normal = Vector3(-0.283569, 0, 0.958952)
[sub_resource type="Resource" id="Resource_wiucl"]
script = ExtResource("2_8om43")
point = Vector3(0.439841, 0.99525, -0.447174)
normal = Vector3(0.0776629, 0.993597, 0.0820541)
[node name="mid_bend" type="Node3D"]
[node name="path2" type="Node3D" parent="."]
transform = Transform3D(0.99644, 0, 0.0843039, 0, 1, 0, -0.0843039, 0, 0.99644, 0.293748, 0, 0)
script = ExtResource("1_61koq")
spots = Array[ExtResource("2_8om43")]([SubResource("Resource_rlmvv"), SubResource("Resource_4ssj4"), SubResource("Resource_wiucl")])
path_width = 0.01
inner_curve_radius = 0.05
bend_sharpness = 0.307
path_mat = ExtResource("3_dlu5u")
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.828627, 0.559801, 0, -0.559801, 0.828627, 0, 1.47828, 1.16019)
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(0.91249, -0.154231, 0.378914, 0, 0.926213, 0.377, -0.4091, -0.344008, 0.84516, 0.951467, 0.854797, 0.660344)

View file

@ -0,0 +1,31 @@
[gd_scene load_steps=6 format=3 uid="uid://dmokry5wki4la"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_tdmdc"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_ed7de"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/common/materials/move.tres" id="3_jou7f"]
[sub_resource type="Resource" id="Resource_lat08"]
script = ExtResource("2_ed7de")
point = Vector3(-0.019576, 0.330117, 0.308354)
normal = Vector3(-0.883153, 0, 0.469085)
[sub_resource type="Resource" id="Resource_aq3dt"]
script = ExtResource("2_ed7de")
point = Vector3(0.492358, 0.739297, 0.295264)
normal = Vector3(0.356353, 0.164684, 0.919724)
[node name="mid_bend" type="Node3D"]
[node name="path2" type="Node3D" parent="."]
transform = Transform3D(0.99644, 0, 0.0843039, 0, 1, 0, -0.0843039, 0, 0.99644, 0.293748, 0, 0)
script = ExtResource("1_tdmdc")
spots = Array[ExtResource("2_ed7de")]([SubResource("Resource_lat08"), SubResource("Resource_aq3dt")])
path_width = 0.05
inner_curve_radius = 0.05
path_mat = ExtResource("3_jou7f")
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.828627, 0.559801, 0, -0.559801, 0.828627, 0, 1.47828, 1.16019)
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(0.91249, -0.154231, 0.378914, 0, 0.926213, 0.377, -0.4091, -0.344008, 0.84516, 0.951467, 0.854797, 0.868185)

View file

@ -0,0 +1,30 @@
[gd_scene load_steps=6 format=3 uid="uid://8d5a3q2jlkpu"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_1isnb"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_hrr5y"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/common/materials/move.tres" id="3_ef85y"]
[sub_resource type="Resource" id="Resource_4ssj4"]
script = ExtResource("2_hrr5y")
point = Vector3(0, 0, 0)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_1jroy"]
script = ExtResource("2_hrr5y")
point = Vector3(-0.424557, 0.5, -0.472062)
normal = Vector3(0, 1, 0)
[node name="one_bend" type="Node3D"]
[node name="path" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.130919, -0.0840064, 0)
script = ExtResource("1_1isnb")
spots = Array[ExtResource("2_hrr5y")]([SubResource("Resource_4ssj4"), SubResource("Resource_1jroy")])
bend_segs = 8
path_mat = ExtResource("3_ef85y")
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.828627, 0.559801, 0, -0.559801, 0.828627, 0, 1.47828, 1.16019)
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(0.84005, 0.364052, -0.402221, 0, 0.741409, 0.671053, 0.542508, -0.563718, 0.622821, -0.44569, 0.886962, 0.464843)

View file

@ -0,0 +1,29 @@
[gd_scene load_steps=6 format=3 uid="uid://dwirjkvwkv75u"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_heaqv"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_flef7"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/common/materials/move.tres" id="3_fyvtr"]
[sub_resource type="Resource" id="Resource_o651y"]
script = ExtResource("2_flef7")
point = Vector3(0.359788, 0.518665, -0.0131293)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_4ssj4"]
script = ExtResource("2_flef7")
point = Vector3(-0.288032, 0.444831, -0.170361)
normal = Vector3(0, 0, 1)
[node name="straight" type="Node3D"]
[node name="path" type="Node3D" parent="."]
script = ExtResource("1_heaqv")
spots = Array[ExtResource("2_flef7")]([SubResource("Resource_o651y"), SubResource("Resource_4ssj4")])
bend_lip = 0.05
path_mat = ExtResource("3_fyvtr")
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.828627, 0.559801, 0, -0.559801, 0.828627, 0, 1.47828, 1.16019)
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(0.631322, 0.489607, -0.60143, 0, 0.775517, 0.631326, 0.775521, -0.39857, 0.489601, -0.535581, 0.968096, 0.314222)

View file

@ -0,0 +1,37 @@
[gd_scene load_steps=7 format=3 uid="uid://3tjj6ldef4lo"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_2jxs7"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_dhnds"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/common/materials/move.tres" id="3_cjil2"]
[sub_resource type="Resource" id="Resource_o651y"]
script = ExtResource("2_dhnds")
point = Vector3(0.182239, 0.0924503, 0)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_2clix"]
script = ExtResource("2_dhnds")
point = Vector3(-0.0228493, 0.395443, 0)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_bwwrl"]
script = ExtResource("2_dhnds")
point = Vector3(0.90799, 0.724231, 0)
normal = Vector3(0, 0, 1)
[node name="three_points" type="Node3D"]
[node name="path" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.778687, -0.65607, 0)
script = ExtResource("1_2jxs7")
spots = Array[ExtResource("2_dhnds")]([SubResource("Resource_o651y"), SubResource("Resource_2clix"), SubResource("Resource_bwwrl")])
path_width = 0.05
num_curve_segs = 60
bend_segs = 10
path_mat = ExtResource("3_cjil2")
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.828627, 0.559801, 0, -0.559801, 0.828627, 0, 1.47828, 1.16019)
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.24272)

View file

@ -0,0 +1,10 @@
extends Node3D
# Called when the node enters the scene tree for the first time.
func _ready():
pass
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
pass

View file

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

View file

@ -0,0 +1,62 @@
[gd_scene load_steps=12 format=3 uid="uid://c55gugehr1r3q"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_3gjiw"]
[ext_resource type="Script" path="res://example/two_bend/two_bend.gd" id="1_avpar"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_xhjfb"]
[ext_resource type="Material" uid="uid://bb6vecpbvsco2" path="res://example/vizpath/common/materials/green.tres" id="4_dnqvd"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/vizpath/common/materials/move.tres" id="5_cr2c7"]
[sub_resource type="Resource" id="Resource_m5l7s"]
script = ExtResource("2_xhjfb")
point = Vector3(0.576658, 0.1, 0.050687)
normal = Vector3(1, 0, 0)
[sub_resource type="Resource" id="Resource_swer1"]
script = ExtResource("2_xhjfb")
point = Vector3(-0.3, 0.507225, 0)
normal = Vector3(0, 1, 0)
[sub_resource type="Resource" id="Resource_u3fio"]
script = ExtResource("2_xhjfb")
point = Vector3(-0.3, 0.1, 0.3)
normal = Vector3(0, 0, 1)
[sub_resource type="Resource" id="Resource_h2nq6"]
script = ExtResource("2_xhjfb")
point = Vector3(-0.0696068, 0.591908, 0)
normal = Vector3(0, 1, 0)
[sub_resource type="Resource" id="Resource_cl30b"]
script = ExtResource("2_xhjfb")
point = Vector3(-0.492063, 0.105, -0.892321)
normal = Vector3(0, 0, -1)
[sub_resource type="Resource" id="Resource_eg1h8"]
script = ExtResource("2_xhjfb")
point = Vector3(0.557, 0.369389, -0.617691)
normal = Vector3(0.988393, 0, 0.151917)
[node name="two_bend" type="Node3D"]
script = ExtResource("1_avpar")
[node name="path1" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.125237)
script = ExtResource("1_3gjiw")
spots = Array[ExtResource("2_xhjfb")]([SubResource("Resource_m5l7s"), SubResource("Resource_swer1"), SubResource("Resource_u3fio")])
path_width = 0.05
path_mat = ExtResource("4_dnqvd")
[node name="path2" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.0673205)
script = ExtResource("1_3gjiw")
spots = Array[ExtResource("2_xhjfb")]([SubResource("Resource_m5l7s"), SubResource("Resource_h2nq6"), SubResource("Resource_cl30b"), SubResource("Resource_eg1h8")])
inner_curve_radius = 0.05
bend_segs = 8
bend_lip = 0.05
path_mat = ExtResource("5_cr2c7")
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.828627, 0.559801, 0, -0.559801, 0.828627, 0, 1.47828, 1.16019)
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.948013, 0.318231, 0, -0.318231, 0.948013, -0.143137, 0.97094, 1.10501)

View file

@ -0,0 +1,41 @@
[gd_scene load_steps=9 format=3 uid="uid://lya0l1b74f08"]
[ext_resource type="Script" path="res://addons/vizpath/visualized_path.gd" id="1_2ehhl"]
[ext_resource type="Script" path="res://addons/vizpath/resources/spot.gd" id="2_7kv0e"]
[ext_resource type="Material" uid="uid://c4qytbc7juuoa" path="res://example/vizpath/common/materials/move.tres" id="3_pq303"]
[ext_resource type="Resource" uid="uid://ca6a3fjxcmbhc" path="res://addons/vizpath/resources/viz_head.tres" id="4_exeba"]
[ext_resource type="Resource" uid="uid://dnaxoh1d4t82c" path="res://addons/vizpath/resources/viz_tail.tres" id="5_76glu"]
[sub_resource type="Resource" id="Resource_o651y"]
script = ExtResource("2_7kv0e")
point = Vector3(0, 0.114297, -0.0441982)
normal = Vector3(0, 0, -1)
[sub_resource type="Resource" id="Resource_2clix"]
script = ExtResource("2_7kv0e")
point = Vector3(-0.346671, 0.276115, 0.160896)
normal = Vector3(-1, 0, 0)
[sub_resource type="Resource" id="Resource_rwwtj"]
script = ExtResource("2_7kv0e")
point = Vector3(-0.140459, 0.608702, 0.100734)
normal = Vector3(0, 1, 0)
[node name="two_points" type="Node3D"]
[node name="path" type="Node3D" parent="."]
transform = Transform3D(-0.992377, 0, -0.123238, 0, 1, 0, 0.123238, 0, -0.992377, 0, 0, 0)
script = ExtResource("1_2ehhl")
spots = Array[ExtResource("2_7kv0e")]([SubResource("Resource_o651y"), SubResource("Resource_2clix"), SubResource("Resource_rwwtj")])
path_width = 0.05
inner_curve_radius = 0.01
bend_lip = 0.05
path_mat = ExtResource("3_pq303")
path_head = ExtResource("4_exeba")
path_tail = ExtResource("5_76glu")
[node name="light" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.828627, 0.559801, 0, -0.559801, 0.828627, 0, 1.47828, 1.16019)
[node name="camera" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.24272)

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

34
icon.png.import Normal file
View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c0wdd27awcglc"
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.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

View file

@ -91,6 +91,6 @@ layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 4
[connection signal="pressed" from="MarginContainer/VBoxContainer/ResumeButton" to="." method="_on_resume_button_pressed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ResumeButton" to="." method="_on_button_pressed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ResumeButton" to="." method="_on_resume_button_pressed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ExitButton" to="." method="_on_exit_button_pressed"]

81
show_spectrum.gd Normal file
View file

@ -0,0 +1,81 @@
extends Node2D
const VU_COUNT = 16
const FREQ_MAX = 11050.0
const WIDTH = 800
const HEIGHT = 250
const HEIGHT_SCALE = 8.0
const MIN_DB = 60
const ANIMATION_SPEED = 0.1
var spectrum
var min_values = []
var max_values = []
func _draw():
var w = WIDTH / VU_COUNT
for i in range(VU_COUNT):
var min_height = min_values[i]
var max_height = max_values[i]
var height = lerp(min_height, max_height, ANIMATION_SPEED)
draw_rect(
Rect2(w * i, HEIGHT - height, w - 2, height),
Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 0.6)
)
draw_line(
Vector2(w * i, HEIGHT - height),
Vector2(w * i + w - 2, HEIGHT - height),
Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 1.0),
2.0,
true
)
# Draw a reflection of the bars with lower opacity.
draw_rect(
Rect2(w * i, HEIGHT, w - 2, height),
Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 0.6) * Color(1, 1, 1, 0.125)
)
draw_line(
Vector2(w * i, HEIGHT + height),
Vector2(w * i + w - 2, HEIGHT + height),
Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 1.0) * Color(1, 1, 1, 0.125),
2.0,
true
)
func _process(_delta):
var data = []
var prev_hz = 0
for i in range(1, VU_COUNT + 1):
var hz = i * FREQ_MAX / VU_COUNT
var magnitude = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length()
var energy = clampf((MIN_DB + linear_to_db(magnitude)) / MIN_DB, 0, 1)
var height = energy * HEIGHT * HEIGHT_SCALE
data.append(height)
prev_hz = hz
for i in range(VU_COUNT):
if data[i] > max_values[i]:
max_values[i] = data[i]
else:
max_values[i] = lerp(max_values[i], data[i], ANIMATION_SPEED)
if data[i] <= 0.0:
min_values[i] = lerp(min_values[i], 0.0, ANIMATION_SPEED)
# Sound plays back continuously, so the graph needs to be updated every frame.
queue_redraw()
func _ready():
spectrum = AudioServer.get_bus_effect_instance(0, 0)
min_values.resize(VU_COUNT)
max_values.resize(VU_COUNT)
min_values.fill(0.0)
max_values.fill(0.0)

1
show_spectrum.gd.uid Normal file
View file

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

14
show_spectrum.tscn Normal file
View file

@ -0,0 +1,14 @@
[gd_scene load_steps=2 format=3 uid="uid://dsit517glos2s"]
[ext_resource type="Script" uid="uid://x3hrdg2smx4f" path="res://show_spectrum.gd" id="1"]
[node name="ShowSpectrum" type="Node2D"]
position = Vector2(136, 80)
script = ExtResource("1")
[node name="Player" type="AudioStreamPlayer" parent="."]
autoplay = true
[node name="Camera2D" type="Camera2D" parent="."]
position = Vector2(0, 144)
offset = Vector2(440, 100)

1
source/vizpath/.gdignore Normal file
View file

@ -0,0 +1 @@
icon.svg

1
source/vizpath/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.blend[0-9]

Binary file not shown.

Binary file not shown.

47
source/vizpath/icon.svg Normal file
View file

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="icon.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.69664703"
inkscape:cx="109.09398"
inkscape:cy="445.70635"
inkscape:window-width="2492"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#0000d9;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="m 30.753041,132.21182 c 0,0 10.010254,-15.2619 18.023962,-22.0133 8.013709,-6.7514 22.573376,-7.54391 30.155161,1.21654 7.581785,8.76044 6.189859,17.90833 18.236116,19.42593 9.9617,1.25499 21.88274,-11.14017 21.88274,-11.14017 l -5.48923,-7.62409 19.34583,2.49538 -4.21336,17.76136 -4.3721,-6.47877 c 0,0 -13.47411,13.05178 -27.817042,12.90117 -14.342932,-0.1506 -17.860759,-14.58992 -22.628979,-21.50294 -4.76822,-6.91302 -14.511224,-5.45497 -19.83986,0.35161 -5.328637,5.80657 -16.145755,19.59209 -16.145755,19.59209 z"
id="path42"
sodipodi:nodetypes="czzsccccczzzcc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
source/vizpath/ladder.blend Normal file

Binary file not shown.

View file

@ -0,0 +1,2 @@
# Blender 3.5.0 MTL File: 'ladder.blend'
# www.blender.org

1345
source/vizpath/ladder.obj Normal file

File diff suppressed because it is too large Load diff

BIN
source/vizpath/piece.blend Normal file

Binary file not shown.

2
source/vizpath/piece.mtl Normal file
View file

@ -0,0 +1,2 @@
# Blender 3.5.0 MTL File: 'ladder.blend'
# www.blender.org

2547
source/vizpath/piece.obj Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

BIN
source/vizpath/spot.blend Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

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