snake/src/Arts.cs
2024-11-10 04:21:17 -05:00

216 lines
No EOL
6.6 KiB
C#

using System.Collections.Generic;
using StereoKit;
namespace snake;
static class Arts
{
static Model assets_model = Model.FromFile("meshes/assets.glb", Shader.Unlit);
static Dictionary<string, Mesh> meshes = new();
static Material mat_mono = new Material("mono.hlsl");
static Material mat_unlit = new Material("unlit.hlsl");
static Material mat_backbox = new Material("backbox.hlsl");
static Material mat_justcolor = new Material("justcolor.hlsl");
static Quat food_ori = Quat.Identity;
static XYZi last_headpos = new(0, 0, 0);
static DeltaBool headmove = new(false);
static XYZi last_tailpos = new(0, 0, 0);
static DeltaBool tailmove = new(false);
public static void Init()
{
foreach (ModelNode node in assets_model.Nodes)
{
if (node.Mesh != null)
{
meshes.Add(node.Name, node.Mesh);
}
}
mat_backbox.Transparency = Transparency.Add;
mat_backbox.FaceCull = Cull.Front;
}
public static void Frame()
{
// background
if (Device.DisplayBlend == DisplayBlend.Opaque)
{
}
// fullstick
Mesh.Sphere.Draw(
mat_unlit,
Matrix.TS(
Rig.r_con_stick.position,
5 * U.mm
),
Color.White
);
Lines.Add(
Rig.r_con_stick.position + V.XYZ(0, 0, 0),
Rig.r_con_stick.position + Rig.fullstick * U.cm,
Color.White,
2 * U.mm
);
// box
Hierarchy.Push(Mono.box_pose.ToMatrix(Mono.box_scale));
meshes["InsideOut"].Draw(mat_unlit, Matrix.Identity);
meshes["InsideOut"].Draw(mat_backbox, Matrix.Identity);
meshes["Corrugation"].Draw(
Mono.in_dist.state ? mat_justcolor : mat_unlit,
Matrix.Identity
);
if (Mono.in_cone.state)
{
meshes["Hanging"].Draw(
mat_unlit,
Matrix.Identity
);
}
if (Mono.menu)
{
meshes["Tape"].Draw(mat_mono, Matrix.Identity);
meshes["uiPlay"].Draw(
mat_unlit,
Matrix.TR(
V.XYZ(0, 0, Mono.SD_Z + 0.5f + 0.1f),
Quat.FromAngles(90, 0, 0)
)
);
meshes["uiCursor"].Draw(
mat_unlit,
Matrix.TR(
V.XYZ(0, 0, Mono.SD_Z + 0.5f + 0.2f),
Quat.FromAngles(90, 0, 0)
)
);
}
// snake
float snake_t = headmove.state ? Maths.u_clamp(Maths.smooth_stop((float)Mono.step_t) * 3.0f) : 1.0f;
bool food_next = !Mono.eaten_latch.state && (Mono.snake[0] + Mono.snake_dir) == Mono.food;
if (!food_next)
{
meshes["Tongue"].Draw(
mat_mono,
Matrix.TRS(
Mono.snake[0].ToVec3,
Quat.LookDir(Rig.fullstick),
V.XYZ(1, 1, 0.666f + Maths.smooth_stop((float)Mono.step_t) * 0.333f)
)
);
}
string face = food_next ? "Face1Eat" : "Face0Default";
meshes[face].Draw(
mat_mono,
Matrix.TRS(
Mono.snake[0].ToVec3 - (Mono.snake_dir.ToVec3 * (float)(1.0 - snake_t) * 0.3f),
Quat.LookDir(Mono.snake_dir.ToVec3),
V.XYZ(1, 1, (float)(snake_t))
)
);
for (int i = 1; i < Mono.snake_len; i++)
{
float scale = 1.0f;
if ((int)((Time.Total - Mono.eat_timestamp) * Mono.snake_len / Mono.step_step) == i)
{
scale = 1.1f;
}
meshes["Segment"].Draw(
mat_mono,
Matrix.TRS(
Mono.snake[i].ToVec3,
Quat.LookAt(Mono.snake[i].ToVec3, Mono.snake[i - 1].ToVec3),
scale
)
);
}
// false tail
if (tailmove.state && snake_t < 1.0f) {
int i_tail = Maths.min(Mono.snake_len, Mono.snake.Length - 1);
Vec3 tail_dir = Vec3.Direction(Mono.snake[i_tail - 1].ToVec3, Mono.snake[i_tail].ToVec3);
meshes["Segment"].Draw(
mat_mono,
Matrix.TRS(
Mono.snake[i_tail].ToVec3 + (tail_dir * (float)(snake_t) * 0.7f),
Quat.LookDir(tail_dir),
V.XYZ(1, 1, (float)(1.0 - snake_t))
)
);
}
// holes
foreach (KeyValuePair<XYZi, XYZi> hole in Mono.holes)
{
meshes["Hole"].Draw(
mat_unlit,
Matrix.TRS(
hole.Key.ToVec3,
Quat.LookDir(hole.Value.ToVec3),
1
)
);
}
// food
if (!food_next)
{
food_ori *= Quat.FromAngles(
90 * Time.Stepf,
30 * Time.Stepf,
10 * Time.Stepf
);
}
if (!Mono.eaten_latch.state)
{
float food_t = Mono.eaten_latch.delta == -1 ? Maths.smooth_stop((float)Mono.step_t) : 1;
meshes["Food"].Draw(
mat_mono,
Matrix.TRS(
Mono.food.ToVec3,
food_ori,
food_t
)
);
}
Hierarchy.Pop();
// for (int sx = -Mono.head_fill.Xslen; Mono.head_fill.InX(sx); sx++)
// {
// for (int sy = -Mono.head_fill.Yslen; Mono.head_fill.InY(sy); sy++)
// {
// for (int sz = -Mono.head_fill.Zslen; Mono.head_fill.InZ(sz); sz++)
// {
// Vec3 pos = Mono.box_pose.ToMatrix(U.cm) * V.XYZ(sx, sy, sz);
// Text.Add(
// (Mono.head_fill[new XYZi(sx, sy, sz)] + Mono.tail_fill[new XYZi(sx, sy, sz)]).ToString(),
// Matrix.TRS(
// pos,
// Quat.LookAt(pos, Input.Head.position),
// 0.1f
// )
// );
// }
// }
// }
}
public static void Step()
{
XYZi snake_head = Mono.snake[0];
XYZi snake_tail = Mono.snake[Mono.snake_len -1];
headmove.Step(snake_head != last_headpos);
tailmove.Step(snake_tail != last_tailpos);
last_headpos = snake_head;
last_tailpos = snake_tail;
}
}