inside an oriel + cubic flow

This commit is contained in:
spatialfree 2021-11-27 22:46:08 -05:00
parent 901e9112ce
commit 43c98bb95e
4 changed files with 337 additions and 125 deletions

View file

@ -6,53 +6,50 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
public class MonoNet { public class MonoNet {
public MonoNet() { public Mono mono;
public MonoNet(Mono mono) {
this.mono = mono;
Random rnd = new Random(); Random rnd = new Random();
me = new Peer(rnd.Next(1, 256)); // temp, until unique usernames me = new Peer(rnd.Next(1, 256)); // temp, until unique usernames
} }
public Socket socket; public Socket socket;
byte[] data; int bufferSize = 1024;
int head; byte[] rData; int rHead;
byte[] wData; int wHead;
public Peer me; public Peer me;
public Peer[] peers; public Peer[] peers;
public async void Start() { public void Start() {
string publicIP, localIP;
// GetIPs();
void GetIPs()
{
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect("8.8.8.8", 65530);
IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
localIP = endPoint.Address.ToString();
}
// Console.WriteLine("Your local IP is: " + localIP);
publicIP = new WebClient().DownloadString("https://ipv4.icanhazip.com/").TrimEnd();
// Console.WriteLine("Your IP is: " + publicIP);
}
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string ip = "192.168.1.70"; string ip = "192.168.1.70";
// ip = "139.177.201.219"; // ip = "139.177.201.219";
EndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), 1234); EndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), 1234);
socket.Connect(serverEndPoint); socket.Connect(serverEndPoint);
data = new byte[1024]; rData = new byte[bufferSize];
wData = new byte[bufferSize];
peers = new Peer[64]; peers = new Peer[64];
Thread.Sleep(1000); // useful? Thread.Sleep(1000); // useful?
Thread readThread = new Thread(Read);
readThread.Start();
Thread writeThread = new Thread(Write);
writeThread.Start();
// socket.Close();
}
void Read() {
bool running = true; bool running = true;
while (running) { while (running) {
while (socket.Available > 0) { while (socket.Available > 0) {
try {socket.Receive(data, 0, data.Length, SocketFlags.None);} try { socket.Receive(rData, 0, bufferSize, SocketFlags.None); } catch (Exception e) {
catch (Exception e) {
Console.WriteLine($"can't connect to the server: {e}"); Console.WriteLine($"can't connect to the server: {e}");
return; return;
} }
head = 0; rHead = 0;
int id = ReadInt(); int id = ReadInt();
if (id != 0) { if (id != 0) {
int index = -1; int index = -1;
@ -72,66 +69,88 @@ public class MonoNet {
Console.WriteLine("too many peers"); Console.WriteLine("too many peers");
return; return;
} }
peers[index].cursor = ReadVec3(); peers[index].cursorA = ReadVec3();
peers[index].cursorB = ReadVec3();
peers[index].cursorC = ReadVec3();
peers[index].cursorD = ReadVec3();
peers[index].headset = ReadPose(); peers[index].headset = ReadPose();
peers[index].offHand = ReadPose(); peers[index].offHand = ReadPose();
peers[index].mainHand = ReadPose(); peers[index].mainHand = ReadPose();
} }
} }
}
}
data = new byte[1024]; void Write() {
head = 0; bool running = true;
while (running) {
wHead = 0;
WriteInt(me.id); WriteInt(me.id);
WriteVec3(me.cursor); WriteVec3(me.cursorA);
WriteVec3(me.cursorB);
WriteVec3(me.cursorC);
WriteVec3(me.cursorD);
WritePose(me.headset); WritePose(me.headset);
WritePose(me.offHand); WritePose(me.offHand);
WritePose(me.mainHand); WritePose(me.mainHand);
socket.Send(data); socket.Send(wData);
await Task.Delay(1); Thread.Sleep(60);
} }
socket.Close();
} }
int ReadInt() { int ReadInt() {
int value = BitConverter.ToInt32(data, head); int value = BitConverter.ToInt32(rData, rHead);
head += 4; rHead += 4;
return value; return value;
} void WriteInt(int value) { }
BitConverter.GetBytes(value).CopyTo(data, head); void WriteInt(int value) {
head += 4; BitConverter.GetBytes(value).CopyTo(wData, wHead);
wHead += 4;
}
float ReadFloat() {
float value = BitConverter.ToSingle(rData, rHead);
rHead += 4;
return value;
}
void WriteFloat(float value) {
BitConverter.GetBytes(value).CopyTo(wData, wHead);
wHead += 4;
} }
Vec3 ReadVec3() { Vec3 ReadVec3() {
Vec3 value = new Vec3( Vec3 value = new Vec3(
BitConverter.ToSingle(data, head), BitConverter.ToSingle(rData, rHead),
BitConverter.ToSingle(data, head + 4), BitConverter.ToSingle(rData, rHead + 4),
BitConverter.ToSingle(data, head + 8) BitConverter.ToSingle(rData, rHead + 8)
); );
head += 12; rHead += 12;
return value; return value;
} void WriteVec3(Vec3 vec) { }
BitConverter.GetBytes(vec.x).CopyTo(data, head); void WriteVec3(Vec3 vec) {
BitConverter.GetBytes(vec.y).CopyTo(data, head + 4); BitConverter.GetBytes(vec.x).CopyTo(wData, wHead);
BitConverter.GetBytes(vec.z).CopyTo(data, head + 8); BitConverter.GetBytes(vec.y).CopyTo(wData, wHead + 4);
head += 12; BitConverter.GetBytes(vec.z).CopyTo(wData, wHead + 8);
wHead += 12;
} }
Quat ReadQuat() { Quat ReadQuat() {
Quat value = new Quat( Quat value = new Quat(
BitConverter.ToSingle(data, head), BitConverter.ToSingle(rData, rHead),
BitConverter.ToSingle(data, head + 4), BitConverter.ToSingle(rData, rHead + 4),
BitConverter.ToSingle(data, head + 8), BitConverter.ToSingle(rData, rHead + 8),
BitConverter.ToSingle(data, head + 12) BitConverter.ToSingle(rData, rHead + 12)
); );
head += 16; rHead += 16;
return value; return value;
} void WriteQuat(Quat quat) { }
BitConverter.GetBytes(quat.x).CopyTo(data, head); void WriteQuat(Quat quat) {
BitConverter.GetBytes(quat.y).CopyTo(data, head + 4); BitConverter.GetBytes(quat.x).CopyTo(wData, wHead);
BitConverter.GetBytes(quat.z).CopyTo(data, head + 8); BitConverter.GetBytes(quat.y).CopyTo(wData, wHead + 4);
BitConverter.GetBytes(quat.w).CopyTo(data, head + 12); BitConverter.GetBytes(quat.z).CopyTo(wData, wHead + 8);
head += 16; BitConverter.GetBytes(quat.w).CopyTo(wData, wHead + 12);
wHead += 16;
} }
Pose ReadPose() { Pose ReadPose() {
@ -139,27 +158,42 @@ public class MonoNet {
ReadVec3(), ReadVec3(),
ReadQuat() ReadQuat()
); );
} void WritePose(Pose pose) { }
void WritePose(Pose pose) {
WriteVec3(pose.position); WriteVec3(pose.position);
WriteQuat(pose.orientation); WriteQuat(pose.orientation);
} }
string localIP, publicIP;
void GetIPs() {
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0)) {
socket.Connect("8.8.8.8", 65530);
IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
localIP = endPoint.Address.ToString();
}
publicIP = new WebClient().DownloadString("https://ipv4.icanhazip.com/").TrimEnd();
}
Mesh meshCube = Default.MeshCube; Mesh meshCube = Default.MeshCube;
Material matCube = Default.Material; Material matCube = Default.Material;
public void Cubee(Matrix m) { public void Cubee(Matrix m) {
meshCube.Draw(matCube, m); meshCube.Draw(matCube, m);
} }
public class Peer public class Peer {
{
public int id; public int id;
public Vec3 cursor; public Vec3 cursorA, cursorB, cursorC, cursorD;
public Pose headset; public Pose headset;
public Pose offHand; public Pose offHand;
public Pose mainHand; public Pose mainHand;
public Sound voice;
public SoundInst voiceInst; // update position
public Peer(int id) { public Peer(int id) {
this.id = id; this.id = id;
// voice = Sound.CreateStream(0.5f);
// voiceInst = voice.Play(Vec3.Zero, 0.5f);
} }
} }
} }

