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) {
|
||||
blocks[PullRequest.RandomRange(0, blocks.Length)].Enable(cursor, Quat.Identity);
|
||||
blocks[PR.RandomRange(0, blocks.Length)].Enable(cursor, Quat.Identity);
|
||||
}
|
||||
} else {
|
||||
blocks[index].Disable();
|
||||
|
@ -139,7 +139,7 @@ public class BlockCon {
|
|||
blocks[index].solid.Move(toPos, toRot);
|
||||
|
||||
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;
|
||||
|
||||
delta = (cursor + (con.ori * heldRot * spinRot).Normalized * offset) - blocks[index].solid.GetPose().position;
|
|
@ -35,7 +35,7 @@ public class CubicCon {
|
|||
break;
|
||||
}
|
||||
}
|
||||
Cubic cubic = cubics[PullRequest.RandomRange(0, cubics.Length)];
|
||||
Cubic cubic = cubics[PR.RandomRange(0, cubics.Length)];
|
||||
cubic.p0 = rPos;
|
||||
cubic.p1 = rig.rCon.pos;
|
||||
cubic.p2 = rig.lCon.pos;
|
|
@ -356,7 +356,7 @@ public class Peer {
|
|||
public void Draw(bool body) {
|
||||
Mono mono = Mono.inst;
|
||||
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(
|
||||
|
@ -370,7 +370,7 @@ public class Peer {
|
|||
for (int i = 0; i < blocks.Length; i++) {
|
||||
NetBlock block = blocks[i];
|
||||
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>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7</TargetFramework>
|
||||
<SKAssetFolder>add</SKAssetFolder>
|
||||
<SKAssetDestination>add</SKAssetDestination>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -50,7 +50,7 @@ public class Mono {
|
|||
Oriels.Rig rig = Oriels.Mono.inst.rig;
|
||||
|
||||
// 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;
|
||||
|
||||
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();
|
||||
// bool other = false;
|
||||
|
||||
Tex tex;
|
||||
Material mat = new Material(Shader.FromFile("compositor.hlsl"));
|
||||
|
||||
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();
|
||||
greenyard.Init();
|
||||
}
|
||||
|
@ -65,6 +77,16 @@ public class Compositor {
|
|||
// );
|
||||
// Model model = Model.FromFile("oriel.glb");
|
||||
// ~ 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() {
|
|
@ -59,21 +59,21 @@ public class Oriel {
|
|||
|
||||
Vec3 cornerDetect = Vec3.Zero;
|
||||
public Vec3 XAnchor { get {
|
||||
float x = PullRequest.Clamp(localCursor.x,
|
||||
float x = PR.Clamp(localCursor.x,
|
||||
LocalAnchor.x - cornerRadius,
|
||||
LocalAnchor.x + cornerRadius
|
||||
);
|
||||
return new Vec3(x, LocalAnchor.y, LocalAnchor.z);
|
||||
} }
|
||||
public Vec3 YAnchor { get {
|
||||
float y = PullRequest.Clamp(localCursor.y,
|
||||
float y = PR.Clamp(localCursor.y,
|
||||
LocalAnchor.y - cornerRadius,
|
||||
LocalAnchor.y + cornerRadius
|
||||
);
|
||||
return new Vec3(LocalAnchor.x, y, LocalAnchor.z);
|
||||
} }
|
||||
public Vec3 ZAnchor { get {
|
||||
float z = PullRequest.Clamp(localCursor.z,
|
||||
float z = PR.Clamp(localCursor.z,
|
||||
LocalAnchor.z - cornerRadius,
|
||||
LocalAnchor.z + cornerRadius
|
||||
);
|
||||
|
@ -251,7 +251,7 @@ public class Oriel {
|
|||
// cursor
|
||||
Color col = new Color(0.15f, 0.15f, 0.15f);
|
||||
float thk = 0.002f;
|
||||
float prx = PullRequest.Clamp(
|
||||
float prx = PR.Clamp(
|
||||
cursorRadius - (localCursor - LocalAnchor).Magnitude / 3, 0, cursorRadius
|
||||
) / cursorRadius;
|
||||
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) {
|
||||
pullPoint = con.pos + -direction * stretch;
|
||||
} else {
|
||||
direction = PullRequest.Direction(con.pos, pullPoint);
|
||||
direction = PR.Direction(con.pos, pullPoint);
|
||||
}
|
||||
} else {
|
||||
pullPoint = con.pos;
|
||||
|
@ -83,7 +83,7 @@ public class Glove {
|
|||
|
||||
case Pull.Backhanded:
|
||||
pullPoint = otherCon.pos;
|
||||
direction = PullRequest.Direction(con.pos, otherCon.pos);
|
||||
direction = PR.Direction(con.pos, otherCon.pos);
|
||||
virtualGlove.orientation = con.ori;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public class Mono {
|
|||
Oriels.Rig rig = Oriels.Mono.inst.rig;
|
||||
|
||||
// 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;
|
||||
|
||||
Vec3 input = new Vec3(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
public interface dof { // <T> ?
|
||||
public interface Interaction { // <T> ?
|
||||
void Init();
|
||||
void Frame();
|
||||
// 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;
|
||||
|
||||
class RollsCursor : dof {
|
||||
class RollsCursor : Interaction {
|
||||
public bool Active { get; set; }
|
||||
|
||||
// input
|
||||
|
@ -25,7 +25,7 @@ class RollsCursor : dof {
|
|||
Vec3 to = Roll(hand, JointId.KnuckleMid, 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;
|
||||
|
||||
|
@ -44,10 +44,10 @@ class RollsCursor : dof {
|
|||
Vec3 r = hand.Get(FingerId.Ring, jointId).position;
|
||||
Vec3 l = hand.Get(FingerId.Little, jointId).position;
|
||||
|
||||
fI = PullRequest.Clamp(fI, 0.0001f, 1f);
|
||||
fM = PullRequest.Clamp(fM, 0.0001f, 1f);
|
||||
fR = PullRequest.Clamp(fR, 0.0001f, 1f);
|
||||
fL = PullRequest.Clamp(fL, 0.0001f, 1f);
|
||||
fI = PR.Clamp(fI, 0.0001f, 1f);
|
||||
fM = PR.Clamp(fM, 0.0001f, 1f);
|
||||
fR = PR.Clamp(fR, 0.0001f, 1f);
|
||||
fL = PR.Clamp(fL, 0.0001f, 1f);
|
||||
|
||||
Vec3 im = Vec3.Lerp(i , m , fM / (fM + fI));
|
||||
Vec3 mr = Vec3.Lerp( m , r , fR / (fR + fM));
|
|
@ -1,6 +1,6 @@
|
|||
namespace Oriels;
|
||||
|
||||
class StretchCursor : dof {
|
||||
class StretchCursor : Interaction {
|
||||
public bool Active { get; set; }
|
||||
|
||||
// input
|
|
@ -1,6 +1,6 @@
|
|||
namespace Oriels;
|
||||
|
||||
class Trackballer : dof {
|
||||
class Trackballer : Interaction {
|
||||
public bool Active { get; set; }
|
||||
|
||||
// input
|
||||
|
@ -18,7 +18,7 @@ class Trackballer : dof {
|
|||
Matrix oldPad = Matrix.Identity;
|
||||
int lastClosestIndex;
|
||||
|
||||
PullRequest.Vec3PID compliance = new PullRequest.Vec3PID();
|
||||
PR.Vec3PID compliance = new PR.Vec3PID();
|
||||
|
||||
Model model = Model.FromFile("thumb_pad.glb");
|
||||
Mesh mesh;
|
||||
|
@ -140,7 +140,7 @@ class Trackballer : dof {
|
|||
compliance.value += offset * compliant.value;
|
||||
compliance.integral = Vec3.Zero;
|
||||
} else {
|
||||
PullRequest.ToAxisAngle(momentum, out Vec3 axis, out float angle);
|
||||
PR.ToAxisAngle(momentum, out Vec3 axis, out float angle);
|
||||
if (angle < stop.value) {
|
||||
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,
|
||||
width / -2f,
|
||||
width / 2f
|
||||
);
|
||||
cursorPos.y = PullRequest.Clamp(
|
||||
cursorPos.y = PR.Clamp(
|
||||
cursorPos.y + (momentum * Vec3.Right).y * -0.1f,
|
||||
height / -2f,
|
||||
height / 2f
|
|
@ -1,6 +1,6 @@
|
|||
namespace Oriels;
|
||||
|
||||
class WaveCursor : dof {
|
||||
class WaveCursor : Interaction {
|
||||
public bool Active { get; set; }
|
||||
|
||||
// input
|
||||
|
@ -68,7 +68,7 @@ class WaveCursor : dof {
|
|||
// if (i > 0) {
|
||||
// Vec3 dir = Vec3.Forward;
|
||||
// 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;
|
||||
// }
|
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());
|
||||
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 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 Glove rGlove = new Glove(true), lGlove = new Glove(false);
|
||||
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() {
|
||||
Renderer.SetClip(0.02f, 1000f);
|
||||
|
||||
dofs = new dof[] {
|
||||
new Chiral(new dof[] {
|
||||
dofs = new Interaction[] {
|
||||
new Chiral(new Interaction[] {
|
||||
new WaveCursor() { handed = Handed.Left },
|
||||
new WaveCursor() { handed = Handed.Right }
|
||||
}),
|
||||
new Chiral(new dof[] {
|
||||
new Chiral(new Interaction[] {
|
||||
new Trackballer() { handed = Handed.Left },
|
||||
new Trackballer() { handed = Handed.Right }
|
||||
}),
|
||||
new Chiral(new dof[] {
|
||||
new Chiral(new Interaction[] {
|
||||
new RollsCursor() { handed = Handed.Left },
|
||||
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));
|
||||
bool shapeHeld = false;
|
||||
|
||||
|
||||
|
||||
|
||||
Spatial spatial = new Spatial();
|
||||
|
||||
public void Frame() {
|
||||
|
||||
// Input.HandClearOverride(Handed.Left);
|
||||
|
@ -156,8 +148,23 @@ public class Mono {
|
|||
new Color(0.5f, 0.55f, 0.75f) * 0.3f
|
||||
);
|
||||
|
||||
spatial.Frame();
|
||||
|
||||
// </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();
|
||||
|
||||
// cubicCon.Step();
|
||||
|
@ -166,8 +173,8 @@ public class Mono {
|
|||
|
||||
// -------------------------------------------------
|
||||
|
||||
net.me.Step();
|
||||
net.send = true;
|
||||
// net.me.Step();
|
||||
// net.send = true;
|
||||
|
||||
ShowWindowButton();
|
||||
}
|
||||
|
@ -202,7 +209,7 @@ public class Mono {
|
|||
}
|
||||
|
||||
|
||||
dof dof = dofs[dofIndex];
|
||||
Interaction dof = dofs[dofIndex];
|
||||
Type type = dof.GetType();
|
||||
// active toggle
|
||||
Color tint = dof.Active ? new Color(0, 1, 0) : new Color(1, 0, 0);
|
||||
|
@ -239,7 +246,7 @@ public class Mono {
|
|||
UI.WindowEnd();
|
||||
}
|
||||
|
||||
void RenderDof(dof dof) {
|
||||
void RenderDof(Interaction dof) {
|
||||
Type type = dof.GetType();
|
||||
UI.Label("°" + type.Name);
|
||||
System.Reflection.FieldInfo[] fields = type.GetFields();
|
||||
|
@ -261,15 +268,15 @@ public class Mono {
|
|||
}
|
||||
|
||||
// Chiral : handedness implies symmetry
|
||||
public class Chiral : dof {
|
||||
public Chiral(dof[] dofs) => this.dofs = dofs;
|
||||
public class Chiral : Interaction {
|
||||
public Chiral(Interaction[] dofs) => this.dofs = dofs;
|
||||
private bool active;
|
||||
public bool Active {
|
||||
get { return this.active; }
|
||||
set {
|
||||
this.active = value;
|
||||
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) {
|
||||
dof.Active = value;
|
||||
} 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 Handed handed = Handed.Max;
|
||||
|
||||
|
@ -298,7 +305,7 @@ public class Chiral : dof {
|
|||
}
|
||||
|
||||
for (int i = 0; i < dofs.Length; i++) {
|
||||
dof dof = dofs[i];
|
||||
Interaction dof = dofs[i];
|
||||
if ((int)handed == 2 || i == (int)handed) {
|
||||
dof.Frame();
|
||||
dof.Active = true;
|
||||
|
@ -320,7 +327,7 @@ public class Design {
|
|||
public float value {
|
||||
get {
|
||||
try {
|
||||
float value = PullRequest.Clamp(float.Parse(str), min, max);
|
||||
float value = PR.Clamp(float.Parse(str), min, max);
|
||||
// if clamped, update string
|
||||
if (value != float.Parse(str)) {
|
||||
if (Input.Key(Key.Return).IsJustActive()) {
|
||||
|
@ -337,9 +344,9 @@ public class Design {
|
|||
}
|
||||
|
||||
public class Cursor {
|
||||
PullRequest.OneEuroFilter xF = new PullRequest.OneEuroFilter(0.001f, 0.1f);
|
||||
PullRequest.OneEuroFilter yF = new PullRequest.OneEuroFilter(0.001f, 0.1f);
|
||||
PullRequest.OneEuroFilter zF = new PullRequest.OneEuroFilter(0.001f, 0.1f);
|
||||
PR.OneEuroFilter xF = new PR.OneEuroFilter(0.001f, 0.1f);
|
||||
PR.OneEuroFilter yF = new PR.OneEuroFilter(0.001f, 0.1f);
|
||||
PR.OneEuroFilter zF = new PR.OneEuroFilter(0.001f, 0.1f);
|
||||
Vec3 _raw;
|
||||
public Vec3 raw {
|
||||
get => _raw;
|
||||
|
@ -392,4 +399,110 @@ public class Cursor {
|
|||
particularly for hand tracking dofs (so Moses can better test them!)
|
||||
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;
|
||||
public static class PullRequest {
|
||||
public static class PR {
|
||||
public static void BoundsDraw(Bounds b, float thickness, Color color) {
|
||||
Vec3 c = Vec3.One / 2;
|
||||
Vec3 ds = b.dimensions;
|
|
@ -1,7 +1,6 @@
|
|||
namespace Oriels;
|
||||
|
||||
public class Rig {
|
||||
public Mic mic = new Mic();
|
||||
public Vec3 pos = new Vec3(0, 0, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
public float Flexion(Hand hand, FingerId id) {
|
||||
public float Flexion(Hand hand, FingerId id, float deadzone = 0.15f) {
|
||||
float fingerFlex = (Vec3.Dot(
|
||||
Vec3.Direction(
|
||||
hand.Get(id, JointId.Tip).position,
|
||||
|
@ -94,8 +93,7 @@ public class Rig {
|
|||
hand.Get(id, JointId.KnuckleMajor).position
|
||||
)
|
||||
) + 1f) / 2;
|
||||
|
||||
float fingerTrim = 0.15f;
|
||||
float fingerTrim = 0f + deadzone; // 180°
|
||||
fingerFlex = Math.Max(fingerFlex - fingerTrim, 0f) / (1 - fingerTrim);
|
||||
|
||||
float knuckleFlex = (Vec3.Dot(
|
||||
|
@ -108,21 +106,12 @@ public class Rig {
|
|||
hand.Get(id, JointId.Root).position
|
||||
)
|
||||
) + 1f) / 2;
|
||||
|
||||
float knuckleTrim = 0.666f;
|
||||
float knuckleTrim = 0.5f + deadzone; // 90°
|
||||
knuckleFlex = Math.Max(knuckleFlex - knuckleTrim, 0f) / (1 - knuckleTrim);
|
||||
|
||||
float flexion = knuckleFlex + fingerFlex;
|
||||
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 {
|
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);
|
||||
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;
|
||||
|
||||
Solid floor;
|
||||
|
@ -24,28 +23,28 @@ public class Space {
|
|||
// recenter the nodes in the leek model
|
||||
// so that the leek is centered at the origin
|
||||
// and the scale is 1
|
||||
Vec3 center = new Vec3(0, 0, 0);
|
||||
foreach (ModelNode node in leek.Nodes) {
|
||||
if (node.Mesh != null) {
|
||||
// average the vertices to find the center
|
||||
foreach (Vertex vertex in node.Mesh.GetVerts()) {
|
||||
center += vertex.pos;
|
||||
}
|
||||
center /= node.Mesh.VertCount;
|
||||
}
|
||||
node.LocalTransform = Matrix.TS(
|
||||
Vec3.Zero,
|
||||
1f
|
||||
);
|
||||
// node.ModelTransform = Matrix.TS(
|
||||
// new Vec3(0, 0, 0),
|
||||
// 1f
|
||||
// );
|
||||
}
|
||||
leek.RootNode.LocalTransform = Matrix.TS(
|
||||
-center,
|
||||
1f
|
||||
);
|
||||
// Vec3 center = new Vec3(0, 0, 0);
|
||||
// foreach (ModelNode node in leek.Nodes) {
|
||||
// if (node.Mesh != null) {
|
||||
// // average the vertices to find the center
|
||||
// foreach (Vertex vertex in node.Mesh.GetVerts()) {
|
||||
// center += vertex.pos;
|
||||
// }
|
||||
// center /= node.Mesh.VertCount;
|
||||
// }
|
||||
// node.LocalTransform = Matrix.TS(
|
||||
// Vec3.Zero,
|
||||
// 1f
|
||||
// );
|
||||
// // node.ModelTransform = Matrix.TS(
|
||||
// // new Vec3(0, 0, 0),
|
||||
// // 1f
|
||||
// // );
|
||||
// }
|
||||
// leek.RootNode.LocalTransform = Matrix.TS(
|
||||
// -center,
|
||||
// 1f
|
||||
// );
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
// 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.HandVisible(Handed.Max, true);
|
||||
// Input.HandMaterial(Handed.Max, Material.Default);
|
||||
|
||||
Renderer.SetClip(0.02f, 100f);
|
||||
Renderer.EnableSky = false;
|
||||
Renderer.ClearColor = new Color(0f / 256f, 162f / 256f, 206f / 256f);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue