braille_xr/sk_demo/src/Mono.cs
2024-02-04 01:33:54 -05:00

350 lines
No EOL
7.1 KiB
C#

using System.Security.AccessControl;
namespace Main;
public class Mono {
private static readonly Lazy<Mono> 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 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;
public class Character {
public string character;
public int[] dots;
public Character(string character, int[] dots) {
this.character = character;
this.dots = dots;
}
}
// key:(string) value:(int[] dots)
Dictionary<string, int[]> char_cell = new Dictionary<string, int[]> {
{ "a", new int[] {
1, 0,
0, 0,
0, 0
} },
{ "b", new int[] {
1, 0,
1, 0,
0, 0
} },
{ "c", new int[] {
1, 1,
0, 0,
0, 0
} },
{ "d", new int[] {
1, 1,
0, 1,
0, 0
} },
{ "e", new int[] {
1, 0,
0, 1,
0, 0
} },
{ "f", new int[] {
1, 1,
1, 0,
0, 0
} },
{ "g", new int[] {
1, 1,
1, 1,
0, 0
} },
{ "h", new int[] {
1, 0,
1, 1,
0, 0
} },
{ "i", new int[] {
0, 1,
1, 0,
0, 0
} },
{ "j", new int[] {
0, 1,
1, 1,
0, 0
} },
{ "k", new int[] {
1, 0,
0, 0,
1, 0
} },
{ "l", new int[] {
1, 0,
1, 0,
1, 0
} },
{ "m", new int[] {
1, 1,
0, 0,
1, 0
} },
{ "n", new int[] {
1, 1,
0, 1,
1, 0
} },
{ "o", new int[] {
1, 0,
0, 1,
1, 0
} },
{ "p", new int[] {
1, 1,
1, 0,
1, 0
} },
{ "q", new int[] {
1, 1,
1, 1,
1, 0
} },
{ "r", new int[] {
1, 0,
1, 1,
1, 0
} },
{ "s", new int[] {
0, 1,
1, 0,
1, 0
} },
{ "t", new int[] {
0, 1,
1, 1,
1, 0
} },
{ "u", new int[] {
1, 0,
0, 0,
1, 1
} },
{ "v", new int[] {
1, 0,
1, 0,
1, 1
} },
{ "w", new int[] {
0, 1,
1, 1,
0, 1
} },
{ "x", new int[] {
1, 1,
0, 0,
1, 1
} },
{ "y", new int[] {
1, 1,
0, 1,
1, 1
} },
{ "z", new int[] {
1, 0,
0, 1,
1, 1
} },
{ " ", new int[] {
0, 0,
0, 0,
0, 0
} },
{ ",", new int[] {
0, 0,
1, 0,
0, 0
} },
{ ".", new int[] {
0, 0,
1, 1,
0, 1
} },
{ "/", new int[] {
0, 1,
0, 0,
1, 0
} },
{ ";", new int[] {
0, 0,
1, 0,
1, 0
} },
};
// enum of layouts
public enum Layout {
Qwerty,
Colemak
}
Dictionary<Layout, string[]> layouts = new Dictionary<Layout, string[]> {
{ Layout.Colemak, new string[] {
"q", "w", "f", "p", "g", "j", "l", "u", "y", ";",
"a", "r", "s", "t", "d", "h", "n", "e", "i", "o",
"z", "x", "c", "v", "b", "k", "m", ",", ".", "/",
} },
{ Layout.Qwerty, new string[] {
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
"a", "s", "d", "f", "g", "h", "j", "k", "l", ";",
"z", "x", "c", "v", "b", "n", "m", ",", ".", "/",
} },
};
public string 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;
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;
}
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;
// }
if (Input.Key(Key.Down).IsJustActive()) {
monoNet.value = 0;
monoNet.send = true;
}
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 (keyboard_btn.frameDown) {
Log.Info($"index_i: {index_i}");
monoNet.value = index_i;
monoNet.send = true;
}
// 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;
// string text = characters[index].character;
string keychar = KeyToChar(index);
Text.Add(
keychar,
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(
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))
);
mesh_floor.Draw(
mat.unlit,
Matrix.TS(
V.XYZ(0, 0, 0),
1*U.cm
),
Color.Hex(0x666666FF)
);
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();
}
}