Compare commits
10 commits
ba6fc33a40
...
e5c6514b67
Author | SHA1 | Date | |
---|---|---|---|
e5c6514b67 | |||
cabd123404 | |||
66e5afdb22 | |||
af27931d6c | |||
d1cb1bd452 | |||
741f2ee713 | |||
041ceea867 | |||
290ada0f0c | |||
1a3a9c2ee5 | |||
a5328c1a6e |
8 changed files with 183 additions and 62 deletions
45
Assets/hand.hlsl
Normal file
45
Assets/hand.hlsl
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include "stereokit.hlsli"
|
||||||
|
|
||||||
|
//--name = dofdev/hand
|
||||||
|
//--color:color = 1, 1, 1, 1
|
||||||
|
//--tex_scale = 1
|
||||||
|
//--diffuse = white
|
||||||
|
|
||||||
|
float4 color;
|
||||||
|
float tex_scale;
|
||||||
|
Texture2D diffuse : register(t0);
|
||||||
|
SamplerState diffuse_s : register(s0);
|
||||||
|
|
||||||
|
struct vsIn {
|
||||||
|
float4 pos : SV_Position;
|
||||||
|
float3 norm : NORMAL0;
|
||||||
|
float2 uv : TEXCOORD0;
|
||||||
|
float4 col : COLOR0;
|
||||||
|
};
|
||||||
|
struct psIn {
|
||||||
|
float4 pos : SV_POSITION;
|
||||||
|
float2 uv : TEXCOORD0;
|
||||||
|
float4 color : COLOR0;
|
||||||
|
uint view_id : SV_RenderTargetArrayIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
psIn vs(vsIn input, uint id : SV_InstanceID) {
|
||||||
|
psIn o;
|
||||||
|
o.view_id = id % sk_view_count;
|
||||||
|
id = id / sk_view_count;
|
||||||
|
|
||||||
|
float3 world = mul(float4(input.pos.xyz, 1), sk_inst[id].world).xyz;
|
||||||
|
o.pos = mul(float4(world, 1), sk_viewproj[o.view_id]);
|
||||||
|
|
||||||
|
float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
|
||||||
|
|
||||||
|
o.uv = input.uv * tex_scale;
|
||||||
|
float3 norm_color = float3(0.5) + (normal * 0.5);
|
||||||
|
float3 norm_shade = float3(0.5) + (norm_color * 0.5);
|
||||||
|
o.color = float4(norm_shade, 1) * input.col; // input.col * color * sk_inst[id].color;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
float4 ps(psIn input) : SV_TARGET {
|
||||||
|
float4 col = diffuse.Sample(diffuse_s, input.uv);
|
||||||
|
return input.color * col * float4(1, 1, 1, 0.1333);
|
||||||
|
}
|
BIN
Assets/meshes/assets.glb
(Stored with Git LFS)
BIN
Assets/meshes/assets.glb
(Stored with Git LFS)
Binary file not shown.
|
@ -52,11 +52,11 @@ todo
|
||||||
featuring:
|
featuring:
|
||||||
[x] stretch_cursor
|
[x] stretch_cursor
|
||||||
[x] color_cube
|
[x] color_cube
|
||||||
[ ] reach_cursor
|
|
||||||
[ ] orbital_view // same dis/mount system as snake in a box
|
|
||||||
[ ] fullstick
|
|
||||||
[ ] twist_cursor
|
[ ] twist_cursor
|
||||||
|
[ ] reach_cursor
|
||||||
[ ] cubic_flow
|
[ ] cubic_flow
|
||||||
|
[ ] fullstick
|
||||||
|
[ ] orbital_view // same dis/mount system as snake in a box
|
||||||
|
|
||||||
bug(s)
|
bug(s)
|
||||||
...
|
...
|
||||||
|
|
79
src/Arts.cs
79
src/Arts.cs
|
@ -8,6 +8,7 @@ static class Arts
|
||||||
static Model assets_model = Model.FromFile("meshes/assets.glb", Shader.Unlit);
|
static Model assets_model = Model.FromFile("meshes/assets.glb", Shader.Unlit);
|
||||||
static Dictionary<string, Mesh> meshes = new();
|
static Dictionary<string, Mesh> meshes = new();
|
||||||
static Material mat_mono = new Material("mono.hlsl");
|
static Material mat_mono = new Material("mono.hlsl");
|
||||||
|
static Material mat_hand = Default.MaterialHand;
|
||||||
static Material mat_unlit = new Material("unlit.hlsl");
|
static Material mat_unlit = new Material("unlit.hlsl");
|
||||||
static Material mat_both = new Material("unlit.hlsl");
|
static Material mat_both = new Material("unlit.hlsl");
|
||||||
static Material mat_backface = new Material("backface.hlsl");
|
static Material mat_backface = new Material("backface.hlsl");
|
||||||
|
@ -43,13 +44,15 @@ static class Arts
|
||||||
|
|
||||||
// draw ontop of everything
|
// draw ontop of everything
|
||||||
mat_colorcursor.DepthTest = DepthTest.Always;
|
mat_colorcursor.DepthTest = DepthTest.Always;
|
||||||
|
|
||||||
|
mat_hand.Shader = Shader.FromFile("hand.hlsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frame()
|
public static void Frame()
|
||||||
{
|
{
|
||||||
if (SK.GetStepper<PassthroughFBExt>().Enabled) {
|
// if (SK.GetStepper<PassthroughFBExt>().Enabled) {
|
||||||
Input.HandVisible(Handed.Max, false);
|
// Input.HandVisible(Handed.Max, false);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// world
|
// world
|
||||||
// Matrix m4_dof = Mono.dof_pose.ToMatrix(Mono.dof_scl);
|
// Matrix m4_dof = Mono.dof_pose.ToMatrix(Mono.dof_scl);
|
||||||
|
@ -76,26 +79,45 @@ static class Arts
|
||||||
|
|
||||||
// stretch_cursor
|
// stretch_cursor
|
||||||
{
|
{
|
||||||
float flip_x = Stretch.to_grab.Held && Stretch.to_grab.held_by.handed == Handed.Left ? -1 : 1;
|
|
||||||
meshes["con"].Draw(
|
meshes["con"].Draw(
|
||||||
mat_mono,
|
mat_mono,
|
||||||
Stretch.to_grab.pose.ToMatrix(V.XYZ(flip_x, 1, 1) * 1.5f * U.cm)
|
Stretch.to_grab.pose.ToMatrix(1.5f * U.cm)
|
||||||
);
|
);
|
||||||
flip_x = Stretch.from_grab.Held && Stretch.from_grab.held_by.handed == Handed.Left ? -1 : 1;
|
|
||||||
meshes["con"].Draw(
|
meshes["con"].Draw(
|
||||||
mat_mono,
|
mat_mono,
|
||||||
Stretch.from_grab.pose.ToMatrix(V.XYZ(flip_x, 1, 1) * 1.5f * U.cm)
|
Stretch.from_grab.pose.ToMatrix(1.5f * U.cm)
|
||||||
);
|
);
|
||||||
|
|
||||||
Mesh.Cube.Draw(
|
Mesh.Cube.Draw(
|
||||||
mat_mono,
|
mat_justcolor,
|
||||||
Stretch.cursor.ToMatrix(3 * U.cm)
|
Stretch.cursor.ToMatrix(V.XYZ(-1, 1, 1) * 1.2f * U.cm),
|
||||||
|
Color.Hex(0x000000FF).ToLinear()
|
||||||
);
|
);
|
||||||
|
Mesh.Cube.Draw(
|
||||||
|
mat_mono,
|
||||||
|
Stretch.cursor.ToMatrix(1 * U.cm)
|
||||||
|
);
|
||||||
|
|
||||||
|
// particles
|
||||||
|
Particle[] particles = Stretch.particles;
|
||||||
|
for (int i = 0; i < particles.Length; i++)
|
||||||
|
{
|
||||||
|
Particle particle = particles[i];
|
||||||
|
Mesh.Sphere.Draw(
|
||||||
|
mat_unlit,
|
||||||
|
Matrix.TRS(
|
||||||
|
particle.pos,
|
||||||
|
particle.ori,
|
||||||
|
particle.scl
|
||||||
|
),
|
||||||
|
Color.Hex(0xFFFFFFFF).ToLinear()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// color_cube
|
// color_cube
|
||||||
{
|
{
|
||||||
meshes["color_cube"].Draw(
|
meshes[ColorCube.toggle ? "color_cube_toggle" : "color_cube"].Draw(
|
||||||
mat_colorcube,
|
mat_colorcube,
|
||||||
ColorCube.grab.pose.ToMatrix(ColorCube.scl)
|
ColorCube.grab.pose.ToMatrix(ColorCube.scl)
|
||||||
);
|
);
|
||||||
|
@ -121,6 +143,11 @@ static class Arts
|
||||||
Hierarchy.Pop();
|
Hierarchy.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reach_cursor
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Hierarchy.Pop();
|
// Hierarchy.Pop();
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,23 +168,23 @@ static class Arts
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// menu
|
// menu
|
||||||
Matrix m4_menu = Mono.menu_pose.ToMatrix(Mono.menu_scale);
|
// Matrix m4_menu = Mono.menu_pose.ToMatrix(Mono.menu_scale);
|
||||||
Hierarchy.Push(m4_menu);
|
// Hierarchy.Push(m4_menu);
|
||||||
|
|
||||||
// score
|
// // score
|
||||||
char[] score_txt = Mono.score.ToString("000").ToCharArray();
|
// char[] score_txt = Mono.score.ToString("000").ToCharArray();
|
||||||
for (int i = 0; i < score_txt.Length; i++)
|
// for (int i = 0; i < score_txt.Length; i++)
|
||||||
{
|
// {
|
||||||
Text.Add(
|
// Text.Add(
|
||||||
score_txt[i].ToString(),
|
// score_txt[i].ToString(),
|
||||||
Matrix.TS(
|
// Matrix.TS(
|
||||||
V.XYZ(0, 0, 0),
|
// V.XYZ(0, 0, 0),
|
||||||
48
|
// 48
|
||||||
),
|
// ),
|
||||||
text_style
|
// text_style
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
Hierarchy.Pop();
|
// Hierarchy.Pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
20
src/Data.cs
20
src/Data.cs
|
@ -13,7 +13,7 @@ public class Grab
|
||||||
public Pose pose;
|
public Pose pose;
|
||||||
private Vec3 pos_offset;
|
private Vec3 pos_offset;
|
||||||
private Quat ori_offset;
|
private Quat ori_offset;
|
||||||
public Hand? held_by;
|
public Controller? held_by;
|
||||||
private bool snap_to_hand = false;
|
private bool snap_to_hand = false;
|
||||||
|
|
||||||
public Grab(float x, float y, float z, bool snap_to_hand = false)
|
public Grab(float x, float y, float z, bool snap_to_hand = false)
|
||||||
|
@ -25,16 +25,16 @@ public class Grab
|
||||||
this.snap_to_hand = snap_to_hand;
|
this.snap_to_hand = snap_to_hand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnGrab(ref Hand hand, ref Grab grab_ref)
|
public bool OnGrab(ref Controller con, ref Grab grab_ref)
|
||||||
{
|
{
|
||||||
if (!Held) // Allow only one hand at a time to grab
|
if (!Held) // Allow only one hand at a time to grab
|
||||||
{
|
{
|
||||||
if (Vec3.Distance(hand.palm.position, pose.position) < 0.1f)
|
if (Vec3.Distance(con.pose.position, pose.position) < 0.14f)
|
||||||
{
|
{
|
||||||
held_by = hand;
|
held_by = con;
|
||||||
grab_ref = this;
|
grab_ref = this;
|
||||||
pos_offset = hand.palm.orientation.Inverse * (hand.palm.position - pose.position);
|
pos_offset = con.pose.orientation.Inverse * (con.pose.position - pose.position);
|
||||||
ori_offset = hand.palm.orientation.Inverse * pose.orientation;
|
ori_offset = con.pose.orientation.Inverse * pose.orientation;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,13 +54,13 @@ public class Grab
|
||||||
{
|
{
|
||||||
if (snap_to_hand)
|
if (snap_to_hand)
|
||||||
{
|
{
|
||||||
pose.orientation = held_by.palm.orientation;
|
pose.orientation = held_by.pose.orientation;
|
||||||
pose.position = held_by.palm.position;
|
pose.position = held_by.pose.position;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pose.orientation = held_by.palm.orientation * ori_offset;
|
pose.orientation = held_by.pose.orientation * ori_offset;
|
||||||
pose.position = held_by.palm.position - held_by.palm.orientation * pos_offset;
|
pose.position = held_by.pose.position - held_by.pose.orientation * pos_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
56
src/Dofs.cs
56
src/Dofs.cs
|
@ -12,23 +12,66 @@ static class Stretch
|
||||||
public static float stretch = 0.0f;
|
public static float stretch = 0.0f;
|
||||||
public static Pose cursor;
|
public static Pose cursor;
|
||||||
|
|
||||||
|
// vfx
|
||||||
|
public static Particle[] particles = new Particle[64];
|
||||||
|
static int index = 0;
|
||||||
|
static float trail_dist = 3 * U.cm;
|
||||||
|
static Vec3 last_particle_pos = Vec3.Zero;
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
to_grab = new(-0.3f, 0, 0, true);
|
to_grab = new(-0.3f, -0.25f, -0.5f, true);
|
||||||
from_grab = new(-0.3f, 0, 0.1f, true);
|
from_grab = new(-0.3f, -0.25f, -0.4f, true);
|
||||||
|
|
||||||
|
for (int i = 0; i < particles.Length; i++)
|
||||||
|
{
|
||||||
|
particles[i] = new();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frame()
|
public static void Frame()
|
||||||
{
|
{
|
||||||
|
if (!from_grab.Held && !to_grab.Held)
|
||||||
|
{
|
||||||
|
from_grab.pose.orientation = Quat.Identity;
|
||||||
|
to_grab.pose.orientation = Quat.Identity;
|
||||||
|
from_grab.pose.position = to_grab.pose.position - Vec3.Forward * ((15 * U.cm) - (MathF.Sin(Time.Totalf * 3f) * 4 * U.cm));
|
||||||
|
}
|
||||||
|
|
||||||
Vec3 delta = to_grab.pose.position - from_grab.pose.position;
|
Vec3 delta = to_grab.pose.position - from_grab.pose.position;
|
||||||
stretch = Maths.max(delta.Magnitude - deadzone, 0);
|
stretch = Maths.max(delta.Magnitude - deadzone, 0);
|
||||||
|
|
||||||
Vec3 dir = delta.Normalized;
|
Vec3 dir = toggle ? delta.Normalized : to_grab.pose.orientation * Vec3.Forward;
|
||||||
|
cursor.orientation = from_grab.pose.orientation;
|
||||||
cursor.position = to_grab.pose.position + dir * stretch * strength;
|
cursor.position = to_grab.pose.position + dir * stretch * strength;
|
||||||
|
|
||||||
|
if (Vec3.Distance(cursor.position, last_particle_pos) > trail_dist)
|
||||||
|
{
|
||||||
|
index = (index + 1) % particles.Length;
|
||||||
|
Particle particle = particles[index];
|
||||||
|
particle.pos = last_particle_pos + Vec3.Direction(cursor.position, last_particle_pos) * trail_dist;
|
||||||
|
// particle.vel = Quat.FromAngles(Random.Shared.NextSingle() * 360, 0, 0) * Quat.FromAngles(0, Random.Shared.NextSingle() * 360, 0) * Vec3.Forward * 6.0f;
|
||||||
|
particle.ori = Quat.Identity;
|
||||||
|
particle.scl = 3 * U.mm;
|
||||||
|
|
||||||
|
last_particle_pos = particle.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < particles.Length; i++)
|
||||||
|
{
|
||||||
|
Particle particle = particles[i];
|
||||||
|
if (particle.vel.MagnitudeSq > float.Epsilon)
|
||||||
|
{
|
||||||
|
// particle.pos += particle.vel * Time.Stepf;
|
||||||
|
// particle.vel *= 1 - (3 * Time.Stepf);
|
||||||
|
}
|
||||||
|
particle.scl *= 1.0f - (3 * Time.Stepf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// design
|
// design
|
||||||
static float deadzone = 0.1f;
|
public static bool toggle = true;
|
||||||
|
static float deadzone = 0.06f;
|
||||||
static float strength = 3;
|
static float strength = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +86,7 @@ static class ColorCube
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
grab = new(0, 0, 0);
|
grab = new(0, -0.25f, -0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frame()
|
public static void Frame()
|
||||||
|
@ -75,5 +118,8 @@ static class ColorCube
|
||||||
|
|
||||||
return x / 12.92f;
|
return x / 12.92f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// design
|
||||||
|
public static bool toggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
src/Mono.cs
13
src/Mono.cs
|
@ -39,6 +39,8 @@ static class Mono
|
||||||
ColorCube.Init();
|
ColorCube.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Pose windowPoseButton = new Pose(0, -0.4f, -0.4f, Quat.FromAngles(45, 180, 0));
|
||||||
|
|
||||||
public static void Frame()
|
public static void Frame()
|
||||||
{
|
{
|
||||||
if (Rig.btn_back.delta == +1)
|
if (Rig.btn_back.delta == +1)
|
||||||
|
@ -58,6 +60,13 @@ static class Mono
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UI.WindowBegin("test toggles", ref windowPoseButton);
|
||||||
|
if (UI.Button(ColorCube.toggle ? "color frame" : "color face"))
|
||||||
|
ColorCube.toggle = !ColorCube.toggle;
|
||||||
|
if (UI.Button(Stretch.toggle ? "con dir" : "stretch dir"))
|
||||||
|
Stretch.toggle = !Stretch.toggle;
|
||||||
|
UI.WindowEnd();
|
||||||
|
|
||||||
// flatscreen dev controls
|
// flatscreen dev controls
|
||||||
if (Device.Name == "Simulator")
|
if (Device.Name == "Simulator")
|
||||||
{
|
{
|
||||||
|
@ -111,7 +120,7 @@ static class Mono
|
||||||
{
|
{
|
||||||
if (Rig.btn_l_grip.delta == +1)
|
if (Rig.btn_l_grip.delta == +1)
|
||||||
{
|
{
|
||||||
grab.OnGrab(ref Rig.l_hnd, ref Rig.l_held);
|
grab.OnGrab(ref Rig.l_con, ref Rig.l_held);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +141,7 @@ static class Mono
|
||||||
{
|
{
|
||||||
if (Rig.btn_r_grip.delta == +1)
|
if (Rig.btn_r_grip.delta == +1)
|
||||||
{
|
{
|
||||||
grab.OnGrab(ref Rig.r_hnd, ref Rig.r_held);
|
grab.OnGrab(ref Rig.r_con, ref Rig.r_held);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
src/Rig.cs
22
src/Rig.cs
|
@ -6,8 +6,8 @@ static class Rig
|
||||||
{
|
{
|
||||||
public static Pose head = Pose.Identity;
|
public static Pose head = Pose.Identity;
|
||||||
|
|
||||||
public static Hand l_hnd;
|
public static Hand l_hnd, r_hnd;
|
||||||
public static Hand r_hnd;
|
public static Controller l_con, r_con;
|
||||||
|
|
||||||
public static DeltaBool btn_select = new(false);
|
public static DeltaBool btn_select = new(false);
|
||||||
public static DeltaBool btn_l_grip = new(false);
|
public static DeltaBool btn_l_grip = new(false);
|
||||||
|
@ -17,8 +17,6 @@ static class Rig
|
||||||
public static Grab? l_held = null;
|
public static Grab? l_held = null;
|
||||||
public static Grab? r_held = null;
|
public static Grab? r_held = null;
|
||||||
|
|
||||||
public static Pose l_hld, l_aim, r_hld, r_aim;
|
|
||||||
|
|
||||||
public static Vec3 fullstick = Vec3.Up;
|
public static Vec3 fullstick = Vec3.Up;
|
||||||
public static Pose r_con_stick = Pose.Identity;
|
public static Pose r_con_stick = Pose.Identity;
|
||||||
|
|
||||||
|
@ -26,7 +24,8 @@ static class Rig
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
|
l_con = new();
|
||||||
|
r_con = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frame()
|
public static void Frame()
|
||||||
|
@ -62,21 +61,16 @@ static class Rig
|
||||||
// [!] hand input simulates controller...
|
// [!] hand input simulates controller...
|
||||||
|
|
||||||
l_hnd = Input.Hand(Handed.Left);
|
l_hnd = Input.Hand(Handed.Left);
|
||||||
Controller l_con = Input.Controller(Handed.Left);
|
l_con = Input.Controller(Handed.Left);
|
||||||
// l_hld = l_con.pose;
|
|
||||||
l_hld = l_hnd.palm;
|
|
||||||
// l_aim = l_con.aim;
|
|
||||||
|
|
||||||
r_hnd = Input.Hand(Handed.Right);
|
r_hnd = Input.Hand(Handed.Right);
|
||||||
Controller r_con = Input.Controller(Handed.Right);
|
r_con = Input.Controller(Handed.Right);
|
||||||
// r_hld = r_con.pose;
|
|
||||||
r_hld = r_hnd.palm;
|
|
||||||
// r_aim = r_con.aim;
|
|
||||||
|
|
||||||
|
|
||||||
btn_l_grip.Step(l_con.grip > 0.5f || l_hnd.IsGripped);
|
btn_l_grip.Step(l_con.grip > 0.5f || l_hnd.IsGripped);
|
||||||
btn_r_grip.Step(r_con.grip > 0.5f || r_hnd.IsGripped);
|
btn_r_grip.Step(r_con.grip > 0.5f || r_hnd.IsGripped);
|
||||||
|
|
||||||
|
// double grip?
|
||||||
|
|
||||||
btn_select.Step(r_con.x1.IsActive() || r_con.trigger > 0.5f);
|
btn_select.Step(r_con.x1.IsActive() || r_con.trigger > 0.5f);
|
||||||
btn_back.Step(r_con.x2.IsActive());
|
btn_back.Step(r_con.x2.IsActive());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue