diff --git a/README.md b/README.md index 68a0026..4f9fa65 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # braille_xr refreshable braille display for rendering and input with handtracking -**[ disclaimer ]** +**[ disclaimer ]** + this early repo may require special help/information depending on your setup and prior knowledge - so do not hesitate to reach out to [@spatialfree](https://x.com/spatialfree) with any questions! ## init @@ -32,10 +33,13 @@ sudo chmod 666 /dev/ttyUSB0 - ... ## <3 -[Bryan Chris Brown](https://twitter.com/BryanChrisBrown) -[StereoNick](https://twitter.com/koujaku) -[Peter Sassaman](https://twitter.com/PeterSassaman) -[Lucas De Bonet (LucidVR)](https://twitter.com/VrLucid) +[Bryan Chris Brown](https://twitter.com/BryanChrisBrown) + +[StereoNick](https://twitter.com/koujaku) + +[Peter Sassaman](https://twitter.com/PeterSassaman) + +[Lucas De Bonet (LucidVR)](https://twitter.com/VrLucid) ### WIP hot glue bump tutorial diff --git a/sk_demo/braille_xr.csproj b/sk_demo/braille_xr.csproj index bf07b5d..3646dca 100644 --- a/sk_demo/braille_xr.csproj +++ b/sk_demo/braille_xr.csproj @@ -5,7 +5,7 @@ net8 enable enable - + res res @@ -14,7 +14,7 @@ - + PreserveNewest diff --git a/sk_demo/src/Mat.cs b/sk_demo/src/Mat.cs index d08a2eb..3413f59 100644 --- a/sk_demo/src/Mat.cs +++ b/sk_demo/src/Mat.cs @@ -2,58 +2,65 @@ namespace Main; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] -struct oriel_data { - public Matrix m4; - public Matrix m4_inv; - public Vec3 size; - public float pad; // padding (16 byte alignment) +struct oriel_data +{ + public Matrix m4; + public Matrix m4_inv; + public Vec3 size; + public float pad; // padding (16 byte alignment) } [StructLayout(LayoutKind.Sequential)] -unsafe struct oriel_buffer { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 455)] // 455 *see dofdev.hlsli - public oriel_data[] oriels; +unsafe struct oriel_buffer +{ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 455)] // 455 *see dofdev.hlsli + public oriel_data[] oriels; } -public class Mat { - MaterialBuffer buffer = new (3); - oriel_buffer data = new (); - public void SetOriel(int id, Matrix m4, Vec3 size) { - data.oriels[id].m4 = (Matrix)System.Numerics.Matrix4x4.Transpose( - m4.Inverse - ); - data.oriels[id].m4_inv = (Matrix)System.Numerics.Matrix4x4.Transpose( - m4 - ); - data.oriels[id].size = size; - buffer.Set(data); - } +public class Mat +{ + MaterialBuffer buffer = new(3); + oriel_buffer data = new(); + public void SetOriel(int id, Matrix m4, Vec3 size) + { + data.oriels[id].m4 = (Matrix)System.Numerics.Matrix4x4.Transpose( + m4.Inverse + ); + data.oriels[id].m4_inv = (Matrix)System.Numerics.Matrix4x4.Transpose( + m4 + ); + data.oriels[id].size = size; + buffer.Set(data); + } - public Material mono = new (Shader.FromFile("shaders/mono.hlsl")); - public void SetAtlas(string name, Material mat) { - Tex tex = Tex.FromFile($"{name}/{name}.png"); - tex.SampleMode = TexSample.Point; - mat.SetTexture("diffuse", tex); - } + public Material mono = new(Shader.FromFile("shaders/mono.hlsl")); + public void SetAtlas(string name, Material mat) + { + Tex tex = Tex.FromFile($"{name}/{name}.png"); + tex.SampleMode = TexSample.Point; + mat.SetTexture("diffuse", tex); + } - public Material sky = new (Shader.FromFile("shaders/sky.hlsl")); - - public Material unlit = new (Shader.FromFile("shaders/unlit.hlsl")); - public Material unlit_clear = new (Shader.FromFile("shaders/unlit.hlsl")); + public Material sky = new(Shader.FromFile("shaders/sky.hlsl")); - public void Init() { - data.oriels = new oriel_data[455]; // 455 *see dofdev.hlsli + public Material unlit = new(Shader.FromFile("shaders/unlit.hlsl")); + public Material unlit_clear = new(Shader.FromFile("shaders/unlit.hlsl")); - mono.FaceCull = Cull.None; - sky.FaceCull = Cull.Front; + public void Init() + { + data.oriels = new oriel_data[455]; // 455 *see dofdev.hlsli - unlit_clear.Transparency = Transparency.Blend; - unlit_clear.DepthWrite = false; - } + mono.FaceCull = Cull.None; + sky.FaceCull = Cull.Front; - public void Run() { - Rig rig = Main.Mono.inst.rig; + unlit_clear.Transparency = Transparency.Blend; + unlit_clear.DepthWrite = false; + } + + public void Run() + { + Rig rig = Main.Mono.inst.rig; - // Log.Info($"{rig.perch_pos.z}"); - } + // Log.Info($"{rig.perch_pos.z}"); + } } \ No newline at end of file diff --git a/sk_demo/src/Mono.cs b/sk_demo/src/Mono.cs index ecb70cd..7076710 100644 --- a/sk_demo/src/Mono.cs +++ b/sk_demo/src/Mono.cs @@ -1,26 +1,28 @@ -using System.Security.AccessControl; +using System.Security.AccessControl; namespace Main; -public class Mono { - private static readonly Lazy lazy = new(() => new Mono()); - public static Mono inst { get { return lazy.Value; } } +public class Mono +{ + private static readonly Lazy lazy = new(() => new Mono()); + public static Mono inst { get { return lazy.Value; } } - public static readonly bool dev = Environment.CommandLine.Contains("--dev"); - - public MonoNet monoNet = new(); - - public Rig rig = new(); + public static readonly bool dev = Environment.CommandLine.Contains("--dev"); - public Mat mat = new(); - Mesh mesh_floor = Mesh.Quad; + public MonoNet monoNet = new(); - Material mat_room = new (Shader.FromFile("shaders/room.hlsl")); - Model model_room = Model.FromFile("room.glb"); - Mesh mesh_room = Mesh.Quad; + public Rig rig = new(); - // key:(char) value:(int[] dots) - Dictionary char_cell = new Dictionary { + + public Mat mat = new(); + Mesh mesh_floor = Mesh.Quad; + + Material mat_room = new(Shader.FromFile("shaders/room.hlsl")); + Model model_room = Model.FromFile("room.glb"); + Mesh mesh_room = Mesh.Quad; + + // key:(char) value:(int[] dots) + Dictionary char_cell = new Dictionary { { ' ', new int[] { 0, 0, 0, 0, @@ -183,13 +185,14 @@ public class Mono { } }, }; - // enum of layouts - public enum Layout { - Qwerty, - Colemak - } + // enum of layouts + public enum Layout + { + Qwerty, + Colemak + } - Dictionary layouts = new Dictionary { + Dictionary layouts = new Dictionary { { Layout.Colemak, new char[] { 'q', 'w', 'f', 'p', 'g', 'j', 'l', 'u', 'y', ';', 'a', 'r', 's', 't', 'd', 'h', 'n', 'e', 'i', 'o', @@ -202,178 +205,190 @@ public class Mono { } }, }; - public char KeyToChar(int index) { - return layouts[Layout.Colemak][index]; - } - - Matrix keyboard_m4 = Matrix.Identity; - Rig.Btn keyboard_btn = new(); - Vec3 index_pos = Vec3.Zero; - int index_i = 0; - int last_index_i = 0; - - string txt = "hello "; - - public void Init() { - rig.Init(); - - mat.Init(); - mesh_floor = Mesh.GenerateCircle(1, 64); - - mat_room.SetTexture("diffuse", Tex.FromFile("bake.png")); - mesh_room = model_room.Nodes.First(n => n.Name == "Room").Mesh; - - keyboard_btn.held = true; - } - - public void Run() { - rig.Run(); - - keyboard_m4 = Matrix.TRS( - V.XYZ(-0.18f, 1.15f, -0.5f), - Quat.FromAngles(0, 180, 0) * Quat.FromAngles(40, 0, 0), - V.XYZ(-1, -1, 1) * 0.04f - ); - - // thumb extension - // Matrix palm_ori = rig.hand_1.palm.ToMatrix(); - // Vec3 thumb_tip = palm_ori.Inverse * rig.hand_1.Get(FingerId.Thumb, JointId.Tip).position; - // Vec3 thumb_minor = palm_ori.Inverse * rig.hand_1.Get(FingerId.Thumb, JointId.KnuckleMinor).position; - // if (thumb_tip.x < thumb_minor.x - 0f * U.cm) { - // // Log.Info("thumb is out"); - // xi = 0; - // } - for (int i = 0; i < keb_keys.Length-1; i++) { - if (Input.Key(keb_keys[i].key).IsJustActive()) { - txt += keb_keys[i].char_; - monoNet.value = keb_keys[i].char_; - monoNet.send = true; - } + public char KeyToChar(int index) + { + return layouts[Layout.Colemak][index]; } - Vec3 index_tip = keyboard_m4.Inverse * rig.hand_1.Get(FingerId.Index, JointId.Tip).position; - // press - index_pos.z = Math.Clamp(index_tip.z, -0.3f, 0.1f); - keyboard_btn.Frame(index_pos.z > 0.0f, index_pos.z < -0.2f); + Matrix keyboard_m4 = Matrix.Identity; + Rig.Btn keyboard_btn = new(); + Vec3 index_pos = Vec3.Zero; + int index_i = 0; + int last_index_i = 0; - if (!keyboard_btn.held) { - // snap to grid - index_pos.x = (float)Math.Clamp(Math.Round(index_tip.x), 0, 10-1); - index_pos.y = (float)Math.Clamp(Math.Round(index_tip.y), 0, 3-1); + string txt = "hello "; - index_i = (int)(index_pos.y * 10 + index_pos.x); + public void Init() + { + rig.Init(); - if (index_i != last_index_i) { - last_index_i = index_i; - // Log.Info($"index_i: {index_i}"); - monoNet.value = KeyToChar(index_i); - monoNet.send = true; - } + mat.Init(); + mesh_floor = Mesh.GenerateCircle(1, 64); + + mat_room.SetTexture("diffuse", Tex.FromFile("bake.png")); + mesh_room = model_room.Nodes.First(n => n.Name == "Room").Mesh; + + keyboard_btn.held = true; } - if (keyboard_btn.frameDown) { - // send haptic input for input confirmation - txt += KeyToChar(index_i); - } + public void Run() + { + rig.Run(); - - // RENDER RENDER RENDER - - // keyboard - Hierarchy.Push(keyboard_m4); - // 3 rows of 10 keys - for (int y = 0; y < 3; y++) { - for (int x = 0; x < 10; x++) { - Vec3 pos = V.XYZ(x, y, 0); - // background quad - Mesh.Quad.Draw( - mat.unlit_clear, - Matrix.TS(pos, 0.9f), - Color.Hex(0x00000040) + keyboard_m4 = Matrix.TRS( + V.XYZ(-0.18f, 1.15f, -0.5f), + Quat.FromAngles(0, 180, 0) * Quat.FromAngles(40, 0, 0), + V.XYZ(-1, -1, 1) * 0.04f ); - int index = y * 10 + x; - char keychar = KeyToChar(index); + // thumb extension + // Matrix palm_ori = rig.hand_1.palm.ToMatrix(); + // Vec3 thumb_tip = palm_ori.Inverse * rig.hand_1.Get(FingerId.Thumb, JointId.Tip).position; + // Vec3 thumb_minor = palm_ori.Inverse * rig.hand_1.Get(FingerId.Thumb, JointId.KnuckleMinor).position; + // if (thumb_tip.x < thumb_minor.x - 0f * U.cm) { + // // Log.Info("thumb is out"); + // xi = 0; + // } + for (int i = 0; i < keb_keys.Length - 1; i++) + { + if (Input.Key(keb_keys[i].key).IsJustActive()) + { + txt += keb_keys[i].char_; + monoNet.value = keb_keys[i].char_; + monoNet.send = true; + } + } - Text.Add( - keychar.ToString(), + Vec3 index_tip = keyboard_m4.Inverse * rig.hand_1.Get(FingerId.Index, JointId.Tip).position; + // press + index_pos.z = Math.Clamp(index_tip.z, -0.3f, 0.1f); + keyboard_btn.Frame(index_pos.z > 0.0f, index_pos.z < -0.2f); + + if (!keyboard_btn.held) + { + // snap to grid + index_pos.x = (float)Math.Clamp(Math.Round(index_tip.x), 0, 10 - 1); + index_pos.y = (float)Math.Clamp(Math.Round(index_tip.y), 0, 3 - 1); + + index_i = (int)(index_pos.y * 10 + index_pos.x); + + if (index_i != last_index_i) + { + last_index_i = index_i; + // Log.Info($"index_i: {index_i}"); + monoNet.value = KeyToChar(index_i); + monoNet.send = true; + } + } + + if (keyboard_btn.frameDown) + { + // send haptic input for input confirmation + txt += KeyToChar(index_i); + } + + + // RENDER RENDER RENDER + + // keyboard + Hierarchy.Push(keyboard_m4); + // 3 rows of 10 keys + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 10; x++) + { + Vec3 pos = V.XYZ(x, y, 0); + // background quad + Mesh.Quad.Draw( + mat.unlit_clear, + Matrix.TS(pos, 0.9f), + Color.Hex(0x00000040) + ); + + int index = y * 10 + x; + char keychar = KeyToChar(index); + + Text.Add( + keychar.ToString(), + Matrix.TS( + pos + V.XYZ(-0.3f, -0.3f, 0), + V.XYZ(-1, -1, 0) * 8.0f + ), + TextAlign.Center, + TextAlign.Center, + 0, 0, 0 + ); + // show the braille dots(spheres) above the text + for (int k = 0; k < 6; k++) + { + float spacing = 0.2f; + float x_offset = (k % 2) * spacing; + float y_offset = (k / 2) * -spacing; + if (char_cell[keychar][k] == 1) + { + Mesh.Sphere.Draw( + mat.unlit_clear, + Matrix.TS( + V.XYZ(pos.x + x_offset, pos.y - y_offset, 0) + V.XYZ(-0.1f, -0.18f, 0), + 0.1f + ), + Color.Hex(0xFFFFFFFF) + ); + } + } + } + } + Hierarchy.Pop(); + + // keyboard button + Mesh.Cube.Draw( + mat.unlit_clear, Matrix.TS( - pos + V.XYZ(-0.3f, -0.3f, 0), - V.XYZ(-1, -1, 0) * 8.0f - ), - TextAlign.Center, - TextAlign.Center, + index_pos * V.XYZ(1, 1, 0.25f), + V.XYZ(0.8f, 0.8f, -index_pos.z * 0.5f) + ) * keyboard_m4, + keyboard_btn.held ? Color.Hex(0x00000090) : Color.Hex(0x80808090) + ); + + // text + // show over the keyboard + Text.Add( + txt, + Matrix.TS( + V.XYZ(0, -1, 0), + V.XYZ(-1, -1, 0) * 20.0f + ) * keyboard_m4, + TextAlign.CenterLeft, + TextAlign.CenterLeft, 0, 0, 0 ); - // show the braille dots(spheres) above the text - for (int k = 0; k < 6; k++) { - float spacing = 0.2f; - float x_offset = (k % 2) * spacing; - float y_offset = (k / 2) * -spacing; - if (char_cell[keychar][k] == 1) { - Mesh.Sphere.Draw( - mat.unlit_clear, - Matrix.TS( - V.XYZ(pos.x + x_offset, pos.y - y_offset, 0) + V.XYZ(-0.1f, -0.18f, 0), - 0.1f - ), - Color.Hex(0xFFFFFFFF) - ); - } - } - } - } - Hierarchy.Pop(); - // keyboard button - Mesh.Cube.Draw( - mat.unlit_clear, - Matrix.TS( - index_pos * V.XYZ(1, 1, 0.25f), - V.XYZ(0.8f, 0.8f, -index_pos.z * 0.5f) - ) * keyboard_m4, - keyboard_btn.held ? Color.Hex(0x00000090) : Color.Hex(0x80808090) - ); + // WORLD + mesh_room.Draw( + mat_room, + Matrix.T(V.XYZ(0, 0, 0)) + ); - // text - // show over the keyboard - Text.Add( - txt, - Matrix.TS( - V.XYZ(0, -1, 0), - V.XYZ(-1, -1, 0) * 20.0f - ) * keyboard_m4, - TextAlign.CenterLeft, - TextAlign.CenterLeft, - 0, 0, 0 - ); - // WORLD - mesh_room.Draw( - mat_room, - Matrix.T(V.XYZ(0, 0, 0)) - ); - - - mesh_floor.Draw( - mat.unlit, - Matrix.TS( - V.XYZ(0, 0, 0), - 1*U.cm - ), - Color.Hex(0x666666FF) - ); + mesh_floor.Draw( + mat.unlit, + Matrix.TS( + V.XYZ(0, 0, 0), + 1 * U.cm + ), + Color.Hex(0x666666FF) + ); - Vec3[] offsets = new Vec3[] { + Vec3[] offsets = new Vec3[] { V.XYZ(-2, -2f, -2f) * U.cm, V.XYZ(2, 2f, 2f) * U.cm, V.XYZ(0, 0, 0) }; - mat.Run(); - } + mat.Run(); + } - KebKey[] keb_keys = new KebKey[] { + KebKey[] keb_keys = new KebKey[] { new() { key = Key.Space, char_ = ' ' }, new() { key = Key.Return, char_ = '\n' }, new() { key = Key.A, char_ = 'a' }, @@ -403,8 +418,9 @@ public class Mono { new() { key = Key.Y, char_ = 'y' }, new() { key = Key.Z, char_ = 'z' }, }; - public struct KebKey { - public Key key; - public char char_; - } + public struct KebKey + { + public Key key; + public char char_; + } } \ No newline at end of file diff --git a/sk_demo/src/MonoNet.cs b/sk_demo/src/MonoNet.cs index 721e6bc..504554e 100644 --- a/sk_demo/src/MonoNet.cs +++ b/sk_demo/src/MonoNet.cs @@ -3,44 +3,49 @@ using System.Net.Http; using System.Net.Sockets; using System.Threading; -public class MonoNet { - public Socket socket; - int bufferSize = 180; // ? - byte[] wData; int wHead; +public class MonoNet +{ + public Socket socket; + int bufferSize = 180; // ? + byte[] wData; int wHead; - public bool send = true; - public char value = ' '; + public bool send = true; + public char value = ' '; - public MonoNet() { + public MonoNet() + { - socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - string ip = "192.168.0.23"; + socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + string ip = "192.168.1.117"; - EndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), 1234); - socket.Connect(serverEndPoint); - wData = new byte[bufferSize]; + EndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), 1234); + socket.Connect(serverEndPoint); + wData = new byte[bufferSize]; - Thread.Sleep(1000); // useful? + Thread.Sleep(1000); // useful? - // Thread readThread = new Thread(Read); - // readThread.Start(); - Thread writeThread = new Thread(Write); - writeThread.Start(); - } - - void Write() { - bool running = true; - while (running) { - Thread.Sleep(60); - if (send) { - wHead = 0; - BitConverter.GetBytes(value).CopyTo(wData, wHead); - socket.Send(wData); - - // Log.Info($"Sent {value}"); - send = false; // for testing - } + // Thread readThread = new Thread(Read); + // readThread.Start(); + Thread writeThread = new Thread(Write); + writeThread.Start(); } - } -} \ No newline at end of file + + void Write() + { + bool running = true; + while (running) + { + Thread.Sleep(60); + if (send) + { + wHead = 0; + BitConverter.GetBytes(value).CopyTo(wData, wHead); + socket.Send(wData); + + // Log.Info($"Sent {value}"); + send = false; // for testing + } + } + } +} diff --git a/sk_demo/src/Rig.cs b/sk_demo/src/Rig.cs index dbc377b..44e4130 100644 --- a/sk_demo/src/Rig.cs +++ b/sk_demo/src/Rig.cs @@ -1,47 +1,54 @@ -public class Rig { - public Vec3 head_pos = Vec3.Zero; - public Quat head_ori = Quat.Identity; - public Vec3 view_pos = Vec3.Zero; +public class Rig +{ + public Vec3 head_pos = Vec3.Zero; + public Quat head_ori = Quat.Identity; + public Vec3 view_pos = Vec3.Zero; - public Hand hand_0 = new(); - public Hand hand_1 = new(); - public Vec3 palm_pos = Vec3.Zero; - public Quat palm_ori = Quat.Identity; + public Hand hand_0 = new(); + public Hand hand_1 = new(); + public Vec3 palm_pos = Vec3.Zero; + public Quat palm_ori = Quat.Identity; - public Vec3 perch_pos = Vec3.Zero; + public Vec3 perch_pos = Vec3.Zero; - public void Init() { - } + public void Init() + { - public void Run() { - hand_0 = Input.Hand(Handed.Left); - hand_1 = Input.Hand(Handed.Right); - - head_pos = Main.Mono.dev && Time.Totalf > 0.5f ? head_pos : Input.Head.position; - head_ori = Main.Mono.dev && Time.Totalf > 0.5f ? head_ori : Input.Head.orientation; - view_pos = head_pos + V.XYZ(0, -6*U.cm, 0); - - - - // Position is specifically defined as the middle of the middle finger's root (metacarpal) bone. - palm_pos = hand_1.palm.position; - // For orientation, Forward is the direction the flat of the palm is facing, "Iron Man" style. X+ is to the outside of the right hand, and to the inside of the left hand. - palm_ori = hand_1.palm.orientation; - - perch_pos = palm_pos + Vec3.Up * 8 * U.cm; - } - - public struct Btn { - public bool frameDown, held, frameUp; - - public void Frame(bool down, bool? up = null) { - if (up != null && held) { - down = !(bool)up; - } - - frameDown = down && !held; - frameUp = !down && held; - held = down; } - } + + public void Run() + { + hand_0 = Input.Hand(Handed.Left); + hand_1 = Input.Hand(Handed.Right); + + head_pos = Main.Mono.dev && Time.Totalf > 0.5f ? head_pos : Input.Head.position; + head_ori = Main.Mono.dev && Time.Totalf > 0.5f ? head_ori : Input.Head.orientation; + view_pos = head_pos + V.XYZ(0, -6 * U.cm, 0); + + + + // Position is specifically defined as the middle of the middle finger's root (metacarpal) bone. + palm_pos = hand_1.palm.position; + // For orientation, Forward is the direction the flat of the palm is facing, "Iron Man" style. X+ is to the outside of the right hand, and to the inside of the left hand. + palm_ori = hand_1.palm.orientation; + + perch_pos = palm_pos + Vec3.Up * 8 * U.cm; + } + + public struct Btn + { + public bool frameDown, held, frameUp; + + public void Frame(bool down, bool? up = null) + { + if (up != null && held) + { + down = !(bool)up; + } + + frameDown = down && !held; + frameUp = !down && held; + held = down; + } + } } \ No newline at end of file diff --git a/sk_demo/src/SKs.cs b/sk_demo/src/SKs.cs index 42c9853..ab8d7ed 100644 --- a/sk_demo/src/SKs.cs +++ b/sk_demo/src/SKs.cs @@ -4,22 +4,24 @@ global using StereoKit; Log.Filter = LogLevel.Info; Log.Info("hello log!"); -SKSettings settings = new() { - appName = "dofbox", - assetsFolder = "res", - depthMode = DepthMode.D32, - disableUnfocusedSleep = true, - flatscreenWidth = 1280, - flatscreenHeight = 720, - // displayPreference = DisplayMode.Flatscreen, - // disableFlatscreenMRSim = true, - origin = OriginMode.Floor, - overlayApp = true, - overlayPriority = 1, - blendPreference = DisplayBlend.AnyTransparent, +SKSettings settings = new() +{ + appName = "dofbox", + + assetsFolder = "res", + depthMode = DepthMode.D32, + disableUnfocusedSleep = true, + flatscreenWidth = 1280, + flatscreenHeight = 720, + displayPreference = DisplayMode.Flatscreen, + // disableFlatscreenMRSim = true, + origin = OriginMode.Floor, + overlayApp = true, + overlayPriority = 1, + blendPreference = DisplayBlend.AnyTransparent, }; if (!SK.Initialize(settings)) - Environment.Exit(1); + Environment.Exit(1); // Input.HandSolid(Handed.Max, false); // Input.HandVisible(Handed.Max, true); @@ -34,6 +36,7 @@ Renderer.SetFOV(60f); Main.Mono mono = Main.Mono.inst; mono.Init(); -SK.Run(() => { - mono.Run(); +SK.Run(() => +{ + mono.Run(); });