Merge branch 'main' of https://github.com/dofdev/oriels
This commit is contained in:
commit
7e1811a8d3
45 changed files with 306 additions and 454 deletions
|
@ -78,7 +78,7 @@ public class BlockCon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bFound) {
|
if (!bFound) {
|
||||||
blocks[PullRequest.RandomRange(0, blocks.Length)].Enable(cursor, Quat.Identity);
|
blocks[PR.RandomRange(0, blocks.Length)].Enable(cursor, Quat.Identity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
blocks[index].Disable();
|
blocks[index].Disable();
|
||||||
|
@ -139,7 +139,7 @@ public class BlockCon {
|
||||||
blocks[index].solid.Move(toPos, toRot);
|
blocks[index].solid.Move(toPos, toRot);
|
||||||
|
|
||||||
Quat newHeldRot = blocks[index].solid.GetPose().orientation;
|
Quat newHeldRot = blocks[index].solid.GetPose().orientation;
|
||||||
angularMomentum = Vec3.Lerp(angularMomentum, PullRequest.AngularDisplacement((newHeldRot * oldHeldRot.Inverse).Normalized), Time.Stepf / 0.1f);
|
angularMomentum = Vec3.Lerp(angularMomentum, PR.AngularDisplacement((newHeldRot * oldHeldRot.Inverse).Normalized), Time.Stepf / 0.1f);
|
||||||
oldHeldRot = newHeldRot;
|
oldHeldRot = newHeldRot;
|
||||||
|
|
||||||
delta = (cursor + (con.ori * heldRot * spinRot).Normalized * offset) - blocks[index].solid.GetPose().position;
|
delta = (cursor + (con.ori * heldRot * spinRot).Normalized * offset) - blocks[index].solid.GetPose().position;
|
|
@ -35,7 +35,7 @@ public class CubicCon {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Cubic cubic = cubics[PullRequest.RandomRange(0, cubics.Length)];
|
Cubic cubic = cubics[PR.RandomRange(0, cubics.Length)];
|
||||||
cubic.p0 = rPos;
|
cubic.p0 = rPos;
|
||||||
cubic.p1 = rig.rCon.pos;
|
cubic.p1 = rig.rCon.pos;
|
||||||
cubic.p2 = rig.lCon.pos;
|
cubic.p2 = rig.lCon.pos;
|
|
@ -356,7 +356,7 @@ public class Peer {
|
||||||
public void Draw(bool body) {
|
public void Draw(bool body) {
|
||||||
Mono mono = Mono.inst;
|
Mono mono = Mono.inst;
|
||||||
if (body) {
|
if (body) {
|
||||||
PullRequest.BlockOut(Matrix.TRS(headset.position + Input.Head.Forward * -0.15f, headset.orientation, Vec3.One * 0.3f), color);
|
PR.BlockOut(Matrix.TRS(headset.position + Input.Head.Forward * -0.15f, headset.orientation, Vec3.One * 0.3f), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bezier.Draw(
|
// Bezier.Draw(
|
||||||
|
@ -370,7 +370,7 @@ public class Peer {
|
||||||
for (int i = 0; i < blocks.Length; i++) {
|
for (int i = 0; i < blocks.Length; i++) {
|
||||||
NetBlock block = blocks[i];
|
NetBlock block = blocks[i];
|
||||||
if (block.active) {
|
if (block.active) {
|
||||||
PullRequest.BlockOut(block.pose.ToMatrix(block.scale), block.color);
|
PR.BlockOut(block.pose.ToMatrix(block.scale), block.color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
53
add/shaders/compositor.hlsl
Normal file
53
add/shaders/compositor.hlsl
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include "stereokit.hlsli"
|
||||||
|
|
||||||
|
//--name = dofdev/compositor
|
||||||
|
|
||||||
|
//--diffuse = white
|
||||||
|
|
||||||
|
Texture2D diffuse : register(t0);
|
||||||
|
SamplerState diffuse_s : register(s0);
|
||||||
|
|
||||||
|
struct vsIn {
|
||||||
|
float4 pos : SV_Position;
|
||||||
|
float3 norm : NORMAL0;
|
||||||
|
float2 uv : TEXCOORD0;
|
||||||
|
};
|
||||||
|
struct psIn {
|
||||||
|
float4 pos : SV_Position;
|
||||||
|
float3 world : WORLD;
|
||||||
|
float2 uv : TEXCOORD0;
|
||||||
|
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.world = mul(input.pos, sk_inst[id].world).xyz;
|
||||||
|
o.pos = mul(float4(o.world, 1), sk_viewproj[o.view_id]);
|
||||||
|
|
||||||
|
// float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
|
||||||
|
|
||||||
|
o.uv = input.uv;
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 ps(psIn input) : SV_TARGET {
|
||||||
|
float depth = diffuse.Sample(diffuse_s, input.uv).r;
|
||||||
|
// 16 bit DepthTexture *non-linear* depth
|
||||||
|
// render depth for debug
|
||||||
|
|
||||||
|
if (depth > 0.0) {
|
||||||
|
depth = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// float4 og = mul(float4(input.world, 1), sk_viewproj[input.view_id]);
|
||||||
|
// float depth = (og * rcp(og.w)).z;
|
||||||
|
|
||||||
|
return float4(depth, depth, depth, 1);
|
||||||
|
// float v = -rcp(-val.r);
|
||||||
|
// v = val.r;
|
||||||
|
// return float4(v, v, v, 1);
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7</TargetFramework>
|
||||||
<SKAssetFolder>add</SKAssetFolder>
|
<SKAssetFolder>add</SKAssetFolder>
|
||||||
<SKAssetDestination>add</SKAssetDestination>
|
<SKAssetDestination>add</SKAssetDestination>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class Mono {
|
||||||
Oriels.Rig rig = Oriels.Mono.inst.rig;
|
Oriels.Rig rig = Oriels.Mono.inst.rig;
|
||||||
|
|
||||||
// angle.x -= rig.rCon.device.stick.y * 90f * Time.Stepf;
|
// angle.x -= rig.rCon.device.stick.y * 90f * Time.Stepf;
|
||||||
// angle.x = PullRequest.Clamp(angle.x, -89, 89);
|
// angle.x = PR.Clamp(angle.x, -89, 89);
|
||||||
angle.y -= rig.rCon.device.stick.x * 90f * Time.Stepf;
|
angle.y -= rig.rCon.device.stick.x * 90f * Time.Stepf;
|
||||||
|
|
||||||
Vec3 input = new Vec3(
|
Vec3 input = new Vec3(
|
||||||
|
|
5
src/Dofs.cs
Normal file
5
src/Dofs.cs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
namespace Oriels;
|
||||||
|
public static class Dofs {
|
||||||
|
// stretch
|
||||||
|
// flex
|
||||||
|
}
|
|
@ -8,7 +8,19 @@ public class Compositor {
|
||||||
Greenyard.Mono greenyard = new Greenyard.Mono();
|
Greenyard.Mono greenyard = new Greenyard.Mono();
|
||||||
// bool other = false;
|
// bool other = false;
|
||||||
|
|
||||||
|
Tex tex;
|
||||||
|
Material mat = new Material(Shader.FromFile("compositor.hlsl"));
|
||||||
|
|
||||||
public void Init() {
|
public void Init() {
|
||||||
|
tex = new Tex(TexType.Rendertarget);
|
||||||
|
tex.SetSize(512, 512);
|
||||||
|
tex.AddZBuffer(TexFormat.Depth16); // DepthStencil
|
||||||
|
mat[MatParamName.DiffuseTex] = tex;
|
||||||
|
mat.FaceCull = Cull.Front;
|
||||||
|
|
||||||
|
// Renderer.Blit(tex, newMat)
|
||||||
|
|
||||||
|
|
||||||
backrooms.Init();
|
backrooms.Init();
|
||||||
greenyard.Init();
|
greenyard.Init();
|
||||||
}
|
}
|
||||||
|
@ -65,6 +77,16 @@ public class Compositor {
|
||||||
// );
|
// );
|
||||||
// Model model = Model.FromFile("oriel.glb");
|
// Model model = Model.FromFile("oriel.glb");
|
||||||
// ~ Mesh mesh = model.GetMesh("oriel");
|
// ~ Mesh mesh = model.GetMesh("oriel");
|
||||||
|
|
||||||
|
Renderer.RenderTo(tex,
|
||||||
|
Matrix.TR(V.XYZ(0, 1, 0), Quat.FromAngles(0, 180, 0)),
|
||||||
|
Matrix.Perspective(60, 1, 0.1f, 100),
|
||||||
|
RenderLayer.All // & ~RenderLayer.Layer1
|
||||||
|
);
|
||||||
|
|
||||||
|
Default.MeshQuad.Draw(mat,
|
||||||
|
Matrix.TR(V.XYZ(0, 1, 0), Quat.FromAngles(0, 0, 0))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Place() {
|
void Place() {
|
|
@ -59,21 +59,21 @@ public class Oriel {
|
||||||
|
|
||||||
Vec3 cornerDetect = Vec3.Zero;
|
Vec3 cornerDetect = Vec3.Zero;
|
||||||
public Vec3 XAnchor { get {
|
public Vec3 XAnchor { get {
|
||||||
float x = PullRequest.Clamp(localCursor.x,
|
float x = PR.Clamp(localCursor.x,
|
||||||
LocalAnchor.x - cornerRadius,
|
LocalAnchor.x - cornerRadius,
|
||||||
LocalAnchor.x + cornerRadius
|
LocalAnchor.x + cornerRadius
|
||||||
);
|
);
|
||||||
return new Vec3(x, LocalAnchor.y, LocalAnchor.z);
|
return new Vec3(x, LocalAnchor.y, LocalAnchor.z);
|
||||||
} }
|
} }
|
||||||
public Vec3 YAnchor { get {
|
public Vec3 YAnchor { get {
|
||||||
float y = PullRequest.Clamp(localCursor.y,
|
float y = PR.Clamp(localCursor.y,
|
||||||
LocalAnchor.y - cornerRadius,
|
LocalAnchor.y - cornerRadius,
|
||||||
LocalAnchor.y + cornerRadius
|
LocalAnchor.y + cornerRadius
|
||||||
);
|
);
|
||||||
return new Vec3(LocalAnchor.x, y, LocalAnchor.z);
|
return new Vec3(LocalAnchor.x, y, LocalAnchor.z);
|
||||||
} }
|
} }
|
||||||
public Vec3 ZAnchor { get {
|
public Vec3 ZAnchor { get {
|
||||||
float z = PullRequest.Clamp(localCursor.z,
|
float z = PR.Clamp(localCursor.z,
|
||||||
LocalAnchor.z - cornerRadius,
|
LocalAnchor.z - cornerRadius,
|
||||||
LocalAnchor.z + cornerRadius
|
LocalAnchor.z + cornerRadius
|
||||||
);
|
);
|
||||||
|
@ -251,7 +251,7 @@ public class Oriel {
|
||||||
// cursor
|
// cursor
|
||||||
Color col = new Color(0.15f, 0.15f, 0.15f);
|
Color col = new Color(0.15f, 0.15f, 0.15f);
|
||||||
float thk = 0.002f;
|
float thk = 0.002f;
|
||||||
float prx = PullRequest.Clamp(
|
float prx = PR.Clamp(
|
||||||
cursorRadius - (localCursor - LocalAnchor).Magnitude / 3, 0, cursorRadius
|
cursorRadius - (localCursor - LocalAnchor).Magnitude / 3, 0, cursorRadius
|
||||||
) / cursorRadius;
|
) / cursorRadius;
|
||||||
if (detectCount == 1 || detectCount == 2) {
|
if (detectCount == 1 || detectCount == 2) {
|
12
src/Functions.cs
Normal file
12
src/Functions.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Oriels;
|
||||||
|
public static class Functions {
|
||||||
|
|
||||||
|
// in SK >= 1.2.0 as Vec3.Direction()
|
||||||
|
public static Vec3 Dir(Vec3 to, Vec3 from) {
|
||||||
|
return (to - from).Normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
// deadzone
|
||||||
|
// magnitude
|
||||||
|
// extension
|
||||||
|
}
|
|
@ -58,7 +58,7 @@ public class Glove {
|
||||||
if (lift) {
|
if (lift) {
|
||||||
pullPoint = con.pos + -direction * stretch;
|
pullPoint = con.pos + -direction * stretch;
|
||||||
} else {
|
} else {
|
||||||
direction = PullRequest.Direction(con.pos, pullPoint);
|
direction = PR.Direction(con.pos, pullPoint);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pullPoint = con.pos;
|
pullPoint = con.pos;
|
||||||
|
@ -83,7 +83,7 @@ public class Glove {
|
||||||
|
|
||||||
case Pull.Backhanded:
|
case Pull.Backhanded:
|
||||||
pullPoint = otherCon.pos;
|
pullPoint = otherCon.pos;
|
||||||
direction = PullRequest.Direction(con.pos, otherCon.pos);
|
direction = PR.Direction(con.pos, otherCon.pos);
|
||||||
virtualGlove.orientation = con.ori;
|
virtualGlove.orientation = con.ori;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class Mono {
|
||||||
Oriels.Rig rig = Oriels.Mono.inst.rig;
|
Oriels.Rig rig = Oriels.Mono.inst.rig;
|
||||||
|
|
||||||
// angle.x -= rig.rCon.device.stick.y * 90f * Time.Stepf;
|
// angle.x -= rig.rCon.device.stick.y * 90f * Time.Stepf;
|
||||||
// angle.x = PullRequest.Clamp(angle.x, -89, 89);
|
// angle.x = PR.Clamp(angle.x, -89, 89);
|
||||||
angle.y -= rig.rCon.device.stick.x * 90f * Time.Stepf;
|
angle.y -= rig.rCon.device.stick.x * 90f * Time.Stepf;
|
||||||
|
|
||||||
Vec3 input = new Vec3(
|
Vec3 input = new Vec3(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
public interface dof { // <T> ?
|
public interface Interaction { // <T> ?
|
||||||
void Init();
|
void Init();
|
||||||
void Frame();
|
void Frame();
|
||||||
// void Drop();
|
// void Drop();
|
9
src/Interactions/fullstick/Fullstick.cs
Normal file
9
src/Interactions/fullstick/Fullstick.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Oriels;
|
||||||
|
public class Fullstick {
|
||||||
|
public Vec3 Direction(bool chirality) {
|
||||||
|
Controller con = Mono.inst.rig.Con(chirality).device;
|
||||||
|
Quat rot = Quat.FromAngles(con.stick.y * -90, 0, con.stick.x * 90);
|
||||||
|
Vec3 dir = Vec3.Up * (con.IsStickClicked ? -1 : 1);
|
||||||
|
return con.aim.orientation * rot * dir;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Oriels;
|
namespace Oriels;
|
||||||
|
|
||||||
class RollsCursor : dof {
|
class RollsCursor : Interaction {
|
||||||
public bool Active { get; set; }
|
public bool Active { get; set; }
|
||||||
|
|
||||||
// input
|
// input
|
||||||
|
@ -25,7 +25,7 @@ class RollsCursor : dof {
|
||||||
Vec3 to = Roll(hand, JointId.KnuckleMid, fI, fM, fR, fL);
|
Vec3 to = Roll(hand, JointId.KnuckleMid, fI, fM, fR, fL);
|
||||||
Vec3 from = Roll(hand, JointId.KnuckleMajor, fI, fM, fR, fL);
|
Vec3 from = Roll(hand, JointId.KnuckleMajor, fI, fM, fR, fL);
|
||||||
|
|
||||||
Vec3 dir = PullRequest.Direction(to, from);
|
Vec3 dir = PR.Direction(to, from);
|
||||||
|
|
||||||
cursor.raw = to + dir * stretch * reach.value;
|
cursor.raw = to + dir * stretch * reach.value;
|
||||||
|
|
||||||
|
@ -44,10 +44,10 @@ class RollsCursor : dof {
|
||||||
Vec3 r = hand.Get(FingerId.Ring, jointId).position;
|
Vec3 r = hand.Get(FingerId.Ring, jointId).position;
|
||||||
Vec3 l = hand.Get(FingerId.Little, jointId).position;
|
Vec3 l = hand.Get(FingerId.Little, jointId).position;
|
||||||
|
|
||||||
fI = PullRequest.Clamp(fI, 0.0001f, 1f);
|
fI = PR.Clamp(fI, 0.0001f, 1f);
|
||||||
fM = PullRequest.Clamp(fM, 0.0001f, 1f);
|
fM = PR.Clamp(fM, 0.0001f, 1f);
|
||||||
fR = PullRequest.Clamp(fR, 0.0001f, 1f);
|
fR = PR.Clamp(fR, 0.0001f, 1f);
|
||||||
fL = PullRequest.Clamp(fL, 0.0001f, 1f);
|
fL = PR.Clamp(fL, 0.0001f, 1f);
|
||||||
|
|
||||||
Vec3 im = Vec3.Lerp(i , m , fM / (fM + fI));
|
Vec3 im = Vec3.Lerp(i , m , fM / (fM + fI));
|
||||||
Vec3 mr = Vec3.Lerp( m , r , fR / (fR + fM));
|
Vec3 mr = Vec3.Lerp( m , r , fR / (fR + fM));
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Oriels;
|
namespace Oriels;
|
||||||
|
|
||||||
class StretchCursor : dof {
|
class StretchCursor : Interaction {
|
||||||
public bool Active { get; set; }
|
public bool Active { get; set; }
|
||||||
|
|
||||||
// input
|
// input
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Oriels;
|
namespace Oriels;
|
||||||
|
|
||||||
class Trackballer : dof {
|
class Trackballer : Interaction {
|
||||||
public bool Active { get; set; }
|
public bool Active { get; set; }
|
||||||
|
|
||||||
// input
|
// input
|
||||||
|
@ -18,7 +18,7 @@ class Trackballer : dof {
|
||||||
Matrix oldPad = Matrix.Identity;
|
Matrix oldPad = Matrix.Identity;
|
||||||
int lastClosestIndex;
|
int lastClosestIndex;
|
||||||
|
|
||||||
PullRequest.Vec3PID compliance = new PullRequest.Vec3PID();
|
PR.Vec3PID compliance = new PR.Vec3PID();
|
||||||
|
|
||||||
Model model = Model.FromFile("thumb_pad.glb");
|
Model model = Model.FromFile("thumb_pad.glb");
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
|
@ -140,7 +140,7 @@ class Trackballer : dof {
|
||||||
compliance.value += offset * compliant.value;
|
compliance.value += offset * compliant.value;
|
||||||
compliance.integral = Vec3.Zero;
|
compliance.integral = Vec3.Zero;
|
||||||
} else {
|
} else {
|
||||||
PullRequest.ToAxisAngle(momentum, out Vec3 axis, out float angle);
|
PR.ToAxisAngle(momentum, out Vec3 axis, out float angle);
|
||||||
if (angle < stop.value) {
|
if (angle < stop.value) {
|
||||||
momentum = Quat.Slerp(momentum, Quat.Identity, Time.Stepf * 10f);
|
momentum = Quat.Slerp(momentum, Quat.Identity, Time.Stepf * 10f);
|
||||||
}
|
}
|
||||||
|
@ -184,12 +184,12 @@ class Trackballer : dof {
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
cursorPos.x = PullRequest.Clamp(
|
cursorPos.x = PR.Clamp(
|
||||||
cursorPos.x + (momentum * Vec3.Right).z * 0.1f,
|
cursorPos.x + (momentum * Vec3.Right).z * 0.1f,
|
||||||
width / -2f,
|
width / -2f,
|
||||||
width / 2f
|
width / 2f
|
||||||
);
|
);
|
||||||
cursorPos.y = PullRequest.Clamp(
|
cursorPos.y = PR.Clamp(
|
||||||
cursorPos.y + (momentum * Vec3.Right).y * -0.1f,
|
cursorPos.y + (momentum * Vec3.Right).y * -0.1f,
|
||||||
height / -2f,
|
height / -2f,
|
||||||
height / 2f
|
height / 2f
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Oriels;
|
namespace Oriels;
|
||||||
|
|
||||||
class WaveCursor : dof {
|
class WaveCursor : Interaction {
|
||||||
public bool Active { get; set; }
|
public bool Active { get; set; }
|
||||||
|
|
||||||
// input
|
// input
|
||||||
|
@ -68,7 +68,7 @@ class WaveCursor : dof {
|
||||||
// if (i > 0) {
|
// if (i > 0) {
|
||||||
// Vec3 dir = Vec3.Forward;
|
// Vec3 dir = Vec3.Forward;
|
||||||
// if (points[i].v != points[i - 1].v) {
|
// if (points[i].v != points[i - 1].v) {
|
||||||
// dir = PullRequest.Direction(points[i], points[i - 1]);
|
// dir = PR.Direction(points[i], points[i - 1]);
|
||||||
// }
|
// }
|
||||||
// // points[i] = points[i - 1] + dir * 0.02f * scale;
|
// // points[i] = points[i - 1] + dir * 0.02f * scale;
|
||||||
// }
|
// }
|
181
src/Mono.cs
181
src/Mono.cs
|
@ -4,7 +4,7 @@ public class Mono {
|
||||||
private static readonly Lazy<Oriels.Mono> lazy = new Lazy<Oriels.Mono>(() => new Oriels.Mono());
|
private static readonly Lazy<Oriels.Mono> lazy = new Lazy<Oriels.Mono>(() => new Oriels.Mono());
|
||||||
public static Oriels.Mono inst { get { return lazy.Value; } }
|
public static Oriels.Mono inst { get { return lazy.Value; } }
|
||||||
|
|
||||||
public PullRequest.Noise noise = new PullRequest.Noise(939949595);
|
public PR.Noise noise = new PR.Noise(939949595);
|
||||||
|
|
||||||
public Material matDev;
|
public Material matDev;
|
||||||
public Material matHoloframe = new Material(Shader.FromFile("above.hlsl"));
|
public Material matHoloframe = new Material(Shader.FromFile("above.hlsl"));
|
||||||
|
@ -18,41 +18,28 @@ public class Mono {
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
public dof[] dofs;
|
public Interaction[] dofs;
|
||||||
|
|
||||||
public ColorCube colorCube = new ColorCube();
|
public ColorCube colorCube = new ColorCube();
|
||||||
|
|
||||||
public Glove rGlove = new Glove(true), lGlove = new Glove(false);
|
public Glove rGlove = new Glove(true), lGlove = new Glove(false);
|
||||||
public Glove Glove(bool chirality) { return chirality ? rGlove : lGlove; }
|
public Glove Glove(bool chirality) { return chirality ? rGlove : lGlove; }
|
||||||
|
|
||||||
public BlockCon rBlock = new BlockCon(true), lBlock = new BlockCon(false);
|
|
||||||
public BlockCon BlockCon(bool chirality) { return chirality ? rBlock : lBlock; }
|
|
||||||
public Block[] blocks = new Block[] {
|
|
||||||
new Block(), new Block(), new Block(), new Block(), new Block(), new Block()
|
|
||||||
};
|
|
||||||
|
|
||||||
public CubicCon cubicCon = new CubicCon();
|
|
||||||
public Cubic[] cubics = new Cubic[] {
|
|
||||||
new Cubic(), new Cubic(), new Cubic(), new Cubic(), new Cubic(), new Cubic()
|
|
||||||
};
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
public MonoNet net = new MonoNet();
|
// public MonoNet net = new MonoNet();
|
||||||
|
|
||||||
public Mono() {
|
public Mono() {
|
||||||
Renderer.SetClip(0.02f, 1000f);
|
dofs = new Interaction[] {
|
||||||
|
new Chiral(new Interaction[] {
|
||||||
dofs = new dof[] {
|
|
||||||
new Chiral(new dof[] {
|
|
||||||
new WaveCursor() { handed = Handed.Left },
|
new WaveCursor() { handed = Handed.Left },
|
||||||
new WaveCursor() { handed = Handed.Right }
|
new WaveCursor() { handed = Handed.Right }
|
||||||
}),
|
}),
|
||||||
new Chiral(new dof[] {
|
new Chiral(new Interaction[] {
|
||||||
new Trackballer() { handed = Handed.Left },
|
new Trackballer() { handed = Handed.Left },
|
||||||
new Trackballer() { handed = Handed.Right }
|
new Trackballer() { handed = Handed.Right }
|
||||||
}),
|
}),
|
||||||
new Chiral(new dof[] {
|
new Chiral(new Interaction[] {
|
||||||
new RollsCursor() { handed = Handed.Left },
|
new RollsCursor() { handed = Handed.Left },
|
||||||
new RollsCursor() { handed = Handed.Right }
|
new RollsCursor() { handed = Handed.Right }
|
||||||
}),
|
}),
|
||||||
|
@ -91,6 +78,11 @@ public class Mono {
|
||||||
Pose shape = new Pose(new Vec3(0, 1f, -3f), Quat.FromAngles(45, 0, 45));
|
Pose shape = new Pose(new Vec3(0, 1f, -3f), Quat.FromAngles(45, 0, 45));
|
||||||
bool shapeHeld = false;
|
bool shapeHeld = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Spatial spatial = new Spatial();
|
||||||
|
|
||||||
public void Frame() {
|
public void Frame() {
|
||||||
|
|
||||||
// Input.HandClearOverride(Handed.Left);
|
// Input.HandClearOverride(Handed.Left);
|
||||||
|
@ -156,8 +148,23 @@ public class Mono {
|
||||||
new Color(0.5f, 0.55f, 0.75f) * 0.3f
|
new Color(0.5f, 0.55f, 0.75f) * 0.3f
|
||||||
);
|
);
|
||||||
|
|
||||||
|
spatial.Frame();
|
||||||
|
|
||||||
// </Heresy>
|
// </Heresy>
|
||||||
|
|
||||||
|
|
||||||
|
// pinch drawers
|
||||||
|
// do this quick and fun
|
||||||
|
// what's inside?
|
||||||
|
|
||||||
|
// friction flip thumb swipe
|
||||||
|
// overcome with >x force impulse
|
||||||
|
// local to palm
|
||||||
|
|
||||||
|
|
||||||
|
// dofchan bows on the back of the ankles that double as trackers
|
||||||
|
|
||||||
|
|
||||||
// rBlock.Step(); lBlock.Step();
|
// rBlock.Step(); lBlock.Step();
|
||||||
|
|
||||||
// cubicCon.Step();
|
// cubicCon.Step();
|
||||||
|
@ -166,8 +173,8 @@ public class Mono {
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
net.me.Step();
|
// net.me.Step();
|
||||||
net.send = true;
|
// net.send = true;
|
||||||
|
|
||||||
ShowWindowButton();
|
ShowWindowButton();
|
||||||
}
|
}
|
||||||
|
@ -202,7 +209,7 @@ public class Mono {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dof dof = dofs[dofIndex];
|
Interaction dof = dofs[dofIndex];
|
||||||
Type type = dof.GetType();
|
Type type = dof.GetType();
|
||||||
// active toggle
|
// active toggle
|
||||||
Color tint = dof.Active ? new Color(0, 1, 0) : new Color(1, 0, 0);
|
Color tint = dof.Active ? new Color(0, 1, 0) : new Color(1, 0, 0);
|
||||||
|
@ -239,7 +246,7 @@ public class Mono {
|
||||||
UI.WindowEnd();
|
UI.WindowEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderDof(dof dof) {
|
void RenderDof(Interaction dof) {
|
||||||
Type type = dof.GetType();
|
Type type = dof.GetType();
|
||||||
UI.Label("°" + type.Name);
|
UI.Label("°" + type.Name);
|
||||||
System.Reflection.FieldInfo[] fields = type.GetFields();
|
System.Reflection.FieldInfo[] fields = type.GetFields();
|
||||||
|
@ -261,15 +268,15 @@ public class Mono {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chiral : handedness implies symmetry
|
// Chiral : handedness implies symmetry
|
||||||
public class Chiral : dof {
|
public class Chiral : Interaction {
|
||||||
public Chiral(dof[] dofs) => this.dofs = dofs;
|
public Chiral(Interaction[] dofs) => this.dofs = dofs;
|
||||||
private bool active;
|
private bool active;
|
||||||
public bool Active {
|
public bool Active {
|
||||||
get { return this.active; }
|
get { return this.active; }
|
||||||
set {
|
set {
|
||||||
this.active = value;
|
this.active = value;
|
||||||
for (int i = 0; i < this.dofs.Length; i++) {
|
for (int i = 0; i < this.dofs.Length; i++) {
|
||||||
dof dof = this.dofs[i];
|
Interaction dof = this.dofs[i];
|
||||||
if ((int)this.handed == 2 || i == (int)this.handed) {
|
if ((int)this.handed == 2 || i == (int)this.handed) {
|
||||||
dof.Active = value;
|
dof.Active = value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -278,7 +285,7 @@ public class Chiral : dof {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public dof[] dofs = new dof[2];
|
public Interaction[] dofs = new Interaction[2];
|
||||||
// public Design handed = new Design { str = "2", min = 0, max = 2};
|
// public Design handed = new Design { str = "2", min = 0, max = 2};
|
||||||
public Handed handed = Handed.Max;
|
public Handed handed = Handed.Max;
|
||||||
|
|
||||||
|
@ -298,7 +305,7 @@ public class Chiral : dof {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < dofs.Length; i++) {
|
for (int i = 0; i < dofs.Length; i++) {
|
||||||
dof dof = dofs[i];
|
Interaction dof = dofs[i];
|
||||||
if ((int)handed == 2 || i == (int)handed) {
|
if ((int)handed == 2 || i == (int)handed) {
|
||||||
dof.Frame();
|
dof.Frame();
|
||||||
dof.Active = true;
|
dof.Active = true;
|
||||||
|
@ -320,7 +327,7 @@ public class Design {
|
||||||
public float value {
|
public float value {
|
||||||
get {
|
get {
|
||||||
try {
|
try {
|
||||||
float value = PullRequest.Clamp(float.Parse(str), min, max);
|
float value = PR.Clamp(float.Parse(str), min, max);
|
||||||
// if clamped, update string
|
// if clamped, update string
|
||||||
if (value != float.Parse(str)) {
|
if (value != float.Parse(str)) {
|
||||||
if (Input.Key(Key.Return).IsJustActive()) {
|
if (Input.Key(Key.Return).IsJustActive()) {
|
||||||
|
@ -337,9 +344,9 @@ public class Design {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Cursor {
|
public class Cursor {
|
||||||
PullRequest.OneEuroFilter xF = new PullRequest.OneEuroFilter(0.001f, 0.1f);
|
PR.OneEuroFilter xF = new PR.OneEuroFilter(0.001f, 0.1f);
|
||||||
PullRequest.OneEuroFilter yF = new PullRequest.OneEuroFilter(0.001f, 0.1f);
|
PR.OneEuroFilter yF = new PR.OneEuroFilter(0.001f, 0.1f);
|
||||||
PullRequest.OneEuroFilter zF = new PullRequest.OneEuroFilter(0.001f, 0.1f);
|
PR.OneEuroFilter zF = new PR.OneEuroFilter(0.001f, 0.1f);
|
||||||
Vec3 _raw;
|
Vec3 _raw;
|
||||||
public Vec3 raw {
|
public Vec3 raw {
|
||||||
get => _raw;
|
get => _raw;
|
||||||
|
@ -392,4 +399,110 @@ public class Cursor {
|
||||||
particularly for hand tracking dofs (so Moses can better test them!)
|
particularly for hand tracking dofs (so Moses can better test them!)
|
||||||
raw = 0.333f alpha ~
|
raw = 0.333f alpha ~
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
we have a whole inspector thing going on here
|
||||||
|
|
||||||
|
but people are working on better alternatives:
|
||||||
|
malek's foss social xr project
|
||||||
|
|
||||||
|
which was part of the reason that i chopped off the networking parts of this project.
|
||||||
|
as we have vrc for reaching larger audiences + malek's project to develop w/the fossxr community
|
||||||
|
so running our own networking is needlessly redundant, and not my strong suit.
|
||||||
|
|
||||||
|
refocusing this project on just prototyping and hosting our xr tools centrally
|
||||||
|
to then be ported to wherever they can best be applied ^-^
|
||||||
|
|
||||||
|
|
||||||
|
the inspector is a crutch for the lack of a native spatial interface for prototyping
|
||||||
|
as it's an incredibly limited and an awkward abstraction of what is happening spatially
|
||||||
|
|
||||||
|
expose spatial functions and dofs
|
||||||
|
allow the user to bind them to tracked inputs+
|
||||||
|
*don't need it all to be fully featured and extensible out of the gate
|
||||||
|
just need a better foundation than a paper paradigm inspector
|
||||||
|
|
||||||
|
|
||||||
|
'world origin' needs to be adjustable~
|
||||||
|
otherwise the visualizations will be difficult to decipher in different contexts
|
||||||
|
|
||||||
|
no names! as everything remains in it's original context
|
||||||
|
text for math symbols is fine~
|
||||||
|
but don't use that as an excuse to abstract things back into text
|
||||||
|
|
||||||
|
you can do vector math spatially
|
||||||
|
by wrapping the living vectors with operators~
|
||||||
|
i.e av + bv = cv
|
||||||
|
(-- + --) -> --
|
||||||
|
it's hard to represent this with text :<
|
||||||
|
but just think of different points/lines(vectors) being encapsulated by
|
||||||
|
underlying larger points/lines(vectors) with symbols or other identifiers
|
||||||
|
with an output, managing to represent the underlying math within the spatial context
|
||||||
|
|
||||||
|
|
||||||
|
side notes
|
||||||
|
need to run it in a way where if it crashes, it doesn't take the whole app down (ask malek?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class Spatial {
|
||||||
|
// example, to build out from
|
||||||
|
|
||||||
|
// just adding two vectors
|
||||||
|
// with great interactivity and visual feedback
|
||||||
|
|
||||||
|
float scale = 0.1f;
|
||||||
|
float thickness => 0.01f * scale;
|
||||||
|
|
||||||
|
Vec3 origin = new Vec3(0, 1, -1);
|
||||||
|
|
||||||
|
float t = 1.0f;
|
||||||
|
Vec3 aFrom, aTo;
|
||||||
|
Vec3 a => Vec3.Lerp(aFrom, aTo, MathF.Min(t, 1f));
|
||||||
|
Vec3 bFrom, bTo;
|
||||||
|
Vec3 b => Vec3.Lerp(bFrom, bTo, MathF.Min(t, 1f));
|
||||||
|
Vec3 c => a + b;
|
||||||
|
|
||||||
|
public void Frame() {
|
||||||
|
// origin axis
|
||||||
|
Lines.Add(origin, World(new Vec3(1, 0, 0)), new Color(1, 0, 0), thickness);
|
||||||
|
Lines.Add(origin, World(new Vec3(0, 1, 0)), new Color(0, 1, 0), thickness);
|
||||||
|
Lines.Add(origin, World(new Vec3(0, 0, 1)), new Color(0, 0, 1), thickness);
|
||||||
|
Mesh.Sphere.Draw(Material.Unlit, Matrix.TS(origin, thickness), new Color(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
|
Random rand = Random.Shared;
|
||||||
|
if (t >= 1.3f) {
|
||||||
|
aFrom = aTo;
|
||||||
|
bFrom = bTo;
|
||||||
|
|
||||||
|
if (rand.NextSingle() < 0.5f) {
|
||||||
|
aTo = new Vec3(rand.NextSingle(), rand.NextSingle(), rand.NextSingle()) * 0.5f;
|
||||||
|
} else {
|
||||||
|
bTo = new Vec3(rand.NextSingle(), rand.NextSingle(), rand.NextSingle()) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = 0.0f;
|
||||||
|
}
|
||||||
|
t += Time.Stepf / 2f;
|
||||||
|
|
||||||
|
|
||||||
|
Lines.Add(origin, World(a), new Color(1, 1, 0), thickness);
|
||||||
|
Mesh.Sphere.Draw(Material.Unlit, Matrix.TS(World(a), thickness), new Color(1, 1, 0));
|
||||||
|
Lines.Add(origin, World(b), new Color(0, 1, 1), thickness);
|
||||||
|
Mesh.Sphere.Draw(Material.Unlit, Matrix.TS(World(b), thickness), new Color(0, 1, 1));
|
||||||
|
|
||||||
|
Lines.Add(World(a), World(c), new Color(0, 1, 1), thickness);
|
||||||
|
Lines.Add(World(b), World(c), new Color(1, 1, 0), thickness);
|
||||||
|
// color between yellow and cyan using HSV
|
||||||
|
Mesh.Sphere.Draw(Material.Unlit, Matrix.TS(World(c), thickness), new Color(0.5f, 1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 World(Vec3 local) {
|
||||||
|
return origin + local * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
namespace Oriels;
|
namespace Oriels;
|
||||||
public static class PullRequest {
|
public static class PR {
|
||||||
public static void BoundsDraw(Bounds b, float thickness, Color color) {
|
public static void BoundsDraw(Bounds b, float thickness, Color color) {
|
||||||
Vec3 c = Vec3.One / 2;
|
Vec3 c = Vec3.One / 2;
|
||||||
Vec3 ds = b.dimensions;
|
Vec3 ds = b.dimensions;
|
|
@ -1,7 +1,6 @@
|
||||||
namespace Oriels;
|
namespace Oriels;
|
||||||
|
|
||||||
public class Rig {
|
public class Rig {
|
||||||
public Mic mic = new Mic();
|
|
||||||
public Vec3 pos = new Vec3(0, 0, 0);
|
public Vec3 pos = new Vec3(0, 0, 0);
|
||||||
public Quat ori = Quat.Identity;
|
public Quat ori = Quat.Identity;
|
||||||
|
|
||||||
|
@ -83,7 +82,7 @@ public class Rig {
|
||||||
lWrist = new Pose(lCon.pos + lCon.ori * new Vec3(0, 0, 0.052f), lCon.ori);
|
lWrist = new Pose(lCon.pos + lCon.ori * new Vec3(0, 0, 0.052f), lCon.ori);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Flexion(Hand hand, FingerId id) {
|
public float Flexion(Hand hand, FingerId id, float deadzone = 0.15f) {
|
||||||
float fingerFlex = (Vec3.Dot(
|
float fingerFlex = (Vec3.Dot(
|
||||||
Vec3.Direction(
|
Vec3.Direction(
|
||||||
hand.Get(id, JointId.Tip).position,
|
hand.Get(id, JointId.Tip).position,
|
||||||
|
@ -94,8 +93,7 @@ public class Rig {
|
||||||
hand.Get(id, JointId.KnuckleMajor).position
|
hand.Get(id, JointId.KnuckleMajor).position
|
||||||
)
|
)
|
||||||
) + 1f) / 2;
|
) + 1f) / 2;
|
||||||
|
float fingerTrim = 0f + deadzone; // 180°
|
||||||
float fingerTrim = 0.15f;
|
|
||||||
fingerFlex = Math.Max(fingerFlex - fingerTrim, 0f) / (1 - fingerTrim);
|
fingerFlex = Math.Max(fingerFlex - fingerTrim, 0f) / (1 - fingerTrim);
|
||||||
|
|
||||||
float knuckleFlex = (Vec3.Dot(
|
float knuckleFlex = (Vec3.Dot(
|
||||||
|
@ -108,21 +106,12 @@ public class Rig {
|
||||||
hand.Get(id, JointId.Root).position
|
hand.Get(id, JointId.Root).position
|
||||||
)
|
)
|
||||||
) + 1f) / 2;
|
) + 1f) / 2;
|
||||||
|
float knuckleTrim = 0.5f + deadzone; // 90°
|
||||||
float knuckleTrim = 0.666f;
|
|
||||||
knuckleFlex = Math.Max(knuckleFlex - knuckleTrim, 0f) / (1 - knuckleTrim);
|
knuckleFlex = Math.Max(knuckleFlex - knuckleTrim, 0f) / (1 - knuckleTrim);
|
||||||
|
|
||||||
float flexion = knuckleFlex + fingerFlex;
|
float flexion = knuckleFlex + fingerFlex;
|
||||||
return flexion * flexion;
|
return flexion * flexion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Vec3 Fullstick(bool chirality) {
|
|
||||||
Controller con = Con(chirality).device;
|
|
||||||
Quat rot = Quat.FromAngles(con.stick.y * -90, 0, con.stick.x * 90);
|
|
||||||
Vec3 dir = Vec3.Up * (con.IsStickClicked ? -1 : 1);
|
|
||||||
return con.aim.orientation * rot * dir;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Con {
|
public class Con {
|
131
src/Rig/Mic.cs
131
src/Rig/Mic.cs
|
@ -1,131 +0,0 @@
|
||||||
namespace Oriels;
|
|
||||||
|
|
||||||
public class Mic {
|
|
||||||
public float[] bufferRaw = new float[0];
|
|
||||||
public int bufferRawSize = 0;
|
|
||||||
|
|
||||||
public int comp = 8;
|
|
||||||
public float[] buffer = new float[0];
|
|
||||||
public int bufferSize = 0;
|
|
||||||
|
|
||||||
FilterButterworth filter;
|
|
||||||
public void Step() {
|
|
||||||
if (Microphone.IsRecording) {
|
|
||||||
// Ensure our buffer of samples is large enough to contain all the
|
|
||||||
// data the mic has ready for us this frame
|
|
||||||
if (Microphone.Sound.UnreadSamples > bufferRaw.Length) {
|
|
||||||
bufferRaw = new float[Microphone.Sound.UnreadSamples];
|
|
||||||
buffer = new float[Microphone.Sound.UnreadSamples / comp];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read data from the microphone stream into our buffer, and track
|
|
||||||
// how much was actually read. Since the mic data collection runs in
|
|
||||||
// a separate thread, this will often be a little inconsistent. Some
|
|
||||||
// frames will have nothing ready, and others may have a lot!
|
|
||||||
bufferRawSize = Microphone.Sound.ReadSamples(ref bufferRaw);
|
|
||||||
bufferSize = bufferRawSize / comp;
|
|
||||||
|
|
||||||
if (bufferSize > 0) {
|
|
||||||
// LowPassFilter lowpass = new LowPassFilter(48000 / comp / 2, 2, 48000);
|
|
||||||
for (int i = 0; i < bufferRawSize; i++) {
|
|
||||||
// bufferRaw[i] = (float)lowpass.compute(bufferRaw[i]);
|
|
||||||
filter.Update(bufferRaw[i]);
|
|
||||||
bufferRaw[i] = filter.Value;
|
|
||||||
}
|
|
||||||
// voice.WriteSamples(bufferRaw);
|
|
||||||
|
|
||||||
buffer[0] = bufferRaw[0];
|
|
||||||
for (int i = 1; i < bufferSize; i++) {
|
|
||||||
buffer[i] = bufferRaw[i * comp - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// upsample
|
|
||||||
float[] upsampled = new float[bufferSize * comp];
|
|
||||||
for (int i = 0; i < bufferSize - 1; i++) {
|
|
||||||
upsampled[Math.Max(i * comp - 1, 0)] = buffer[i];
|
|
||||||
for (int j = 1; j < comp; j++) {
|
|
||||||
upsampled[i * comp - 1 + j] = SKMath.Lerp(buffer[i], buffer[i + 1], (float)j / (float)comp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
voice.WriteSamples(upsampled);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Microphone.Start();
|
|
||||||
voice = Sound.CreateStream(0.5f);
|
|
||||||
voiceInst = voice.Play(Vec3.Zero, 0.5f);
|
|
||||||
filter = new FilterButterworth(48000 / comp / 2, 48000, FilterButterworth.PassType.Lowpass, (float)Math.Sqrt(2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Sound voice;
|
|
||||||
public SoundInst voiceInst; // update position
|
|
||||||
|
|
||||||
public class FilterButterworth {
|
|
||||||
/// <summary>
|
|
||||||
/// rez amount, from sqrt(2) to ~ 0.1
|
|
||||||
/// </summary>
|
|
||||||
private readonly float resonance;
|
|
||||||
|
|
||||||
private readonly float frequency;
|
|
||||||
private readonly int sampleRate;
|
|
||||||
private readonly PassType passType;
|
|
||||||
|
|
||||||
private readonly float c, a1, a2, a3, b1, b2;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Array of input values, latest are in front
|
|
||||||
/// </summary>
|
|
||||||
private float[] inputHistory = new float[2];
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Array of output values, latest are in front
|
|
||||||
/// </summary>
|
|
||||||
private float[] outputHistory = new float[3];
|
|
||||||
|
|
||||||
public FilterButterworth(float frequency, int sampleRate, PassType passType, float resonance) {
|
|
||||||
this.resonance = resonance;
|
|
||||||
this.frequency = frequency;
|
|
||||||
this.sampleRate = sampleRate;
|
|
||||||
this.passType = passType;
|
|
||||||
|
|
||||||
switch (passType) {
|
|
||||||
case PassType.Lowpass:
|
|
||||||
c = 1.0f / (float)Math.Tan(Math.PI * frequency / sampleRate);
|
|
||||||
a1 = 1.0f / (1.0f + resonance * c + c * c);
|
|
||||||
a2 = 2f * a1;
|
|
||||||
a3 = a1;
|
|
||||||
b1 = 2.0f * (1.0f - c * c) * a1;
|
|
||||||
b2 = (1.0f - resonance * c + c * c) * a1;
|
|
||||||
break;
|
|
||||||
case PassType.Highpass:
|
|
||||||
c = (float)Math.Tan(Math.PI * frequency / sampleRate);
|
|
||||||
a1 = 1.0f / (1.0f + resonance * c + c * c);
|
|
||||||
a2 = -2f * a1;
|
|
||||||
a3 = a1;
|
|
||||||
b1 = 2.0f * (c * c - 1.0f) * a1;
|
|
||||||
b2 = (1.0f - resonance * c + c * c) * a1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum PassType {
|
|
||||||
Highpass,
|
|
||||||
Lowpass,
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(float newInput) {
|
|
||||||
float newOutput = a1 * newInput + a2 * this.inputHistory[0] + a3 * this.inputHistory[1] - b1 * this.outputHistory[0] - b2 * this.outputHistory[1];
|
|
||||||
|
|
||||||
this.inputHistory[1] = this.inputHistory[0];
|
|
||||||
this.inputHistory[0] = newInput;
|
|
||||||
|
|
||||||
this.outputHistory[2] = this.outputHistory[1];
|
|
||||||
this.outputHistory[1] = this.outputHistory[0];
|
|
||||||
this.outputHistory[0] = newOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Value {
|
|
||||||
get { return this.outputHistory[0]; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
47
src/Space.cs
47
src/Space.cs
|
@ -14,7 +14,6 @@ public class Space {
|
||||||
|
|
||||||
Material matFloor = new Material(Shader.Default);
|
Material matFloor = new Material(Shader.Default);
|
||||||
Model shed = Model.FromFile("shed/shed.glb", Shader.FromFile("room.hlsl"));
|
Model shed = Model.FromFile("shed/shed.glb", Shader.FromFile("room.hlsl"));
|
||||||
Model leek = Model.FromFile("houseleek_plant.glb", Shader.FromFile("room.hlsl"));
|
|
||||||
Mesh cube = Mesh.Cube;
|
Mesh cube = Mesh.Cube;
|
||||||
|
|
||||||
Solid floor;
|
Solid floor;
|
||||||
|
@ -24,28 +23,28 @@ public class Space {
|
||||||
// recenter the nodes in the leek model
|
// recenter the nodes in the leek model
|
||||||
// so that the leek is centered at the origin
|
// so that the leek is centered at the origin
|
||||||
// and the scale is 1
|
// and the scale is 1
|
||||||
Vec3 center = new Vec3(0, 0, 0);
|
// Vec3 center = new Vec3(0, 0, 0);
|
||||||
foreach (ModelNode node in leek.Nodes) {
|
// foreach (ModelNode node in leek.Nodes) {
|
||||||
if (node.Mesh != null) {
|
// if (node.Mesh != null) {
|
||||||
// average the vertices to find the center
|
// // average the vertices to find the center
|
||||||
foreach (Vertex vertex in node.Mesh.GetVerts()) {
|
// foreach (Vertex vertex in node.Mesh.GetVerts()) {
|
||||||
center += vertex.pos;
|
// center += vertex.pos;
|
||||||
}
|
// }
|
||||||
center /= node.Mesh.VertCount;
|
// center /= node.Mesh.VertCount;
|
||||||
}
|
// }
|
||||||
node.LocalTransform = Matrix.TS(
|
// node.LocalTransform = Matrix.TS(
|
||||||
Vec3.Zero,
|
// Vec3.Zero,
|
||||||
1f
|
// 1f
|
||||||
);
|
// );
|
||||||
// node.ModelTransform = Matrix.TS(
|
// // node.ModelTransform = Matrix.TS(
|
||||||
// new Vec3(0, 0, 0),
|
// // new Vec3(0, 0, 0),
|
||||||
// 1f
|
// // 1f
|
||||||
// );
|
// // );
|
||||||
}
|
// }
|
||||||
leek.RootNode.LocalTransform = Matrix.TS(
|
// leek.RootNode.LocalTransform = Matrix.TS(
|
||||||
-center,
|
// -center,
|
||||||
1f
|
// 1f
|
||||||
);
|
// );
|
||||||
|
|
||||||
|
|
||||||
floor = new Solid(World.BoundsPose.position, Quat.Identity, SolidType.Immovable);
|
floor = new Solid(World.BoundsPose.position, Quat.Identity, SolidType.Immovable);
|
||||||
|
@ -86,7 +85,7 @@ public class Space {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// PullRequest.BlockOut(floor.GetPose().ToMatrix(floorScale), Color.White * 0.333f, matFloor);
|
// PR.BlockOut(floor.GetPose().ToMatrix(floorScale), Color.White * 0.333f, matFloor);
|
||||||
// foreach (ModelNode node in shed.Visuals) {
|
// foreach (ModelNode node in shed.Visuals) {
|
||||||
|
|
||||||
// Console.WriteLine(i + " - " + node.Name);
|
// Console.WriteLine(i + " - " + node.Name);
|
||||||
|
|
|
@ -1,221 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using Oriels;
|
|
||||||
|
|
||||||
// [X] stretch cursor move
|
|
||||||
// [X] nodes *point of reference rather than interest for now
|
|
||||||
// [X] follow player *cam? matrix? name?
|
|
||||||
// [ ] orbital view
|
|
||||||
// [ ] dummy enemies
|
|
||||||
// [ ] trackballer spin
|
|
||||||
// [ ] roll dodge move
|
|
||||||
|
|
||||||
namespace Space;
|
|
||||||
public class Mono {
|
|
||||||
public Oriel oriel = new Oriel(
|
|
||||||
new Vec3(1.0f, -0.5f, 0.5f),
|
|
||||||
Quat.Identity,
|
|
||||||
new Vec3(0.8f, 0.5f, 0.5f)
|
|
||||||
);
|
|
||||||
Node[] nodes = new Node[18];
|
|
||||||
Vec3 playerPos;
|
|
||||||
List<Vec3> enemies = new List<Vec3>();
|
|
||||||
float spawnTime;
|
|
||||||
|
|
||||||
Oriels.PullRequest.PID pidX = new Oriels.PullRequest.PID();
|
|
||||||
Oriels.PullRequest.PID pidY = new Oriels.PullRequest.PID();
|
|
||||||
Oriels.PullRequest.PID pidZ = new Oriels.PullRequest.PID();
|
|
||||||
|
|
||||||
Mesh meshCube;
|
|
||||||
// Model skyboxModel = Model.FromFile("fantasy_skybox.glb");
|
|
||||||
// Mesh skybox;
|
|
||||||
// Material skyboxMat = new Material(Shader.FromFile("/oriel.hlsl"));
|
|
||||||
|
|
||||||
public Mono() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Init() {
|
|
||||||
Oriels.PullRequest.Noise noise = Oriels.Mono.inst.noise;
|
|
||||||
|
|
||||||
// place nodes around a 10x4x10 cube
|
|
||||||
float scalar = 3f;
|
|
||||||
for (int i = 0; i < nodes.Length; i++) {
|
|
||||||
nodes[i] = new Node(
|
|
||||||
new Vec3(
|
|
||||||
noise.value * 5f * scalar,
|
|
||||||
noise.value * 2f * scalar,
|
|
||||||
noise.value * 5f * scalar
|
|
||||||
),
|
|
||||||
noise.uvalue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
meshCube = Mesh.Cube;
|
|
||||||
// skybox = skyboxModel.GetMesh("sky");
|
|
||||||
// skyboxMat.SetMat(101, Cull.None, true);
|
|
||||||
// skyboxMat.SetTexture("diffuse", Tex.FromFile("fantasy_skybox.jpeg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Frame() {
|
|
||||||
Oriels.Rig rig = Oriels.Mono.inst.rig;
|
|
||||||
|
|
||||||
Matrix simMatrix = Matrix.TRS(
|
|
||||||
-playerPos * 0.5f * oriel.bounds.dimensions.y, //-oriel.bounds.dimensions.y / 2.01f, -playerWorldPos.z),
|
|
||||||
Quat.Identity,
|
|
||||||
Vec3.One * 0.5f * oriel.bounds.dimensions.y
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// stretch cursor pattern:
|
|
||||||
// stretch = dist(offHand, mainHand)
|
|
||||||
// max(stretch - deadzone, 0)
|
|
||||||
// dir = mainHand.fwd
|
|
||||||
// cursor = mainHand.pos + dir * stretch * 3
|
|
||||||
|
|
||||||
// stretch cursor code:
|
|
||||||
float deadzone = 0.1f;
|
|
||||||
float stretch = Vec3.Distance(rig.lCon.pos, rig.rCon.pos);
|
|
||||||
stretch = Math.Max(stretch - deadzone, 0);
|
|
||||||
Vec3 cursor = rig.rCon.pos + rig.rCon.ori * Vec3.Forward * stretch * 3;
|
|
||||||
Vec3 localCursor = simMatrix.Inverse.Transform(oriel.matrixInv.Transform(cursor));
|
|
||||||
|
|
||||||
localCursor = new Vec3(
|
|
||||||
MathF.Sin(Time.Totalf * 2f) * 3f,
|
|
||||||
MathF.Sin(Time.Totalf * 0.5f) * 3f,
|
|
||||||
MathF.Sin(Time.Totalf * 1f) * 3f
|
|
||||||
);
|
|
||||||
|
|
||||||
// fly player towards cursor:
|
|
||||||
// playerPos += (localCursor - playerPos).Normalized * 1f * Time.Stepf;
|
|
||||||
pidX.p = moveP; pidY.p = moveP; pidZ.p = moveP;
|
|
||||||
pidX.i = moveI; pidY.i = moveI; pidZ.i = moveI;
|
|
||||||
playerPos = new Vec3(
|
|
||||||
pidX.Update(localCursor.x),
|
|
||||||
pidY.Update(localCursor.y),
|
|
||||||
pidZ.Update(localCursor.z)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// RENDER
|
|
||||||
for (int i = 0; i < nodes.Length; i++) {
|
|
||||||
meshCube.Draw(oriel.matOriel,
|
|
||||||
Matrix.TRS(nodes[i].pos, Quat.Identity, Vec3.One * 1f) * simMatrix * oriel.matrix,
|
|
||||||
Color.HSV(nodes[i].hue, 1f, 1f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
meshCube.Draw(oriel.matOriel,
|
|
||||||
Matrix.TRS(cursor, Quat.Identity, Vec3.One * 0.02f),
|
|
||||||
new Color(1f, 1f, 1f)
|
|
||||||
);
|
|
||||||
meshCube.Draw(oriel.matOriel,
|
|
||||||
Matrix.TRS(localCursor, Quat.Identity, Vec3.One * 0.02f) * simMatrix * oriel.matrix,
|
|
||||||
new Color(0f, 0f, 0f)
|
|
||||||
);
|
|
||||||
meshCube.Draw(oriel.matOriel,
|
|
||||||
Matrix.TRS(
|
|
||||||
playerPos,
|
|
||||||
Quat.LookDir((localCursor - playerPos).Normalized),
|
|
||||||
new Vec3(0.4f, 0.2f, 0.4f)
|
|
||||||
) * simMatrix * oriel.matrix,
|
|
||||||
new Color(1.0f, 0.0f, 0.05f)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// skyboxMat.SetVector("_center", oriel.bounds.center);
|
|
||||||
// skyboxMat.SetVector("_dimensions", oriel.bounds.dimensions);
|
|
||||||
// skyboxMat.SetVector("_light", oriel.ori * new Vec3(0.6f, -0.9f, 0.3f));
|
|
||||||
// skyboxMat.SetFloat("_lit", 0);
|
|
||||||
// skyboxMat["_matrix"] = (Matrix)System.Numerics.Matrix4x4.Transpose(oriel.matrix);
|
|
||||||
// skybox.Draw(skyboxMat,
|
|
||||||
// Matrix.TRS(
|
|
||||||
// playerPos,
|
|
||||||
// Quat.Identity,
|
|
||||||
// new Vec3(10f, 10f, 10f)
|
|
||||||
// ) * simMatrix * oriel.matrix,
|
|
||||||
// Color.White
|
|
||||||
// );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// meshCube.Draw(oriel.matOriel,
|
|
||||||
// rGlove.virtualGlove.ToMatrix(new Vec3(0.025f, 0.1f, 0.1f) / 3 * 1.05f),
|
|
||||||
// new Color(0.3f, 0.3f, 0.6f)
|
|
||||||
// );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// ENEMIES
|
|
||||||
|
|
||||||
// destroy enemies that are too close to the playerPos
|
|
||||||
for (int i = 0; i < enemies.Count; i++) {
|
|
||||||
if (Vec3.Distance(enemies[i], playerPos) < 0.5f) {
|
|
||||||
// enemies.RemoveAt(i);
|
|
||||||
// i--;
|
|
||||||
enemies[i] = playerPos + Quat.FromAngles(0, Oriels.Mono.inst.noise.value * 360f, 0) * Vec3.Forward * 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enemies.Count < 100 && Time.Totalf > spawnTime) {
|
|
||||||
// enemies.Add(playerPos + Quat.FromAngles(0, Oriels.Mono.inst.noise.value * 360f, 0) * Vec3.Forward * 8);
|
|
||||||
spawnTime = Time.Totalf + 0.05f;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < enemies.Count; i++) {
|
|
||||||
|
|
||||||
// move towards player
|
|
||||||
Vec3 toPlayer = (playerPos - enemies[i]).Normalized;
|
|
||||||
float variation = Oriels.Mono.inst.noise.D1(i);
|
|
||||||
toPlayer *= Quat.FromAngles(0, MathF.Sin(Time.Totalf * variation) * 90 * variation, 0);
|
|
||||||
Vec3 newPos = enemies[i] + toPlayer * Time.Stepf * 0.5f;
|
|
||||||
|
|
||||||
// if far enough away from other enemies than set new pos
|
|
||||||
bool setNewPos = true;
|
|
||||||
int iteration = 0;
|
|
||||||
while (iteration < 6) {
|
|
||||||
for (int j = 0; j < enemies.Count; j++) {
|
|
||||||
if (i == j) continue;
|
|
||||||
float radius = 0.5f;
|
|
||||||
float depth = (newPos - enemies[j]).Length - radius;
|
|
||||||
if (depth < 0) {
|
|
||||||
Vec3 toEnemy = (enemies[j] - newPos).Normalized;
|
|
||||||
newPos = enemies[j] - toEnemy * radius * 1.01f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iteration++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setNewPos) {
|
|
||||||
enemies[i] = newPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
meshCube.Draw(oriel.matOriel,
|
|
||||||
Matrix.TRS(enemies[i],
|
|
||||||
Quat.LookAt(enemies[i], playerPos, Vec3.Up),
|
|
||||||
new Vec3(0.4f, 1f, 0.2f)
|
|
||||||
) * simMatrix * oriel.matrix,
|
|
||||||
Color.White * 0.62f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// design variables
|
|
||||||
float moveP = 8f;
|
|
||||||
float moveI = 0.2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Node {
|
|
||||||
public Vec3 pos;
|
|
||||||
public float hue;
|
|
||||||
|
|
||||||
public Node(Vec3 pos, float hue) {
|
|
||||||
this.pos = pos;
|
|
||||||
this.hue = hue;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,6 +16,8 @@ if (!SK.Initialize(settings))
|
||||||
Input.HandSolid(Handed.Max, false);
|
Input.HandSolid(Handed.Max, false);
|
||||||
Input.HandVisible(Handed.Max, true);
|
Input.HandVisible(Handed.Max, true);
|
||||||
// Input.HandMaterial(Handed.Max, Material.Default);
|
// Input.HandMaterial(Handed.Max, Material.Default);
|
||||||
|
|
||||||
|
Renderer.SetClip(0.02f, 100f);
|
||||||
Renderer.EnableSky = false;
|
Renderer.EnableSky = false;
|
||||||
Renderer.ClearColor = new Color(0f / 256f, 162f / 256f, 206f / 256f);
|
Renderer.ClearColor = new Color(0f / 256f, 162f / 256f, 206f / 256f);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue