diff --git a/app/Glove.cs b/app/Glove.cs index c9bf88e..ef08461 100644 --- a/app/Glove.cs +++ b/app/Glove.cs @@ -23,7 +23,7 @@ public class Glove { float stretchDeadzone = 0; Vec3 pullPoint; - float twist; + public float twist; bool twistOut; Quat twistOffset; Quat oldOri; diff --git a/app/Mono.cs b/app/Mono.cs index c574e95..b93d5dc 100644 --- a/app/Mono.cs +++ b/app/Mono.cs @@ -56,12 +56,8 @@ public class Mono { Renderer.SetClip(0.02f, 1000f); } - Vec3 pos = new Vec3(0f, 0f, 0f); - Quat ori = Quat.Identity; - float yy = 0f; + Vec3 boardDir = Vec3.Forward; public void Step() { - Renderer.CameraRoot = Matrix.TR(pos, ori); - rig.Step(); scene.Step(); @@ -81,44 +77,59 @@ public class Mono { //// + // °board - // trigger & stick.x will be remapped to tracked motions next - - // str = 100± + // handling = 200± // speed = 10± - // con.grip.frameDown: handleCon = con + // board.dir = Vec3.fwd - // turn = handleCon.stick.x - // rig.rot *= Quat(0f, turn * strength * delta, 0f); + // con.grip.frameDown: + // handle = con - // accel = handleCon.trigger - // rig.pos += boardDir * accel * speed * delta + // board.pos = FloorCenter + // newDir = handle.pos.X0Z - board.pos.X0Z + // board.dir = newDir.MagSq > 0.001f ? newDir.normalized : board.dir + // board.ori = Quat.LookDir(board.dir) - // board.pos = rig.floorCenter + rig.pos - // board.dir = (handleCon.pos.X0Z - board.pos.X0Z).normalized - // board.rot = Quat(board.dir, Vec3.up) + // twist = handle.grip * -(Quat.LookDir(board.dir).Inverse * handle.backhandDir).x + // rig.ori *= Quat(0, twist * handling * delta, 0) + + // accel = handle.trigger + // rig.pos += board.dir * accel * speed * delta - Con handleCon = rig.HandleCon(); - Vec3 boardDir = (handleCon.pos.X0Z - pos.X0Z).Normalized; - Quat boardRot = Quat.LookDir(boardDir); - pos += boardDir * handleCon.device.trigger * Time.Elapsedf; - yy += handleCon.device.stick.x * 90 * Time.Elapsedf; - ori = Quat.FromAngles(0f, yy, 0f); // stick.x -> twist z + // °board + float handling = 200; + float speed = 10; + + Vec3 boardPos = rig.FloorCenter; + Vec3 newDir = rig.HandleCon.pos.X0Z - boardPos.X0Z; + boardDir = newDir.MagnitudeSq > 0.001f ? newDir.Normalized : boardDir; + Quat boardOri = Quat.LookDir(boardDir); + + float twist = rig.HandleCon.device.grip * -(Quat.LookDir(boardDir).Inverse * rig.HandleCon.backhandDir).x; + rig.ori *= Quat.FromAngles(0f, twist * handling * Time.Elapsedf, 0f); + + float accel = rig.HandleCon.device.trigger; + rig.pos += boardDir * accel * speed * Time.Elapsedf; + + // Lines.Add(rig.HandleCon.pos, rig.HandleCon.pos + rig.HandleCon.backhandDir, Color.White, 0.01f); + Mesh.Cube.Draw(Material.Default, Matrix.TRS(boardPos, boardOri, new Vec3(0.18f, 0.06f, 0.6f))); + + // DEPRECATED + // PullRequest.Slerp(boardDir.Normalized, handleDelta.Normalized, handleDelta.Magnitude * handling * Time.Elapsedf) : boardDir; + // Quat from = Quat.LookAt(rig.Head.position, rig.HandleCon.pos); + // Lines.Add(rig.HandleCon.pos, rig.HandleCon.pos + from * Vec3.Up, Color.Black, 0.01f); - Vec3 boardPos = pos.X0Z + Vec3.Up * -1.35f; // rig.Head().position.X0Z - Mesh.Cube.Draw(Material.Default, Matrix.TRS(boardPos, boardRot, new Vec3(0.18f, 0.06f, 0.6f))); + // does the FloorCenter move with the CameraRoot? // having a board underneath my feet and a virtual handlebar in my hand // did a lot to improve the quality of the experience (+immersion -sickness) + // the ability and quality at which this can be propagated is higher than I first imagined - // don't do more just yet! - // these are all important, but lets start small and scrappy + it's 9AM - // twist turning - // handleCon - // tighter boardDir + // next? // lean turning (head moving in relation to hand, doesn't that happen a little already?) // ------------------------------------------------- diff --git a/app/PullRequest.cs b/app/PullRequest.cs index 1e65dcf..0c4f7fa 100644 --- a/app/PullRequest.cs +++ b/app/PullRequest.cs @@ -88,6 +88,17 @@ public static class PullRequest { return a + (b - a) * t; } + public static Vec3 Slerp(Vec3 a, Vec3 b, float t) { + // spherical linear interpolation + float dot = Vec3.Dot(a, b); + if (dot > 0.9995f) { + return Vec3.Lerp(a, b, t); + } + float theta = (float)Math.Acos(dot); + float sinTheta = (float)Math.Sin(theta); + return Vec3.Lerp(a * (float)Math.Sin(theta - theta * t) / sinTheta, b * (float)Math.Sin(theta * t) / sinTheta, t); + } + static Pose _pose = new Pose(); public static Pose WorldPose(this Pose pose, float scale = 1) { return pose; diff --git a/app/Rig/Rig.cs b/app/Rig/Rig.cs index f1375d9..5c356c6 100644 --- a/app/Rig/Rig.cs +++ b/app/Rig/Rig.cs @@ -2,23 +2,36 @@ using System; using StereoKit; public class Rig { - public Mic mic; + public Mic mic = new Mic(); + public Vec3 pos = new Vec3(0, 0, 0); + public Quat ori = Quat.Identity; public Rig() { - mic = new Mic(); + if (World.HasBounds) { + // pos.XZ = World.BoundsPose.position.XZ; + // pos.y = World.BoundsPose.position.y; + // ori = World.BoundsPose.orientation; + } } - public Con rCon = new Con(), lCon = new Con(); - public Con Con(bool chirality) { return chirality ? rCon : lCon; } - bool handleChirality = false; - public Con HandleCon() { - return Con(handleChirality); + // public Vec3 center; + // public void Recenter() { + // center = World.BoundsPose.position.X0Z - Head.position.X0Z; + // } + + public Vec3 FloorCenter { + get { + if (World.HasBounds) { return World.BoundsPose.position; } + return new Vec3(0, 0, 0); + } } - public Pose Head() { - Pose pose = Input.Head; - pose.position += pose.orientation * Vec3.Forward * -0.1f; - return pose; + public Pose Head { + get { + Pose pose = Input.Head; // between eyes pose + pose.position += pose.orientation * Vec3.Forward * -0.1f; + return pose; + } } public Pose rShoulder, lShoulder; @@ -27,7 +40,17 @@ public class Rig { public Pose rWrist, lWrist; public Pose Wrist(bool chirality) { return chirality ? rWrist : lWrist; } + public Con rCon = new Con(), lCon = new Con(); + public Con Con(bool chirality) { return chirality ? rCon : lCon; } + bool handleChirality = false; + public Con HandleCon { + get { return Con(handleChirality); } + } + + public void Step() { + Renderer.CameraRoot = Matrix.TR(pos, ori); + // Controllers rCon.Step(true); lCon.Step(false); @@ -63,6 +86,7 @@ public class Con { public Controller device; public Vec3 pos; public Quat ori; + public Vec3 backhandDir; public Btn gripBtn; public Btn triggerBtn; @@ -70,6 +94,7 @@ public class Con { device = Input.Controller(chirality ? Handed.Right : Handed.Left); pos = device.pose.position; ori = device.aim.orientation; + backhandDir = ori * (chirality ? Vec3.Right : -Vec3.Right); gripBtn.Step(device.grip > 0.5f); triggerBtn.Step(device.trigger > 0.5f); }