View file

@ -2,64 +2,73 @@ using StereoKit;
using System; using System;
class Program { class Program {
static void Main(string[] args) { static void Main(string[] args) {
SKSettings settings = new SKSettings { SKSettings settings = new SKSettings {
appName = "oriels", appName = "oriels",
assetsFolder = "Assets", assetsFolder = "Assets",
}; };
if (!SK.Initialize(settings)) if (!SK.Initialize(settings))
Environment.Exit(1); Environment.Exit(1);
// TextStyle style = Text.MakeStyle(Font.FromFile("DMMono-Regular.ttf"), 0.1f, Color.White); // TextStyle style = Text.MakeStyle(Font.FromFile("DMMono-Regular.ttf"), 0.1f, Color.White);
Mono.Run(); Mono mono = new Mono();
} mono.Run();
}
} }
public static class Mono { public class Mono {
public Mic mic;
public Controller offHand, mainHand;
public static Controller offHand, mainHand; public void Run() {
// mic = new Mic();
public static void Run() { MonoNet net = new MonoNet(this);
MonoNet net = new MonoNet();
net.Start(); net.Start();
// StretchCursor stretchCursor = new StretchCursor();
CubicFlow cubicFlow = new CubicFlow();
// ReachCursor reachCursor = new ReachCursor();
// SupineCursor supineCursor = new SupineCursor();
// ClawCursor clawCursor = new ClawCursor();
Oriel oriel = new Oriel();
oriel.Start();
// ColorCube cube = new ColorCube(); // ColorCube cube = new ColorCube();
// OrbitalView.strength = 4; // OrbitalView.strength = 4;
// OrbitalView.distance = 0.4f; // OrbitalView.distance = 0.4f;
// cube.thickness = 0.01f; // cube.thickness = 0.01f;
StretchCursor stretchCursor = new StretchCursor();
// ReachCursor reachCursor = new ReachCursor();
// SupineCursor supineCursor = new SupineCursor();
// ClawCursor clawCursor = new ClawCursor();
// Oriel oriel = new Oriel();
// oriel.Start();
// Lerper lerper = new Lerper(); // Lerper lerper = new Lerper();
while (SK.Step(() => { while (SK.Step(() => {
offHand = Input.Controller(Handed.Left); offHand = Input.Controller(Handed.Left);
mainHand = Input.Controller(Handed.Right); mainHand = Input.Controller(Handed.Right);
// mainHand.aim = Input.Hand(Handed.Right).palm; // mainHand.aim = Input.Hand(Handed.Right).palm;
cubicFlow.Step(offHand.aim, mainHand.aim);
stretchCursor.Step(offHand.aim, mainHand.aim); cubicFlow.DrawSelf();
net.me.cursor = stretchCursor.pos; net.me.cursorA = cubicFlow.p0;
// net.me.cursor = Vec3.Up * (float)Math.Sin(Time.Total); net.me.cursorB = cubicFlow.p1;
net.me.cursorC = cubicFlow.p2;
net.me.cursorD = cubicFlow.p3;
// net.me.cursorA = Vec3.Up * (float)Math.Sin(Time.Total);
net.me.headset = Input.Head; net.me.headset = Input.Head;
net.me.offHand = offHand.aim; net.me.offHand = offHand.aim;
net.me.mainHand = mainHand.aim; net.me.mainHand = mainHand.aim;
for (int i = 0; i < net.peers.Length; i++) { for (int i = 0; i < net.peers.Length; i++) {
MonoNet.Peer peer = net.peers[i]; MonoNet.Peer peer = net.peers[i];
if (peer != null) { if (peer != null) {
net.Cubee(Matrix.TRS(peer.cursor, Quat.Identity, Vec3.One * 0.05f)); net.Cubee(Matrix.TRS(peer.cursorA, Quat.Identity, Vec3.One * 0.05f));
net.Cubee(peer.headset.ToMatrix(Vec3.One * 0.3f)); net.Cubee(peer.headset.ToMatrix(Vec3.One * 0.3f));
net.Cubee(peer.offHand.ToMatrix(Vec3.One * 0.1f)); net.Cubee(peer.offHand.ToMatrix(Vec3.One * 0.1f));
net.Cubee(peer.mainHand.ToMatrix(Vec3.One * 0.1f)); net.Cubee(peer.mainHand.ToMatrix(Vec3.One * 0.1f));
cubicFlow.Draw(peer.cursorA, peer.cursorB, peer.cursorC, peer.cursorD);
} }
} }
oriel.Step();
// domHand subHand ?? :3 // domHand subHand ?? :3
@ -85,49 +94,161 @@ public static class Mono {
// new Pose(mainHand.aim.position, mainHand.aim.orientation), // new Pose(mainHand.aim.position, mainHand.aim.orientation),
// mainHand.IsStickClicked // mainHand.IsStickClicked
// ); // );
// oriel.Step();
// cursor.Draw(Matrix.S(0.1f)); // cursor.Draw(Matrix.S(0.1f));
})); })) ;
SK.Shutdown(); SK.Shutdown();
} }
} }
public class DrawKey { public class Mic {
public int x, y; public float[] bufferRaw = new float[0];
public Key key; public int bufferRawSize = 0;
public DrawKey(int x, int y, Key key) {
this.x = x; public int comp = 8;
this.y = y; public float[] buffer = new float[0];
this.key = key; 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]; }
}
}
} }
public class Lerper public class Lerper {
{
public float t = 0; public float t = 0;
public float spring = 1; public float spring = 1;
public float dampen = 1; public float dampen = 1;
float vel; float vel;
public void Step(float to = 1, bool bounce = false) public void Step(float to = 1, bool bounce = false) {
{
float dir = to - t; float dir = to - t;
vel += dir * spring * Time.Elapsedf; vel += dir * spring * Time.Elapsedf;
if (Math.Sign(vel) != Math.Sign(dir)) if (Math.Sign(vel) != Math.Sign(dir)) {
{
vel *= 1 - (dampen * Time.Elapsedf); vel *= 1 - (dampen * Time.Elapsedf);
} } else {
else
{
vel *= 1 - (dampen * 0.33f * Time.Elapsedf); vel *= 1 - (dampen * 0.33f * Time.Elapsedf);
} }
float newt = t + vel * Time.Elapsedf; float newt = t + vel * Time.Elapsedf;
if (bounce && (newt < 0 || newt > 1)) if (bounce && (newt < 0 || newt > 1)) {
{
vel *= -0.5f; vel *= -0.5f;
newt = Math.Clamp(newt, 0, 1); newt = Math.Clamp(newt, 0, 1);
} }
@ -135,47 +256,54 @@ public class Lerper
t = newt; t = newt;
} }
public void Reset() public void Reset() {
{
t = vel = 0; t = vel = 0;
} }
} }
public class Oriel { public class Oriel {
public Bounds bounds; public Bounds bounds;
// render
// Model model = Model.FromFile("oriel.glb", Shader.FromFile("oriel.hlsl"));
Material mat = new Material(Shader.FromFile("oriel.hlsl")); Material mat = new Material(Shader.FromFile("oriel.hlsl"));
Mesh mesh = Default.MeshCube; Mesh mesh = Default.MeshCube;
Mesh quad = Default.MeshQuad;
Vec3 _dimensions; Vec3 _dimensions;
public void Start() { public void Start() {
bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f)); bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f));
_dimensions = bounds.dimensions; _dimensions = bounds.dimensions;
} }
public void Step() { public void Step() {
// circle around center // circle around center
// bounds.center = Quat.FromAngles(0, 0, Time.Totalf * 60) * Vec3.Up * 0.3f; // bounds.center = Quat.FromAngles(0, 0, Time.Totalf * 60) * Vec3.Up * 0.3f;
// bounds.dimensions = _dimensions * (1f + (MathF.Sin(Time.Totalf * 3) * 0.3f)); // bounds.dimensions = _dimensions * (1f + (MathF.Sin(Time.Totalf * 3) * 0.3f));
mat.Transparency = Transparency.Blend; mat.Transparency = Transparency.Blend;
// mat.FaceCull = Cull.Front;
mat.SetFloat("_height", bounds.dimensions.y); mat.SetFloat("_height", bounds.dimensions.y);
mat.SetFloat("_ypos", bounds.center.y); mat.SetFloat("_ypos", bounds.center.y);
// mat.FaceCull = Cull.None;
mesh.Draw(mat, Matrix.TRS(bounds.center, Quat.Identity, bounds.dimensions)); 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));
}
} }
} }
public class Bitting { public class Bitting {
public class DrawKey {
Tex tex = new Tex(TexType.Image, TexFormat.Rgba32); public int x, y;
public Key key;
public DrawKey(int x, int y, Key key) {
this.x = x;
this.y = y;
this.key = key;
}
}
Tex tex = new Tex(TexType.Image, TexFormat.Rgba32);
Material material = Default.Material; Material material = Default.Material;
Mesh quad = Default.MeshQuad; Mesh quad = Default.MeshQuad;
int [,] bitchar = new int[,] { int[,] bitchar = new int[,] {
{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0},
@ -202,7 +330,7 @@ public class Bitting {
lastKey = null; lastKey = null;
} }
for (int i = 0; i < drawKeys.Length; i++){ for (int i = 0; i < drawKeys.Length; i++) {
DrawKey drawKey = drawKeys[i]; DrawKey drawKey = drawKeys[i];
if (Input.Key(drawKey.key).IsJustActive()) { if (Input.Key(drawKey.key).IsJustActive()) {
bitchar[drawKey.x, drawKey.y] = 1; bitchar[drawKey.x, drawKey.y] = 1;
@ -252,9 +380,9 @@ public static class PullRequest {
Vec3 ds = b.dimensions; Vec3 ds = b.dimensions;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
Quat q = Quat.FromAngles(i * 90, 0, 0); Quat q = Quat.FromAngles(i * 90, 0, 0);
Lines.Add(q * (new Vec3(0, 0, 0) - c) * ds, q * (new Vec3(0, 1, 0) - c) * ds, color, color, thickness); Lines.Add(q * (new Vec3(0, 0, 0) - c) * ds, q * (new Vec3(0, 1, 0) - c) * ds, color, color, thickness);
Lines.Add(q * (new Vec3(0, 1, 0) - c) * ds, q * (new Vec3(1, 1, 0) - c) * ds, color, color, thickness); Lines.Add(q * (new Vec3(0, 1, 0) - c) * ds, q * (new Vec3(1, 1, 0) - c) * ds, color, color, thickness);
Lines.Add(q * (new Vec3(1, 1, 0) - c) * ds, q * (new Vec3(1, 0, 0) - c) * ds, color, color, thickness); Lines.Add(q * (new Vec3(1, 1, 0) - c) * ds, q * (new Vec3(1, 0, 0) - c) * ds, color, color, thickness);
// convert to linepoints // convert to linepoints
} }

View file

@ -37,12 +37,46 @@ public class ReachCursor : SpatialCursor {
} }
public class TwistCursor : SpatialCursor { public class TwistCursor : SpatialCursor {
public void Step(Vec3 mainPos, Quat mainQuat) { public void Step(Vec3 mainPos, Quat mainQuat, float str = 1) {
Quat rel = Quat.LookAt(Vec3.Zero, mainQuat * Vec3.Forward); Quat rel = Quat.LookAt(Vec3.Zero, mainQuat * Vec3.Forward);
float twist = (Vec3.Dot(rel * -Vec3.Right, mainQuat * Vec3.Up) + 1) / 2; float twist = (Vec3.Dot(rel * -Vec3.Right, mainQuat * Vec3.Up) + 1) / 2;
pos = mainPos + mainQuat * Vec3.Forward * twist; pos = mainPos + mainQuat * Vec3.Forward * twist * str;
model.Draw(Matrix.TS(pos, 0.06f)); model.Draw(Matrix.TS(pos, 0.02f));
}
}
public class CubicFlow {
public Vec3 p0, p1, p2, p3;
public TwistCursor offTwist = new TwistCursor();
public TwistCursor mainTwist = new TwistCursor();
public void Step(Pose offPose, Pose mainPose) {
offTwist.Step(offPose.position, offPose.orientation, 3);
mainTwist.Step(mainPose.position, mainPose.orientation, 3);
p0 = offPose.position;
p1 = offTwist.pos;
p2 = mainTwist.pos;
p3 = mainPose.position;
// if toggle
}
public void DrawSelf() {
Draw(this.p0, this.p1, this.p2, this.p3);
}
LinePoint[] bezier = new LinePoint[64];
public void Draw(Vec3 p0, Vec3 p1, Vec3 p2, Vec3 p3) {
for (int i = 0; i < bezier.Length; i++) {
float t = i / ((float)bezier.Length - 1);
Vec3 a = Vec3.Lerp(p0, p1, t);
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);
}
Lines.Add(bezier);
} }
} }

16
omnisharp.json Normal file
View file

@ -0,0 +1,16 @@
{
"FormattingOptions": {
"NewLinesForBracesInLambdaExpressionBody": false,
"NewLinesForBracesInAnonymousMethods": false,
"NewLinesForBracesInAnonymousTypes": false,
"NewLinesForBracesInControlBlocks": false,
"NewLinesForBracesInTypes": false,
"NewLinesForBracesInMethods": false,
"NewLinesForBracesInProperties": false,
"NewLinesForBracesInObjectCollectionArrayInitializers": false,
"NewLinesForBracesInAccessors": false,
"NewLineForElse": false,
"NewLineForCatch": false,
"NewLineForFinally": false
}
}