├── .gitignore ├── favicon.ico ├── favicon.png ├── font └── Roboto-Regular.ttf ├── FunscriptSimulator3D.csproj ├── default_env.tres ├── README.md ├── InputListener.gd ├── favicon.png.import ├── LineDrawer.gd ├── project.godot ├── FunscriptSimulator3D.sln ├── BorderlessWindow.cs ├── export_presets.cfg ├── Funscript.cs ├── ResizeHandle.cs ├── Main.tscn ├── Simulator3D.cs └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .mono 3 | .vscode 4 | export_presets.cfg 5 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZestyRaraferu/OFS_Simulator3D/HEAD/favicon.ico -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZestyRaraferu/OFS_Simulator3D/HEAD/favicon.png -------------------------------------------------------------------------------- /font/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZestyRaraferu/OFS_Simulator3D/HEAD/font/Roboto-Regular.ttf -------------------------------------------------------------------------------- /FunscriptSimulator3D.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net472 4 | 5 | -------------------------------------------------------------------------------- /default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | 5 | [resource] 6 | background_mode = 2 7 | background_sky = SubResource( 1 ) 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A Fork of OpenFunScripter's OFS_Simulator3D that fixes some issues. 2 | 3 | 4 | 5 | # OFS_Simulator3D 6 | A 3D simulator for OFS made in godot. 7 | 8 | This project uses godot 3.5.3 with C# mono support. 9 | -------------------------------------------------------------------------------- /InputListener.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | onready var line_drawer = $"../LineDrawer" 3 | onready var distance_label = $"../UI/DistanceLabel" 4 | onready var tongue = $"../Stroker/Tongue" 5 | onready var stroker = $"../Stroker" 6 | 7 | 8 | func _input(event): 9 | if event is InputEventKey and event.pressed and event.scancode == KEY_L: 10 | line_drawer.visible = not line_drawer.visible 11 | if event is InputEventKey and event.pressed and event.scancode == KEY_D: 12 | distance_label.visible = not distance_label.visible 13 | if event is InputEventKey and event.pressed and event.scancode == KEY_T: 14 | tongue.visible = not tongue.visible 15 | -------------------------------------------------------------------------------- /favicon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/favicon.png-05a5f25b7b35b567a640a7daf7751a8e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://favicon.png" 13 | dest_files=[ "res://.import/favicon.png-05a5f25b7b35b567a640a7daf7751a8e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /LineDrawer.gd: -------------------------------------------------------------------------------- 1 | extends ImmediateGeometry 2 | 3 | onready var target_position = Vector3(0, -1.875, 0) 4 | onready var start_position_node = $"../Stroker/Top" 5 | onready var distance_label = $"../UI/DistanceLabel" 6 | 7 | func _process(_delta): 8 | clear() 9 | begin(Mesh.PRIMITIVE_LINES, null) 10 | add_vertex(start_position_node.global_transform.origin) 11 | add_vertex(target_position) 12 | end() 13 | 14 | var distance = start_position_node.global_transform.origin.distance_to(target_position) 15 | var percentage = (distance / 2.0) * 100 16 | distance_label.text = "%.0f%%" % percentage 17 | 18 | var fraction = max(min((distance - 1.8) / (2.0 - 1.8), 1.0), 0.0) 19 | 20 | if percentage > 100: 21 | material_override.albedo_color = Color.fuchsia 22 | distance_label.modulate = Color.purple 23 | else: 24 | var base_color = Color(3, 3, 3) 25 | var target_color = Color.hotpink 26 | var color = base_color.linear_interpolate(target_color, fraction) 27 | distance_label.modulate = color 28 | material_override.albedo_color = color 29 | 30 | -------------------------------------------------------------------------------- /project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | [application] 12 | 13 | config/name="FunscriptSimulator3D" 14 | run/main_scene="res://Main.tscn" 15 | boot_splash/show_image=false 16 | config/icon="res://favicon.png" 17 | 18 | [display] 19 | 20 | window/size/width=400 21 | window/per_pixel_transparency/allowed=true 22 | window/per_pixel_transparency/enabled=true 23 | 24 | [global] 25 | 26 | verbose=false 27 | renderer=false 28 | 29 | [gui] 30 | 31 | common/drop_mouse_on_gui_input_disabled=true 32 | 33 | [mono] 34 | 35 | project/assembly_name="FunscriptSimulator3D" 36 | 37 | [network] 38 | 39 | limits/websocket_client/max_in_buffer_kb=1048576 40 | 41 | [physics] 42 | 43 | common/enable_pause_aware_picking=true 44 | 45 | [rendering] 46 | 47 | quality/filters/msaa=2 48 | environment/default_environment="res://default_env.tres" 49 | -------------------------------------------------------------------------------- /FunscriptSimulator3D.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2012 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunscriptSimulator3D", "FunscriptSimulator3D.csproj", "{901E817B-A86E-438D-8E46-4B68AC2BD454}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Any CPU = Debug|Any CPU 8 | ExportDebug|Any CPU = ExportDebug|Any CPU 9 | ExportRelease|Any CPU = ExportRelease|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {901E817B-A86E-438D-8E46-4B68AC2BD454}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {901E817B-A86E-438D-8E46-4B68AC2BD454}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {901E817B-A86E-438D-8E46-4B68AC2BD454}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU 15 | {901E817B-A86E-438D-8E46-4B68AC2BD454}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU 16 | {901E817B-A86E-438D-8E46-4B68AC2BD454}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU 17 | {901E817B-A86E-438D-8E46-4B68AC2BD454}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /BorderlessWindow.cs: -------------------------------------------------------------------------------- 1 | using Godot; 2 | using System; 3 | 4 | public class BorderlessWindow : Control 5 | { 6 | private ResizeHandle topBar; 7 | private ResizeHandle bottomBar; 8 | private ResizeHandle leftBar; 9 | private ResizeHandle rightBar; 10 | 11 | private Vector2 windowTranslationOffset = Vector2.Zero; 12 | private bool isMovingWindow = false; 13 | 14 | 15 | public override void _Ready() 16 | { 17 | GetTree().Root.TransparentBg = true; 18 | OS.WindowBorderless = true; 19 | OS.SetWindowAlwaysOnTop(true); 20 | 21 | topBar = GetNode("TopHandle"); 22 | bottomBar = GetNode("BottomHandle"); 23 | leftBar = GetNode("LeftHandle"); 24 | rightBar = GetNode("RightHandle"); 25 | 26 | MouseDefaultCursorShape = CursorShape.Move; 27 | } 28 | 29 | public override void _GuiInput(InputEvent ev) 30 | { 31 | if(ev is InputEventMouseButton button) 32 | { 33 | if(button.ButtonIndex == (int)ButtonList.Left) 34 | { 35 | if(button.Pressed && !isMovingWindow) 36 | { 37 | isMovingWindow = true; 38 | windowTranslationOffset = GetLocalMousePosition(); 39 | } 40 | else 41 | { 42 | isMovingWindow = false; 43 | } 44 | } 45 | } 46 | } 47 | 48 | public override void _Process(float delta) 49 | { 50 | if(isMovingWindow) 51 | { 52 | OS.WindowPosition = OS.WindowPosition + GetGlobalMousePosition() - windowTranslationOffset; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /export_presets.cfg: -------------------------------------------------------------------------------- 1 | [preset.0] 2 | 3 | name="Windows Desktop" 4 | platform="Windows Desktop" 5 | runnable=true 6 | custom_features="" 7 | export_filter="all_resources" 8 | include_filter="" 9 | exclude_filter="" 10 | export_path="../Export/OFS3D/win/FunscriptSimulator3D.exe" 11 | script_export_mode=1 12 | script_encryption_key="" 13 | 14 | [preset.0.options] 15 | 16 | custom_template/debug="" 17 | custom_template/release="" 18 | binary_format/64_bits=true 19 | binary_format/embed_pck=true 20 | texture_format/bptc=false 21 | texture_format/s3tc=true 22 | texture_format/etc=false 23 | texture_format/etc2=false 24 | texture_format/no_bptc_fallbacks=true 25 | codesign/enable=false 26 | codesign/identity_type=0 27 | codesign/identity="" 28 | codesign/password="" 29 | codesign/timestamp=true 30 | codesign/timestamp_server_url="" 31 | codesign/digest_algorithm=1 32 | codesign/description="" 33 | codesign/custom_options=PoolStringArray( ) 34 | application/modify_resources=true 35 | application/icon="res://favicon.ico" 36 | application/file_version="" 37 | application/product_version="" 38 | application/company_name="" 39 | application/product_name="" 40 | application/file_description="" 41 | application/copyright="" 42 | application/trademarks="" 43 | 44 | [preset.1] 45 | 46 | name="Linux/X11" 47 | platform="Linux/X11" 48 | runnable=true 49 | custom_features="" 50 | export_filter="all_resources" 51 | include_filter="" 52 | exclude_filter="" 53 | export_path="../Export/OFS3D/linux/FunscriptSimulator3D.x86_64" 54 | script_export_mode=1 55 | script_encryption_key="" 56 | 57 | [preset.1.options] 58 | 59 | custom_template/debug="" 60 | custom_template/release="" 61 | binary_format/64_bits=true 62 | binary_format/embed_pck=true 63 | texture_format/bptc=false 64 | texture_format/s3tc=true 65 | texture_format/etc=false 66 | texture_format/etc2=false 67 | texture_format/no_bptc_fallbacks=true 68 | -------------------------------------------------------------------------------- /Funscript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Godot; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | public enum ScriptType 7 | { 8 | MainStroke, 9 | Sway, 10 | Surge, 11 | Roll, 12 | Pitch, 13 | Twist, 14 | TypeCount 15 | } 16 | 17 | public struct Action 18 | { 19 | public float timestamp; 20 | public float pos; 21 | } 22 | 23 | public class Funscript 24 | { 25 | public string Name { get; private set; } 26 | public List Actions = new List(); 27 | 28 | public Funscript(Godot.Collections.Dictionary changeEvent) 29 | { 30 | Name = changeEvent["name"] as string; 31 | UpdateFromEvent(changeEvent); 32 | } 33 | 34 | public void UpdateFromEvent(Godot.Collections.Dictionary changeEvent) 35 | { 36 | Actions.Clear(); 37 | var script = changeEvent["funscript"] as Godot.Collections.Dictionary; 38 | var actions = script["actions"] as Godot.Collections.Array; 39 | foreach(Godot.Collections.Dictionary action in actions) 40 | { 41 | Actions.Add(new Action() { 42 | timestamp = (action["at"] as float? ?? 0.0f) / 1000.0f, 43 | pos = action["pos"] as float? / 100.0f ?? 0.0f 44 | }); 45 | } 46 | } 47 | 48 | public float GetPositionAt(float time) 49 | { 50 | var idx = Actions.BinarySearch(0, Actions.Count, new Action() 51 | { 52 | timestamp = time, 53 | pos = 0 54 | }, Comparer.Create((a,b) => Comparer.Default.Compare(a.timestamp, b.timestamp))); 55 | 56 | if(idx < 0) 57 | { 58 | idx = ~idx; 59 | if(idx - 1 >= 0 && idx < Actions.Count) 60 | { 61 | var current = Actions[idx-1]; 62 | var next = Actions[idx]; 63 | 64 | float t = (time - current.timestamp) / (next.timestamp - current.timestamp); 65 | return Mathf.Lerp(current.pos, next.pos, t); 66 | } 67 | else if(Actions.Count > 0) 68 | { 69 | return Actions.Last().pos; 70 | } 71 | } 72 | else 73 | { 74 | return Actions[idx].pos; 75 | } 76 | 77 | return 0.5f; 78 | } 79 | } -------------------------------------------------------------------------------- /ResizeHandle.cs: -------------------------------------------------------------------------------- 1 | using Godot; 2 | using System; 3 | 4 | public enum ResizeHandleType 5 | { 6 | Top, 7 | Bottom, 8 | Left, 9 | Right 10 | } 11 | 12 | public class ResizeHandle : Control 13 | { 14 | [Export] 15 | private ResizeHandleType handleType; 16 | private bool isResizing = false; 17 | private Vector2 resizePos = Vector2.Zero; 18 | private Vector2 startSize = Vector2.Zero; 19 | 20 | public override void _Ready() 21 | { 22 | switch(handleType) 23 | { 24 | case ResizeHandleType.Top: 25 | case ResizeHandleType.Bottom: 26 | MouseDefaultCursorShape = CursorShape.Vsize; 27 | break; 28 | case ResizeHandleType.Left: 29 | case ResizeHandleType.Right: 30 | MouseDefaultCursorShape = CursorShape.Hsize; 31 | break; 32 | } 33 | } 34 | 35 | public override void _GuiInput(InputEvent ev) 36 | { 37 | if(ev is InputEventMouseButton button) 38 | { 39 | if(button.ButtonIndex == (int)ButtonList.Left) 40 | { 41 | if(button.Pressed && !isResizing) { 42 | isResizing = true; 43 | startSize = OS.WindowSize; 44 | resizePos = GetGlobalMousePosition(); 45 | } 46 | else 47 | isResizing = false; 48 | } 49 | } 50 | } 51 | 52 | public override void _Process(float delta) 53 | { 54 | if(isResizing) 55 | { 56 | var mousePos = GetGlobalMousePosition(); 57 | switch(handleType) 58 | { 59 | case ResizeHandleType.Top: 60 | { 61 | var newPos = OS.WindowPosition + mousePos - resizePos; 62 | newPos.x = OS.WindowPosition.x; 63 | var deltaPos = OS.WindowPosition - newPos; 64 | startSize += new Vector2(0.0f, deltaPos.y); 65 | OS.WindowPosition = newPos; 66 | OS.WindowSize = startSize; 67 | break; 68 | } 69 | case ResizeHandleType.Bottom: 70 | OS.WindowSize = startSize + new Vector2(0.0f, mousePos.y - resizePos.y); 71 | break; 72 | case ResizeHandleType.Left: 73 | { 74 | var newPos = OS.WindowPosition + mousePos - resizePos; 75 | newPos.y = OS.WindowPosition.y; 76 | var deltaPos = OS.WindowPosition - newPos; 77 | startSize += new Vector2(deltaPos.x, 0.0f); 78 | OS.WindowPosition = newPos; 79 | OS.WindowSize = startSize; 80 | break; 81 | } 82 | case ResizeHandleType.Right: 83 | OS.WindowSize = startSize + new Vector2(mousePos.x - resizePos.x, 0.0f); 84 | break; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=17 format=2] 2 | 3 | [ext_resource path="res://Simulator3D.cs" type="Script" id=1] 4 | [ext_resource path="res://BorderlessWindow.cs" type="Script" id=2] 5 | [ext_resource path="res://ResizeHandle.cs" type="Script" id=3] 6 | [ext_resource path="res://LineDrawer.gd" type="Script" id=4] 7 | [ext_resource path="res://InputListener.gd" type="Script" id=6] 8 | 9 | [sub_resource type="SpatialMaterial" id=8] 10 | 11 | [sub_resource type="CylinderMesh" id=5] 12 | top_radius = 0.5 13 | bottom_radius = 0.5 14 | height = 1.75 15 | radial_segments = 32 16 | 17 | [sub_resource type="SpatialMaterial" id=6] 18 | vertex_color_use_as_albedo = true 19 | proximity_fade_enable = true 20 | proximity_fade_distance = 0.8 21 | 22 | [sub_resource type="CubeMesh" id=3] 23 | size = Vector3( 0.25, 0.25, 0.25 ) 24 | 25 | [sub_resource type="SpatialMaterial" id=4] 26 | vertex_color_use_as_albedo = true 27 | albedo_color = Color( 1, 0, 0, 1 ) 28 | 29 | [sub_resource type="SpatialMaterial" id=7] 30 | albedo_color = Color( 0.505882, 0.121569, 0.85098, 1 ) 31 | 32 | [sub_resource type="CapsuleMesh" id=10] 33 | radius = 0.5 34 | radial_segments = 32 35 | rings = 4 36 | 37 | [sub_resource type="SpatialMaterial" id=11] 38 | flags_use_point_size = true 39 | albedo_color = Color( 1, 0.380392, 0.380392, 1 ) 40 | 41 | [sub_resource type="Environment" id=2] 42 | ambient_light_color = Color( 1, 1, 1, 1 ) 43 | ambient_light_energy = 0.05 44 | 45 | [sub_resource type="DynamicFontData" id=13] 46 | font_path = "res://font/Roboto-Regular.ttf" 47 | 48 | [sub_resource type="DynamicFont" id=12] 49 | outline_size = 1 50 | outline_color = Color( 0, 0, 0, 0.486275 ) 51 | use_filter = true 52 | font_data = SubResource( 13 ) 53 | 54 | [node name="Root" type="Spatial"] 55 | script = ExtResource( 1 ) 56 | 57 | [node name="LineDrawer" type="ImmediateGeometry" parent="."] 58 | visible = false 59 | material_override = SubResource( 8 ) 60 | cast_shadow = 0 61 | script = ExtResource( 4 ) 62 | 63 | [node name="Stroker" type="MeshInstance" parent="."] 64 | mesh = SubResource( 5 ) 65 | material/0 = SubResource( 6 ) 66 | 67 | [node name="Twist1" type="MeshInstance" parent="Stroker"] 68 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0, 0 ) 69 | mesh = SubResource( 3 ) 70 | material/0 = SubResource( 4 ) 71 | 72 | [node name="Twist2" type="MeshInstance" parent="Stroker"] 73 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0 ) 74 | mesh = SubResource( 3 ) 75 | skeleton = NodePath("../Twist1") 76 | material/0 = SubResource( 7 ) 77 | 78 | [node name="Top" type="Position3D" parent="Stroker"] 79 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.875, 0 ) 80 | 81 | [node name="Tongue" type="MeshInstance" parent="Stroker"] 82 | transform = Transform( 0.689567, 0, 0, 0, -2.42681e-08, 0.555189, 0, -0.310956, -1.35923e-08, 0, -0.673036, -0.295351 ) 83 | visible = false 84 | mesh = SubResource( 10 ) 85 | material/0 = SubResource( 11 ) 86 | 87 | [node name="Camera" type="Camera" parent="."] 88 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3.25 ) 89 | size = 5.0 90 | far = 50.0 91 | 92 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."] 93 | environment = SubResource( 2 ) 94 | 95 | [node name="DirectionalLight" type="DirectionalLight" parent="."] 96 | transform = Transform( 0.866025, 0.353553, -0.353554, 0, 0.707107, 0.707106, 0.5, -0.612372, 0.612373, 0, 4, 0 ) 97 | 98 | [node name="UI" type="Control" parent="."] 99 | anchor_right = 1.0 100 | anchor_bottom = 1.0 101 | rect_min_size = Vector2( 0, 40 ) 102 | script = ExtResource( 2 ) 103 | 104 | [node name="DistanceLabel" type="Label" parent="UI"] 105 | visible = false 106 | anchor_left = 0.5 107 | anchor_top = 1.0 108 | anchor_right = 0.5 109 | anchor_bottom = 1.0 110 | margin_left = -23.0 111 | margin_top = -22.0 112 | margin_right = 17.0 113 | margin_bottom = 5.0 114 | custom_fonts/font = SubResource( 12 ) 115 | align = 2 116 | 117 | [node name="Label" type="Label" parent="UI"] 118 | margin_right = 40.0 119 | margin_bottom = 14.0 120 | text = "Connecting..." 121 | 122 | [node name="TopHandle" type="Control" parent="UI"] 123 | anchor_right = 1.0 124 | margin_bottom = 25.0 125 | rect_min_size = Vector2( 0, 20 ) 126 | rect_pivot_offset = Vector2( -1026, 164 ) 127 | script = ExtResource( 3 ) 128 | 129 | [node name="ColorRect" type="ColorRect" parent="UI/TopHandle"] 130 | anchor_right = 1.0 131 | rect_min_size = Vector2( 0, 1 ) 132 | color = Color( 1, 0, 0, 0.0980392 ) 133 | 134 | [node name="BottomHandle" type="Control" parent="UI"] 135 | anchor_top = 1.0 136 | anchor_right = 1.0 137 | anchor_bottom = 1.0 138 | margin_top = -25.0 139 | script = ExtResource( 3 ) 140 | handleType = 1 141 | 142 | [node name="ColorRect" type="ColorRect" parent="UI/BottomHandle"] 143 | anchor_top = 1.0 144 | anchor_right = 1.0 145 | anchor_bottom = 1.0 146 | margin_top = -1.0 147 | color = Color( 1, 0, 0, 0.0980392 ) 148 | 149 | [node name="LeftHandle" type="Control" parent="UI"] 150 | anchor_bottom = 1.0 151 | margin_right = 25.0 152 | script = ExtResource( 3 ) 153 | handleType = 2 154 | 155 | [node name="ColorRect" type="ColorRect" parent="UI/LeftHandle"] 156 | anchor_bottom = 1.0 157 | margin_right = 1.0 158 | color = Color( 1, 0, 0, 0.0980392 ) 159 | 160 | [node name="RightHandle" type="Control" parent="UI"] 161 | anchor_left = 1.0 162 | anchor_right = 1.0 163 | anchor_bottom = 1.0 164 | margin_left = -25.0 165 | script = ExtResource( 3 ) 166 | handleType = 3 167 | 168 | [node name="ColorRect" type="ColorRect" parent="UI/RightHandle"] 169 | anchor_left = 1.0 170 | anchor_right = 1.0 171 | anchor_bottom = 1.0 172 | margin_left = -1.0 173 | color = Color( 1, 0, 0, 0.0980392 ) 174 | 175 | [node name="InputListener" type="Node" parent="."] 176 | script = ExtResource( 6 ) 177 | -------------------------------------------------------------------------------- /Simulator3D.cs: -------------------------------------------------------------------------------- 1 | using Godot; 2 | using System; 3 | using System.Text; 4 | using System.Linq; 5 | 6 | public class Simulator3D : Spatial 7 | { 8 | [Export] 9 | private string WsSocketUrl = "ws://127.0.0.1:8080/ofs"; 10 | 11 | private WebSocketClient webSocketClient; 12 | public bool ClientConnected { get; private set; } = false; 13 | 14 | public float CurrentTime { get; private set; } = 0.0f; 15 | public bool IsPlaying { get; private set; } = false; 16 | public float PlaybackSpeed { get; private set; } = 1.0f; 17 | 18 | private Label label; 19 | private MeshInstance strokerMesh; 20 | private Funscript[] scripts = new Funscript[(int)ScriptType.TypeCount]; 21 | 22 | public override void _Ready() 23 | { 24 | var args = OS.GetCmdlineArgs(); 25 | if(args.Length > 0) 26 | { 27 | WsSocketUrl = args[0]; 28 | } 29 | 30 | label = GetNode