From 28afb4da83a4f54e7024acf4e2c622eb7ac532a7 Mon Sep 17 00:00:00 2001 From: spatialfree Date: Sun, 5 Dec 2021 17:50:28 -0500 Subject: [PATCH] sdfs and rails --- Assets/crown.hlsl | 59 +++++++++ Assets/example.hlsl | 43 ------- Assets/oriel.hlsl | 184 ++++++++++++++++++++------- MonoNet.cs | 248 +++++++++++++++++++++++++++---------- Program.cs | 295 +++++++++++++++++++++++++++++--------------- SpatialCursor.cs | 38 ++++-- oriels.csproj | 4 +- 7 files changed, 608 insertions(+), 263 deletions(-) create mode 100644 Assets/crown.hlsl delete mode 100644 Assets/example.hlsl diff --git a/Assets/crown.hlsl b/Assets/crown.hlsl new file mode 100644 index 0000000..e6d477f --- /dev/null +++ b/Assets/crown.hlsl @@ -0,0 +1,59 @@ +#include "stereokit.hlsli" + +//--name = dofdev/crown + +float _height; +float _ypos; + +struct vsIn { + float4 pos : SV_POSITION; + float3 norm : NORMAL0; + float2 uv : TEXCOORD0; + float4 col : COLOR0; +}; +struct psIn { + float4 pos : SV_POSITION; + float3 campos : NORMAL0; + float3 world : NORMAL1; + float3 norm : NORMAL2; + 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; + + o.campos = sk_camera_pos[o.view_id].xyz; + o.world = mul(input.pos, sk_inst[id].world).xyz; + o.pos = mul(float4(o.world, 1), sk_viewproj[o.view_id]); + o.norm = normalize(mul(input.norm, (float3x3)sk_inst[id].world)); + + o.uv = input.uv; + o.color = input.col; + float lighting = dot(o.norm, normalize(float3(-0.3, 0.6, 0.1))); + lighting = (clamp(lighting, 0, 1) * 0.8) + 0.2; + o.color.rgb = o.color.rgb * lighting; // * sk_inst[id].color; + return o; +} + +float3 cross(float3 a, float3 b) { + return float3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +} + +float dot(float3 a, float3 b) { + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +float4 ps(psIn input) : SV_TARGET { + float4 col = float4(0, 0, 0, 0); + if (input.world.y - _ypos > (_height / 2.0) - 0.06) { + col = float4(1,1,1,1) * 0.25 * dot(input.world, input.norm); + if (input.norm.y > 0) { + col = float4(1,1,1,1) * 0.025; + } + } + return col; +} \ No newline at end of file diff --git a/Assets/example.hlsl b/Assets/example.hlsl deleted file mode 100644 index fd0258c..0000000 --- a/Assets/example.hlsl +++ /dev/null @@ -1,43 +0,0 @@ -#include "stereokit.hlsli" - -//--name = dofdev/unlit -//--color:color = 1, 1, 1, 1 -//--diffuse = white -float4 color; -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]); - - o.uv = input.uv; - o.color = input.col * color * sk_inst[id].color; - o.color = float4(0, 1, 1, 1); - return o; -} -float4 ps(psIn input) : SV_TARGET { - - float4 col = diffuse.Sample(diffuse_s, input.uv); - - col = col * input.color; - - return col; -} \ No newline at end of file diff --git a/Assets/oriel.hlsl b/Assets/oriel.hlsl index 9d0b817..3967d26 100644 --- a/Assets/oriel.hlsl +++ b/Assets/oriel.hlsl @@ -4,8 +4,15 @@ // float4 color; float _height; float _ypos; -Texture2D tex : register(t0); -SamplerState tex_s : register(s0); +float3 _dimensions; +float3 _center; +Texture2D tex; // : register(t0); +SamplerState tex_s; // : register(s0); + +cbuffer BufferData : register(b3) { + float3 windDirection; + float windStrength; +}; struct vsIn { float4 pos : SV_POSITION; @@ -49,52 +56,143 @@ float dot(float3 a, float3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } -float tri_raycast(float3 origin, float3 dir, float3 v0) { - float final = -1; - float3 v1 = float3(0, 0, 1); - float3 v2 = float3(1, 0, 0); - float3 e1 = v1 - v0; - float3 e2 = v2 - v0; - float3 h = cross(dir, e2); - float a = dot(e1, h); - if (a > -0.00001 && a < 0.00001) {} else{ - float f = 1 / a; - float3 s = origin - v0; - float u = f * dot(s, h); - if (u < 0.0 || u > 1.0) {} else { - float3 q = cross(s, e1); - float v = f * dot(dir, q); - if (v < 0.0 || u + v > 1.0) {} else { - float t = f * dot(e2, q); - if (t > 0.00001) { final = 1.0;} // t - } - } - } - return final; +// float tri_raycast(float3 origin, float3 dir) { +// float final = -1; +// float3 v0 = tri[0].xyz; +// float3 v1 = tri[1].xyz; +// float3 v2 = tri[2].xyz; +// float3 e1 = v1 - v0; +// float3 e2 = v2 - v0; +// float3 h = cross(dir, e2); +// float a = dot(e1, h); +// if (a > -0.00001 && a < 0.00001) {} else{ +// float f = 1 / a; +// float3 s = origin - v0; +// float u = f * dot(s, h); +// if (u < 0.0 || u > 1.0) {} else { +// float3 q = cross(s, e1); +// float v = f * dot(dir, q); +// if (v < 0.0 || u + v > 1.0) {} else { +// float t = f * dot(e2, q); +// if (t > 0.00001) { final = 1.0;} // t +// } +// } +// } +// return final; +// } + +float sdSphere(float3 p, float s) { + return length(p) - s; } -float4 ps(psIn input) : SV_TARGET { - // if (input.world.y - _ypos > (_height / 2.0) - 0.06) { - // // brighten; - // input.color.r += (1.0 - input.color.r) / 2.0; - // input.color.g += (1.0 - input.color.g) / 2.0; - // input.color.b += (1.0 - input.color.b) / 2.0; - // return input.color; - // } +float sdPlane(float3 p, float3 n, float h) +{ + // n must be normalized + return dot(p,n) + h; +} - // clamp how dark the object is *hsv - // float value = input.color.r * 0.3 + input.color.g * 0.59 + input.color.b * 0.11; - // blue tint - input.color.r /= 5.0; - input.color.g /= 5.0; - // input.color.a = 0.5; +float sdBox(float3 p, float3 b) +{ + float3 q = abs(p) - b; + return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0); +} - // raycast or raymarch - float4 col = tex.Sample(tex_s, float2(0.01, 0.01)); - float3 v0 = float3(0, col.r, 0); - float3 ray = normalize(input.world - input.campos); - input.color = float4(float3(1,1,1) * max(tri_raycast(input.world, ray, v0), 0.0), 1); +float sdOctahedron(float3 p, float s) +{ + p = abs(p); + return (p.x + p.y + p.z - s) * 0.57735027; +} + +float map(float3 pos) { + float sphere = sdSphere(pos + float3(0, 0.5, 0), 0.1); + // return sdLink(pos, 0.1, 0.1, 0.1); + float octo = sdOctahedron(pos, 0.1); + // return lerp(sphere, octo, windStrength); + + float plane = sdPlane(pos, float3(0, 1, 0), 0); + + float phere = lerp(plane, sphere, windStrength); + return min(phere, octo); +} + +float3 calcNormal(float3 pos) +{ + float2 e = float2(1.0, -1.0) * 0.5773; + float eps = 0.0005; + return normalize( + e.xyy * map(pos + e.xyy * eps) + + e.yyx * map(pos + e.yyx * eps) + + e.yxy * map(pos + e.yxy * eps) + + e.xxx * map(pos + e.xxx * eps) + ); +} + +float calcAO(float3 pos, float3 nor) +{ + float occ = 0.0; + float sca = 1.0; + for (int i = 0; i < 5; i++) { + float h = 0.01 + 0.12 * float(i)/4.0; + float d = map(pos + h * nor).x; + occ += (h - d) * sca; + sca *= 0.95; + if (occ > 0.35) break; + } + return clamp(1.0 - 3.0 * occ, 0.0, 1.0) * (0.5 + 0.5 * nor.y); +} + + +// float RayMarch(vec3 ro, vec3 rd) { +// float dO=0.; + +// for(int i=0; iMAX_DIST || dS 0.0)) { + ro = input.campos; + // always cull front + // then replace the input.world with a raymarched box position + // brings hands into the space + } + float3 rd = normalize(input.world - input.campos); // ray direction + // input.color = float4(float3(1,1,1) * max(tri_raycast(input.world, ray), 0.0), 1); + + // raymarch + float tmax = 3.0; + float t = 0.0; + for (int i = 0; i < 256; i++) { + float3 pos = ro + t * rd; + float h = map(pos); + if (h < 0.0001 || t > tmax) break; + t += h; + } + + // shading/lighting + float3 col = float3(0.0, 0.0, 0.0); + if (t < tmax) + { + float3 pos = ro + t * rd; + float3 nor = calcNormal(pos); + float dif = clamp(dot(nor, float3(0.7, 0.6, 0.4)), 0.0, 1.0); + float amb = 0.5 + 0.5 * dot(nor, float3(0.0, 0.8, 0.6)); + float ao = calcAO(pos, nor); + dif *= ao; + col = float3(0.2, 0.3, 0.4) * amb + float3(0.8, 0.7, 0.5) * dif; + } + + // input.color = float4(float3(1,1,1) * max(t, 0.0), 1); + input.color = float4(col, 1); + + // input.color = float4(float3(1,1,1) * sdSphere(input.uv, float2(0.2, 0.2), float2(0.8, 0.8)), 1); + // input.color.r = rr; return input.color; } \ No newline at end of file diff --git a/MonoNet.cs b/MonoNet.cs index 9c6521e..7176ca9 100644 --- a/MonoNet.cs +++ b/MonoNet.cs @@ -85,15 +85,17 @@ public class MonoNet { Console.WriteLine("too many peers"); return; } - peers[index].lastPing = Time.Totalf; - peers[index].cursorA = ReadVec3(); - peers[index].cursorB = ReadVec3(); - peers[index].cursorC = ReadVec3(); - peers[index].cursorD = ReadVec3(); + peers[index].color = ReadColor(); + peers[index].cursor0 = ReadVec3(); + peers[index].cursor1 = ReadVec3(); + peers[index].cursor2 = ReadVec3(); + peers[index].cursor3 = ReadVec3(); peers[index].headset = ReadPose(); peers[index].offHand = ReadPose(); peers[index].mainHand = ReadPose(); ReadBlock(ref peers[index].blocks); + + peers[index].lastPing = Time.Totalf; } } @@ -112,10 +114,11 @@ public class MonoNet { while (running) { wHead = 0; WriteInt(me.id); - WriteVec3(me.cursorA); - WriteVec3(me.cursorB); - WriteVec3(me.cursorC); - WriteVec3(me.cursorD); + WriteColor(me.color); + WriteVec3(me.cursor0); + WriteVec3(me.cursor1); + WriteVec3(me.cursor2); + WriteVec3(me.cursor3); WritePose(me.headset); WritePose(me.offHand); WritePose(me.mainHand); @@ -201,6 +204,24 @@ public class MonoNet { WriteQuat(pose.orientation); } + Color ReadColor() { + Color color = new Color( + BitConverter.ToSingle(rData, rHead), + BitConverter.ToSingle(rData, rHead + 4), + BitConverter.ToSingle(rData, rHead + 8), + BitConverter.ToSingle(rData, rHead + 12) + ); + rHead += 16; + return color; + } + void WriteColor(Color color) { + BitConverter.GetBytes(color.r).CopyTo(wData, wHead); + BitConverter.GetBytes(color.g).CopyTo(wData, wHead + 4); + BitConverter.GetBytes(color.b).CopyTo(wData, wHead + 8); + BitConverter.GetBytes(color.a).CopyTo(wData, wHead + 12); + wHead += 16; + } + void ReadBlock(ref Block[] blocks) { for (int i = 0; i < blocks.Length; i++) { bool bActive = ReadBool(); @@ -219,6 +240,32 @@ public class MonoNet { } } + void ReadCubic(ref Cubic[] cubics) { + for (int i = 0; i < cubics.Length; i++) { + bool bActive = ReadBool(); + Color color = ReadColor(); + Vec3 p0 = ReadVec3(); + Vec3 p1 = ReadVec3(); + Vec3 p2 = ReadVec3(); + Vec3 p3 = ReadVec3(); + if (bActive) { + cubics[i].Enable(p0, p1, p2, p3, color); + } else { + cubics[i].Disable(); + } + } + } + void WriteBlock(Cubic[] cubics) { + for (int i = 0; i < cubics.Length; i++) { + WriteBool(cubics[i].active); + WriteColor(cubics[i].color); + WriteVec3(cubics[i].p0); + WriteVec3(cubics[i].p1); + WriteVec3(cubics[i].p2); + WriteVec3(cubics[i].p3); + } + } + string localIP, publicIP; void GetIPs() { using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0)) { @@ -229,51 +276,6 @@ public class MonoNet { publicIP = new WebClient().DownloadString("https://ipv4.icanhazip.com/").TrimEnd(); } - public class Block { - public static Mesh mesh = Default.MeshCube; - public static Material mat = Default.Material; - - public bool active = false; - public Solid solid; - - public Color color; - - // if you grab someone else's it becomes your own - // how to communicate to the other peer that you have grabbed it? - // public int request; // request ownership - // public int owner; // then if owner continue as usual - // public bool busy; // marked as held so no fighting - public Block(SolidType type, Color color) { - this.solid = new Solid(Vec3.Zero, Quat.Identity, type); - this.solid.AddBox(Vec3.One, 1); - this.color = color; - Disable(); - } - - // public Block(Vec3 pos, Quat rot, SolidType type, Color color) { - // this.solid = new Solid(pos, rot, type); - // this.solid.AddBox(Vec3.One, 1); - // this.color = color; - // } - - public void Enable(Vec3 pos, Quat rot) { - solid.SetAngularVelocity(Vec3.Zero); - solid.SetVelocity(Vec3.Zero); - solid.Teleport(pos, rot); - solid.Enabled = active = true; - } - - public void Disable() { - solid.Enabled = active = false; - } - - public void Draw() { - if (active) { - mesh.Draw(mat, solid.GetPose().ToMatrix(), color); - } - } - } - public class Peer { @@ -284,11 +286,13 @@ public class MonoNet { public float lastPing; public int id; - public Vec3 cursorA, cursorB, cursorC, cursorD; + public Color color; + public Vec3 cursor0, cursor1, cursor2, cursor3; public Pose headset; public Pose offHand; public Pose mainHand; public Block[] blocks; + public Cubic[] cubics; // public Sound voice; // public SoundInst voiceInst; // update position @@ -299,8 +303,17 @@ public class MonoNet { new Block(type, color), new Block(type, color), new Block(type, color), + new Block(type, color), new Block(type, color) }; + cubics = new Cubic[] { + new Cubic(), + new Cubic(), + new Cubic(), + new Cubic(), + new Cubic(), + new Cubic() + }; // voice = Sound.CreateStream(0.5f); // voiceInst = voice.Play(Vec3.Zero, 0.5f); } @@ -308,10 +321,14 @@ public class MonoNet { BlockCon dBlock = new BlockCon(); BlockCon sBlock = new BlockCon(); + CubicCon cubicCon = new CubicCon(); + public void Step(Controller domCon, Controller subCon) { - dBlock.Step(domCon, cursorA, ref sBlock, ref blocks); - sBlock.Step(subCon, cursorB, ref dBlock, ref blocks); - + dBlock.Step(domCon, cursor0, ref sBlock, ref blocks); + sBlock.Step(subCon, cursor3, ref dBlock, ref blocks); + + cubicCon.Step(domCon, subCon, this, ref cubics); + Draw(false); } @@ -331,6 +348,7 @@ public class MonoNet { break; } } + blocks[PullRequest.RandomRange(0, blocks.Length)].Enable(cursor, Quat.Identity); } else { blocks[index].Disable(); index = -1; @@ -405,24 +423,124 @@ public class MonoNet { } } + class CubicCon { + public void Step(Controller domCon, Controller subCon, Peer peer, ref Cubic[] cubics) { + bool place = domCon.IsX2JustPressed; + if (place) { + for (int i = 0; i < cubics.Length; i++) { + if (!cubics[i].active) { + cubics[i].Enable(peer.cursor0, peer.cursor1, peer.cursor2, peer.cursor3, peer.color); + break; + } + } + cubics[PullRequest.RandomRange(0, cubics.Length)].Enable(peer.cursor0, peer.cursor1, peer.cursor2, peer.cursor3, peer.color); + } + } + } + public void Draw(bool body) { if (body){ - Cube(Matrix.TRS(cursorA, Quat.Identity, Vec3.One * 0.05f)); - Cube(headset.ToMatrix(Vec3.One * 0.3f)); - Cube(offHand.ToMatrix(Vec3.One * 0.1f)); - Cube(mainHand.ToMatrix(Vec3.One * 0.1f)); + Cube(Matrix.TRS(cursor0, Quat.Identity, Vec3.One * 0.05f), color); + Cube(headset.ToMatrix(Vec3.One * 0.3f), color); + Cube(offHand.ToMatrix(Vec3.One * 0.1f), color); + Cube(mainHand.ToMatrix(Vec3.One * 0.1f), color); + + Bezier.Draw(cursor0, cursor1, cursor2, cursor3, Color.White); } // cubicFlow.Draw(peer.cursorA, peer.cursorB, peer.cursorC, peer.cursorD); for (int i = 0; i < blocks.Length; i++) { - blocks[i].Draw(); + if (blocks[i].solid.GetPose().position.y < -10) { + blocks[i].Disable(); + } else { + blocks[i].Draw(); + } + } + + for (int i = 0; i < cubics.Length; i++) { + cubics[i].Draw(); } } static Mesh meshCube = Default.MeshCube; static Material matCube = Default.Material; - public void Cube(Matrix m) { - meshCube.Draw(matCube, m); + public void Cube(Matrix m, Color color) { + meshCube.Draw(matCube, m, color); } } } + +public class Block { + public static Mesh mesh = Default.MeshCube; + public static Material mat = Default.Material; + + public bool active = false; + public Solid solid; + + public Color color; + + // if you grab someone else's it becomes your own + // how to communicate to the other peer that you have grabbed it? + // public int request; // request ownership + // public int owner; // then if owner continue as usual + // public bool busy; // marked as held so no fighting + public Block(SolidType type, Color color) { + this.solid = new Solid(Vec3.Zero, Quat.Identity, type); + this.solid.AddBox(Vec3.One, 3); + this.color = color; + Disable(); + } + + // public Block(Vec3 pos, Quat rot, SolidType type, Color color) { + // this.solid = new Solid(pos, rot, type); + // this.solid.AddBox(Vec3.One, 1); + // this.color = color; + // } + + public void Enable(Vec3 pos, Quat rot) { + solid.SetAngularVelocity(Vec3.Zero); + solid.SetVelocity(Vec3.Zero); + solid.Teleport(pos, rot); + solid.Enabled = active = true; + } + + public void Disable() { + solid.Enabled = active = false; + } + + public void Draw() { + if (active) { + mesh.Draw(mat, solid.GetPose().ToMatrix(), color); + } + } +} + +public class Cubic { + public bool active; + public Vec3 p0, p1, p2, p3; + public Color color; + + public Cubic() { + color = Color.White; + active = false; + } + + public void Enable(Vec3 p0, Vec3 p1, Vec3 p2, Vec3 p3, Color c) { + this.p0 = p0; + this.p1 = p1; + this.p2 = p2; + this.p3 = p3; + color = c; + active = true; + } + + public void Disable() { + active = false; + } + + public void Draw() { + if (active) { + Bezier.Draw(p0, p1, p2, p3, color); + } + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index e37e948..1694113 100644 --- a/Program.cs +++ b/Program.cs @@ -1,5 +1,6 @@ using StereoKit; using System; +using System.Runtime.InteropServices; class Program { static void Main(string[] args) { @@ -28,26 +29,31 @@ public class Mono { Mesh cube = Default.MeshCube; public void Run() { + Renderer.SetClip(0f, 100f); // mic = new Mic(); Vec3 pos = new Vec3(0, 0, 0); Vec3 vel = new Vec3(0, 0, 0); Solid floor = new Solid(Vec3.Up * -1.5f, Quat.Identity, SolidType.Immovable); - Vec3 floorScale = new Vec3(32f, 0.1f, 32f); + float scale = 64f; + Vec3 floorScale = new Vec3(scale, 0.1f, scale); floor.AddBox(floorScale); // box on each side - floor.AddBox(new Vec3(32f, 16f, 0.1f), 1, new Vec3(0, 8f, -16f)); - floor.AddBox(new Vec3(32f, 16f, 0.1f), 1, new Vec3(0, 8f, 16f)); - floor.AddBox(new Vec3(0.1f, 16f, 32f), 1, new Vec3(-16f, 8f, 0)); - floor.AddBox(new Vec3(0.1f, 16f, 32f), 1, new Vec3(16f, 8f, 0)); + floor.AddBox(new Vec3(scale, scale / 2, 0.1f), 1, new Vec3(0, scale / 4, -scale / 2)); + floor.AddBox(new Vec3(scale, scale / 2, 0.1f), 1, new Vec3(0, scale / 4, scale / 2)); + floor.AddBox(new Vec3(0.1f, scale / 2, scale), 1, new Vec3(-scale / 2, scale / 4, 0)); + floor.AddBox(new Vec3(0.1f, scale / 2, scale), 1, new Vec3(scale / 2, scale / 4, 0)); // and ceiling - floor.AddBox(new Vec3(32f, 0.1f, 32f), 1, new Vec3(0, 16f, 0)); + floor.AddBox(new Vec3(scale, 0.1f, scale), 1, new Vec3(0, scale / 2, 0)); Cursors cursors = new Cursors(this); Oriel oriel = new Oriel(); - oriel.Start(); + oriel.Start(3); + + Oriel otherOriel = new Oriel(); + otherOriel.Start(4); MonoNet net = new MonoNet(this); net.Start(); @@ -58,6 +64,8 @@ public class Mono { SpatialCursor cursor = new ReachCursor(); SpatialCursor subCursor = new ReachCursor(); + SpatialCursor cubicFlow = new CubicFlow(); + Tex camTex = new Tex(TexType.Rendertarget); camTex.SetSize(600, 400); Material camMat = new Material(Shader.Unlit); @@ -65,9 +73,20 @@ public class Mono { Mesh quad = Default.MeshQuad; + float grindDir = 1f; + bool grinding = false; + Vec3 grindVel = Vec3.Forward; + Vec3[] grindRail = new Vec3[4]; + + + Input.HandSolid(Handed.Right, false); + Input.HandSolid(Handed.Left, false); + while (SK.Step(() => { Renderer.CameraRoot = Matrix.T(pos); + cube.Draw(mat, floor.GetPose().ToMatrix(floorScale), Color.White * 0.666f); + if (lefty) { domCon = Input.Controller(Handed.Left); subCon = Input.Controller(Handed.Right); } else { domCon = Input.Controller(Handed.Right); subCon = Input.Controller(Handed.Left); } // if (subCon.IsX2JustPressed) { lefty = !lefty; } @@ -133,27 +152,79 @@ public class Mono { // new Vec3(0, 1, -4), // }; // Bezier.Draw(rail); - // if (subCon.IsX1JustPressed) { - // int closest = 0; - // float closestDist = float.MaxValue; - // Vec3 closestPoint = Vec3.Zero; - // for (int i = 0; i < rail.Length; i++) { - // Vec3 point = Bezier.Sample(rail, (float)i / (rail.Length - 1f)); - // float dist = Vec3.Distance(point, subCon.aim.position); - // if (dist < closestDist) { - // closest = i; - // closestDist = dist; - // closestPoint = point; - // railT = (float)i / (rail.Length - 1f); - // } - // } - // // pos = closestPoint - (subCon.aim.position - pos); - // } - // if (subCon.IsX1Pressed) { - // pos = Vec3.Lerp(pos, Bezier.Sample(rail, railT) - (subCon.aim.position - pos), Time.Elapsedf * 6f); - // railT += Time.Elapsedf * 0.1f; - // // how to reliably determine and control which direction to go? (velocity) - // } + + if (domCon.grip > 0.5f) { + if (!grinding) { + int closest = 0; + float closestDist = float.MaxValue; + Vec3 closestPoint = Vec3.Zero; + int closestRail = 0; + for (int i = 0; i < net.me.cubics.Length; i++) { + if (net.me.cubics[i].active) { + Vec3[] rail = new Vec3[] { + net.me.cubics[i].p0, + net.me.cubics[i].p1, + net.me.cubics[i].p2, + net.me.cubics[i].p3, + }; + for (int j = 0; j < rail.Length; j++) { + Vec3 point = Bezier.Sample(rail, (float)j / (rail.Length - 1f)); + float dist = Vec3.Distance(point, domCon.aim.position + domCon.aim.Forward * 0.2f); + if (dist < closestDist) { + closest = j; + closestRail = i; + closestDist = dist; + closestPoint = point; + railT = (float)j / (rail.Length - 1f); + grinding = true; + } + } + } + } + if (grinding) { + grindRail = new Vec3[] { + net.me.cubics[closestRail].p0, + net.me.cubics[closestRail].p1, + net.me.cubics[closestRail].p2, + net.me.cubics[closestRail].p3, + }; + // pos = closestPoint - (subCon.aim.position - pos); + grindVel = vel; + Vec3 fromPos = Bezier.Sample(grindRail[0], grindRail[1], grindRail[2], grindRail[3], railT); + Vec3 toPos = Bezier.Sample(grindRail[0], grindRail[1], grindRail[2], grindRail[3], railT + 0.1f); + grindDir = Vec3.Dot((fromPos - toPos).Normalized, grindVel) < 0f ? 1 : -1; + } + } + + if (grinding) { + Vec3 grindPos = Bezier.Sample(grindRail[0], grindRail[1], grindRail[2], grindRail[3], railT); + Vec3 nextPos = Bezier.Sample(grindRail[0], grindRail[1], grindRail[2], grindRail[3], railT + 0.1f * grindDir); + + // vel += (toPos - fromPos); + + pos = -(domCon.aim.position - Input.Head.position) + grindPos - (Input.Head.position - pos); + vel = Vec3.Zero; + + railT += Time.Elapsedf * grindVel.Magnitude * grindDir; + // bool clamped = false; + // float railTpreClamp = railT; + // if + railT = Math.Clamp(railT, 0f, 1f); + + grindVel = (nextPos - grindPos).Normalized * grindVel.Magnitude; + + + cube.Draw(mat, Matrix.TS(grindPos, new Vec3(0.1f, 0.1f, 0.1f))); + // cube.Draw(mat, Matrix.TS(toPos, new Vec3(0.1f, 0.1f, 0.1f) * 0.333f)); + // pos = Vec3.Lerp(pos, Bezier.Sample(net.me.cubics[0].p0, net.me.cubics[0].p1, net.me.cubics[0].p2, net.me.cubics[0].p3, railT) - (subCon.aim.position - pos), Time.Elapsedf * 6f); + // how to reliably determine and control which direction to go? (velocity) + } + } else { + if (grinding) { + vel = grindVel; + grinding = false; + } + } // Console.WriteLine(World.RefreshInterval.ToString()); @@ -164,7 +235,7 @@ public class Mono { domDragStart = domPos; } if (domCon.IsX1Pressed) { - vel += -(domPos - domDragStart) * 10; + vel += -(domPos - domDragStart) * 24; domDragStart = domPos; } @@ -174,7 +245,7 @@ public class Mono { subDragStart = subPos; } if (subCon.IsX1Pressed) { - vel += -(subPos - subDragStart) * 10; + vel += -(subPos - subDragStart) * 24; subDragStart = subPos; } @@ -188,39 +259,37 @@ public class Mono { // pos.x = (float)Math.Sin(Time.Total * 0.1f) * 0.5f; pos += vel * Time.Elapsedf; - float preX = pos.x; pos.x = Math.Clamp(pos.x, -16f, 16f); if (pos.x != preX) { vel.x = 0; } - float preY = pos.y; pos.y = Math.Clamp(pos.y, 0f, 16f); if (pos.y != preY) { vel.y = 0; } - float preZ = pos.z; pos.z = Math.Clamp(pos.z, -16f, 16f); if (pos.z != preZ) { vel.z = 0; } + float preX = pos.x; pos.x = Math.Clamp(pos.x, -scale / 2, scale / 2); if (pos.x != preX) { vel.x = 0; } + float preY = pos.y; pos.y = Math.Clamp(pos.y, 0f, scale / 2); if (pos.y != preY) { vel.y = 0; } + float preZ = pos.z; pos.z = Math.Clamp(pos.z, -scale / 2, scale / 2); if (pos.z != preZ) { vel.z = 0; } - vel *= 1 - Time.Elapsedf; + vel *= 1 - Time.Elapsedf * 0.2f; // COLOR CUBE // reveal when palm up - // float reveal = subCon.pose.Right.y * 2; - // colorCube.size = colorCube.ogSize * Math.Clamp(reveal, 0, 1); - // colorCube.center = subCon.pose.position + subCon.pose.Right * 0.0666f; - // // move with grip - // if (reveal > colorCube.thicc) { - // if (reveal > 1f && subCon.grip > 0.5f) { - // colorCube.p0 -= (subCon.pose.position - oldSubPos) / colorCube.ogSize * 2; - // } else { - // // clamp 0 - 1 - // colorCube.p0.x = Math.Clamp(colorCube.p0.x, -1, 1); - // colorCube.p0.y = Math.Clamp(colorCube.p0.y, -1, 1); - // colorCube.p0.z = Math.Clamp(colorCube.p0.z, -1, 1); - // } - // colorCube.Step(); - // } - // oldSubPos = subCon.pose.position; + float reveal = subCon.pose.Right.y * 2; + colorCube.size = colorCube.ogSize * Math.Clamp(reveal, 0, 1); + colorCube.center = subCon.pose.position + subCon.pose.Right * 0.0666f; + // move with grip + if (reveal > colorCube.thicc) { + if (reveal > 1f && subCon.grip > 0.5f) { + colorCube.p0 -= (subCon.pose.position - oldSubPos) / colorCube.ogSize * 2; + } else { + // clamp 0 - 1 + colorCube.p0.x = Math.Clamp(colorCube.p0.x, -1, 1); + colorCube.p0.y = Math.Clamp(colorCube.p0.y, -1, 1); + colorCube.p0.z = Math.Clamp(colorCube.p0.z, -1, 1); + } + colorCube.Step(); + } + oldSubPos = subCon.pose.position; - // for (int i = 0; i < net.me.blocks.Length; i++) { - // cube.Draw(mat, net.me.blocks[i].solid.GetPose().ToMatrix(), net.me.blocks[i].color); - // } - // cursor.Step(lHand.aim, rHand.aim); cursor.DrawSelf(); + cubicFlow.Step(new Pose[] {domCon.aim, subCon.aim}, 1); // net.me.cursorA = Vec3.Up * (float)Math.Sin(Time.Total); - net.me.cursorA = cursor.p0; net.me.cursorB = cursor.p1; - net.me.cursorC = cursor.p2; net.me.cursorD = cursor.p3; + net.me.color = colorCube.color; + net.me.cursor0 = cubicFlow.p0; net.me.cursor1 = cubicFlow.p1; + net.me.cursor2 = cubicFlow.p2; net.me.cursor3 = cubicFlow.p3; net.me.headset = Input.Head; net.me.mainHand = domCon.aim; net.me.offHand = subCon.aim; for (int i = 0; i < net.peers.Length; i++) { @@ -232,7 +301,12 @@ public class Mono { net.me.Step(domCon, subCon); - // oriel.Step(); + + + oriel.Step(); + + otherOriel.bounds.center = Vec3.Forward * -2; + otherOriel.Step(); // Matrix orbitMatrix = OrbitalView.transform; // cube.Step(Matrix.S(Vec3.One * 0.2f) * orbitMatrix); @@ -240,8 +314,6 @@ public class Mono { // cursor.Draw(Matrix.S(0.1f)); - cube.Draw(mat, floor.GetPose().ToMatrix(floorScale), Color.White * 0.666f); - // Renderer.RenderTo(camTex, Matrix.TR(Input.Head.position + Vec3.Up * 10, Quat.FromAngles(-90f, 0, 0)), Matrix.Orthographic(2f, 2f, 0.1f, 100f), RenderLayer.All, RenderClear.All); // quad.Draw(camMat, Matrix.TR(Input.Head.Forward, Quat.FromAngles(0, 180, 0))); @@ -410,60 +482,84 @@ public class Lerper { } } +[StructLayout(LayoutKind.Sequential)] +struct BufferData { + public Vec3 windDirection; + // public Vec3[] tri; + public float windStrength; +} public class Oriel { public Bounds bounds; Material mat = new Material(Shader.FromFile("oriel.hlsl")); + Material crown = new Material(Shader.FromFile("crown.hlsl")); Mesh mesh = Default.MeshCube; Mesh quad = Default.MeshQuad; Vec3 _dimensions; - public void Start() { + + MaterialBuffer buffer; + + public void Start(int bufferIndex) { bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f)); _dimensions = bounds.dimensions; + buffer = new MaterialBuffer(bufferIndex); } + BufferData data = new BufferData(); public void Step() { + data.windDirection = new Vec3( + (float)Math.Sin(Time.Total * 1) / 6, + (float)Math.Cos(Time.Total * 2) / 6, + (float)Math.Sin(Time.Total * 3) / 6 + ); + // data.a = new Color(1.0f, 0.5f, 0.5f); + // data.b = new Color(0.5f, 1.0f, 0.5f); + // data.c = new Color(0.5f, 0.5f, 1.0f); + // data.tri = new Vec3[] { + // new Vec3(0, 0, 0), + // new Vec3(0, 0, 1), + // new Vec3(1, 0, 0), + // }; + + data.windStrength = (1 + (float)Math.Sin(Time.Total)) / 2; + buffer.Set(data); + + // circle around center // bounds.center = Quat.FromAngles(0, 0, Time.Totalf * 60) * Vec3.Up * 0.3f; // bounds.dimensions = _dimensions * (1f + (MathF.Sin(Time.Totalf * 3) * 0.3f)); - mat.Transparency = Transparency.Blend; - mat.SetFloat("_height", bounds.dimensions.y); - mat.SetFloat("_ypos", bounds.center.y); - // mat.FaceCull = Cull.None; - mesh.Draw(mat, Matrix.TRS(bounds.center, Quat.Identity, bounds.dimensions)); - Pose head = Input.Head; - Vec3 quadPos = head.position + head.Forward * 0.04f; - if (bounds.Contains(head.position, quadPos)) { - quad.Draw(mat, Matrix.TRS(quadPos, Quat.LookAt(quadPos, head.position), Vec3.One * 0.5f)); - } - - // instead of a quad, just slap the rendered cube mesh to the head - - Vec3 vertex = new Vec3(0, ((float)Math.Sin(Time.Totalf) + 1) / 3, 0); - - int w = 3, h = 1; - Tex tex = new Tex(TexType.ImageNomips, TexFormat.Rgba32); - tex.SampleMode = TexSample.Point; - tex.SetSize(w, h); - Color32[] colors = new Color32[w * h]; - // tex.GetColors(ref colors); - for (int i = 0; i < colors.Length; i++) { - // convert vertex to color - int vv = (int)Math.Floor(vertex.y * 255); - - colors[i] = new Color( - Math.Clamp(vv, 0, 255), - Math.Clamp(vv - 256, 0, 255), - Math.Clamp(vv - 256 - 256, 0, 255), - Math.Clamp(vv - 256 - 256 - 256, 0, 255) - ); - // colors[i] = new Color32(0, 128, 0, 0); - } - tex.SetColors(w, h, colors); - mat.SetTexture("tex", tex); - // mat.SetMatrix("_matrix", Matrix.TRS(bounds.center, Quat.Identity, bounds.dimensions)); - // mat.Wireframe + mat.FaceCull = Cull.None; + mat.SetVector("_dimensions", bounds.dimensions); + mat.SetVector("_center", bounds.center); + // mat.Wireframe = true; + + Matrix m = Matrix.TRS(bounds.center, Quat.Identity, bounds.dimensions); + Pose head = Input.Head; + // Vec3 quadPos = head.position + head.Forward * 0.0021f; + // if (bounds.Contains(head.position, head.position, 0.036f)) { + // mat.FaceCull = Cull.Front; + // m = Matrix.TRS(head.position, head.orientation, new Vec3(1.0f, 0.5f, 0.0088f * 2)); + // Renderer. + // } + mesh.Draw(mat, m); + + // if (bounds.Contains(head.position, quadPos)) { + // quad.Draw(mat, Matrix.TRS(quadPos, Quat.LookAt(quadPos, head.position), Vec3.One * 0.5f)); + // } + + // instead of a quad, just slap the same mesh to the head + + + + crown.SetFloat("_height", bounds.dimensions.y); + crown.SetFloat("_ypos", bounds.center.y); + crown.FaceCull = Cull.Front; + crown.Transparency = Transparency.Add; + crown.DepthTest = DepthTest.Always; + // crown.QueueOffset = 0; + // crown.DepthWrite = false; + mesh.Draw(crown, Matrix.TRS(bounds.center, Quat.Identity, bounds.dimensions)); } } @@ -588,4 +684,9 @@ public static class PullRequest { axis.z = q.z / s; } } + + static Random r = new Random(); + public static int RandomRange(int min, int max) { + return r.Next(min, max); + } } diff --git a/SpatialCursor.cs b/SpatialCursor.cs index 579517f..188795f 100644 --- a/SpatialCursor.cs +++ b/SpatialCursor.cs @@ -69,9 +69,9 @@ public class ReachCursor : SpatialCursor { Vec3 dir = (pos - from).Normalized; p0 = pos + dir * stretch * str; - model.Draw(Matrix.TS(p0, 0.1f)); + // model.Draw(Matrix.TS(p0, 0.1f)); // model.Draw(Matrix.TS(shoulder.position, 0.06f)); - Lines.Add(from, p0, Color.White, 0.005f); + // Lines.Add(from, p0, Color.White, 0.005f); // model.Draw(Matrix.TS(from, 0.04f)); // Pose mainHand = poses[0]; @@ -79,7 +79,7 @@ public class ReachCursor : SpatialCursor { // Vec2 mid = Vec2.Lerp(lHand.position.XZ, rHand.position.XZ, 0.5f); - Lines.Add(from, p0, Color.White, 0.005f); + // Lines.Add(from, p0, Color.White, 0.005f); // Vec3 calib = shoulder.orientation.Inverse * (pos - shoulder.position); // if (calib.z > origin.z) { @@ -94,19 +94,21 @@ public class ReachCursor : SpatialCursor { public class TwistCursor : SpatialCursor { public TwistCursor() { this.min = 1f; - this.str = 3f; + this.str = 6f; this.max = 10f; } public override void Step(Pose[] poses, float scalar) { Vec3 pos = poses[0].position; Quat quat = poses[0].orientation; Quat rel = Quat.LookAt(Vec3.Zero, quat * Vec3.Forward); - float twist = (Vec3.Dot(rel * -Vec3.Right, quat * Vec3.Up) + 1) / 2; + float twist = (Vec3.Dot(rel * -Vec3.Right * scalar, quat * Vec3.Up) + 1) / 2; p0 = pos + quat * Vec3.Forward * twist * str; - model.Draw(Matrix.TS(p0, 0.02f)); + // model.Draw(Matrix.TS(p0, 0.02f)); } public override void Calibrate() { } + + public bool outty; } public class CubicFlow : SpatialCursor { @@ -121,16 +123,29 @@ public class CubicFlow : SpatialCursor { Pose dom = poses[0]; Pose sub = poses[1]; domTwist.Step(new Pose[] { dom }, scalar); - subTwist.Step(new Pose[] { sub }, scalar); + subTwist.Step(new Pose[] { sub }, -scalar); + p0 = dom.position; p1 = domTwist.p0; p2 = subTwist.p0; p3 = sub.position; + Controller domCon = Input.Controller(Handed.Right); + Controller subCon = Input.Controller(Handed.Left); + + Vec3 np0 = Vec3.Lerp(p0, p1, (1 + domCon.stick.y) / 2); + Vec3 np1 = Vec3.Lerp(p1, p0, (1 + domCon.stick.y) / 2); + Vec3 np2 = Vec3.Lerp(p2, p3, (1 + subCon.stick.y) / 2); + Vec3 np3 = Vec3.Lerp(p3, p2, (1 + subCon.stick.y) / 2); + + p0 = np0; + p1 = np1; + p2 = np2; + p3 = np3; // if toggle - Bezier.Draw(this.p0, this.p1, this.p2, this.p3); + Bezier.Draw(this.p0, this.p1, this.p2, this.p3, Color.White); } public override void Calibrate() {} @@ -167,7 +182,7 @@ public class SupineCursor : SpatialCursor { public static class Bezier { static int detail = 64; - public static void Draw(Vec3 p0, Vec3 p1, Vec3 p2, Vec3 p3) { + public static void Draw(Vec3 p0, Vec3 p1, Vec3 p2, Vec3 p3, Color color) { LinePoint[] bezier = new LinePoint[detail]; for (int i = 0; i < bezier.Length; i++) { float t = i / ((float)bezier.Length - 1); @@ -175,13 +190,10 @@ public static class Bezier { Vec3 b = Vec3.Lerp(p1, p2, t); Vec3 c = Vec3.Lerp(p2, p3, t); Vec3 pos = Vec3.Lerp(Vec3.Lerp(a, b, t), Vec3.Lerp(b, c, t), t); - bezier[i] = new LinePoint(pos, Color.White, 0.01f); + bezier[i] = new LinePoint(pos, color, 0.01f); } Lines.Add(bezier); } - public static void Draw(Vec3[] points) { - Draw(points[0], points[1], points[2], points[3]); - } public static Vec3 Sample(Vec3 p0, Vec3 p1, Vec3 p2, Vec3 p3, float t) { Vec3 a = Vec3.Lerp(p0, p1, t); diff --git a/oriels.csproj b/oriels.csproj index ce64084..c8f8f11 100644 --- a/oriels.csproj +++ b/oriels.csproj @@ -19,14 +19,14 @@ - + - +