sdfs and rails

This commit is contained in:
spatialfree 2021-12-05 17:50:28 -05:00
parent c504586c20
commit 28afb4da83
7 changed files with 608 additions and 263 deletions

59
Assets/crown.hlsl Normal file
View file

@ -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;
}

View file

@ -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;
}

View file

@ -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; i<MAX_STEPS; i++) {
// vec3 p = ro + rd*dO;
// float dS = GetDist(p);
// dO += dS;
// if(dO>MAX_DIST || dS<SURF_DIST) break;
// }
// return dO;
// }
float4 ps(psIn input) : SV_TARGET {
float3 ro = input.world; // ray origin
if (!(sdBox(input.campos, _dimensions / 2) > 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;
}

View file

@ -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);
}
}
}

View file

@ -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<BufferData> buffer;
public void Start(int bufferIndex) {
bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f));
_dimensions = bounds.dimensions;
buffer = new MaterialBuffer<BufferData>(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);
}
}

View file

@ -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);

View file

@ -19,14 +19,14 @@
</ItemGroup>
<ItemGroup>
<None Remove="Assets/example.hlsl" />
<None Remove="Assets/oriel.hlsl" />
<None Remove="Assets/crown.hlsl" />
<None Remove="Assets/colorcube.hlsl" />
</ItemGroup>
<ItemGroup>
<SKShader Include="Assets/example.hlsl" />
<SKShader Include="Assets/oriel.hlsl" />
<SKShader Include="Assets/crown.hlsl" />
<SKShader Include="Assets/colorcube.hlsl" />
</ItemGroup>