oriels/.past/Monolith.cs
2022-03-17 16:55:59 -04:00

1286 lines
No EOL
33 KiB
C#

using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.XR;
using Unity.Collections;
using Unity.Networking.Transport;
using MLAPI.Puncher.Client;
using System;
using System.Net;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.ABI.Model;
using Nethereum.Contracts;
using Nethereum.JsonRpc.UnityClient;
using TMPro;
using NaughtyAttributes;
using Shapes;
using Vector2 = UnityEngine.Vector2;
using Vector3 = UnityEngine.Vector3;
using Quaternion = UnityEngine.Quaternion;
using Matrix4x4 = UnityEngine.Matrix4x4;
using Random = UnityEngine.Random;
public class Monolith : ImmediateModeShapeDrawer
{
public GOManager goManager;
public Contract contract;
public Peer peer;//, toPeer;
public Rig rig;
Oriel[] oriels = new Oriel[32];
// wrap these in a dof class?
public StretchCursor stretchCursor;
public TwistCursor leftTwistCursor, rightTwistCursor;
public Grabber leftGrabber, rightGrabber;
// public Latent latent;
// public Alpha alpha;
public Render render;
void Start()
{
goManager.Start("Prefabs/", this.transform);
rig.Start(this);
contract.Start(this);
// toPeer.Start(this, "peer 2");
peer.Start(this, "peer 1");
noise = new Noise(9000);
plane = goManager.GetPrefab("plane");
stretchCursor.Start(this);
leftTwistCursor.Start(this, rig.offHand);
rightTwistCursor.Start(this, rig.mainHand);
leftGrabber.Start(this, rig.offHand);
rightGrabber.Start(this, rig.mainHand);
// latent.Start(this);
// alpha.Start(this);
render.Start(this);
}
Noise noise;
GameObject plane;
public Vector3 planePos;
void OnDisable()
{
// alpha.Stop();
// peer.Stop();
}
void Update()
{
rig.Update();
contract.Update();
peer.Update();
// toPeer.Update();
Mesh meshPlane = plane.GetComponent<MeshFilter>().mesh;
// set vertex colors to green
List<Color> colors = new List<Color>();
meshPlane.GetColors(colors);
if (colors.Count != meshPlane.vertexCount)
{
colors.Clear();
colors.AddRange(new Color[meshPlane.vertexCount]);
}
Color c = new Color(46 / 256f, 67 / 256f, 34 / 256f);
for (int i = 0; i < colors.Count; i++)
{
colors[i] = c;
}
meshPlane.SetColors(colors);
List<Vector3> verts = new List<Vector3>();
meshPlane.GetVertices(verts);
for (int i = 0; i < verts.Count; i++)
{
Vector3 meshV = verts[i];
Vector3 noiseV = verts[i] + planePos;
float x = noiseV.x / 3;
float z = noiseV.z / 3;
int xi = Mathf.FloorToInt(x);
int zi = Mathf.FloorToInt(z);
float c00 = noise.D2(xi, zi);
float c10 = noise.D2(xi + 1, zi);
float c01 = noise.D2(xi, zi + 1);
float c11 = noise.D2(xi + 1, zi + 1);
meshV.y = Mathf.LerpUnclamped(
Mathf.LerpUnclamped(c00, c10, ut(x - xi)),
Mathf.LerpUnclamped(c01, c11, ut(x - xi)),
ut(z - zi)
) * 1.5f; // scale height
float ut(float t)
{
// if negative, then flip
return t < 0 ? 1 - Mathf.Abs(t) : t;
}
verts[i] = meshV;
}
meshPlane.SetVertices(verts);
meshPlane.RecalculateNormals();
meshPlane.RecalculateBounds();
MeshCollider colPlane = plane.GetComponent<MeshCollider>();
colPlane.sharedMesh = meshPlane;
stretchCursor.Update();
leftGrabber.Update();
rightGrabber.Update();
// leftTwistCursor.Update(leftGrabber.cursor);
// rightTwistCursor.Update(rightGrabber.cursor);
leftTwistCursor.sensitivity += rig.rHand.joystick.y * Time.deltaTime;
rightTwistCursor.sensitivity = leftTwistCursor.sensitivity;
leftTwistCursor.Update(rig.lHand.pos);
rightTwistCursor.Update(rig.rHand.pos);
// latent.Update();
// alpha.Update();
render.Update();
}
public override void DrawShapes(Camera cam)
{
render.DrawShapes(cam);
}
string log = "oriels 0.0.1\n(c) 2018-21 dofdev\n\n";
void OnGUI()
{
// change gui font
GUI.skin.font = (Font)Resources.Load("Fonts/DM-Mono");
GUI.skin.label.fontSize = 14;
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUI.skin.label.normal.textColor = Color.white;
GUI.skin.label.fontStyle = FontStyle.Normal;
GUI.Label(new Rect(10, 10, 512, 256), log);
// how to render censored *****
// peer.newPeerIP = GUI.PasswordField(CenterRect(new Rect(0, Screen.height - 120, 256, 28)), peer.newPeerIP, '*');
// // Debug.Log(peer.newPeerIP);
// peer.connect = GUI.Button(CenterRect(new Rect(0, Screen.height - 80, 128, 28)), "connect");
// peer.disconnect = GUI.Button(CenterRect(new Rect(0, Screen.height - 50, 128, 28)), "disconnect");
// Rect CenterRect(Rect rect)
// {
// rect.x = (Screen.width / 2) - (rect.width / 2);
// return rect;
// }
}
public void Log(string s)
{
log += s + "\n";
// if number of lines > 10 then remove the oldest line
int lines = log.Split('\n').Length;
if (lines > 10)
{
log = log.Substring(log.IndexOf('\n') + 1);
}
}
[Button]
public void Test()
{
}
}
[Serializable]
public class GOManager
{
[HideInInspector] public GameObject[] prefabs;
public void Start(string folderName, Transform parent)
{
prefabs = Resources.LoadAll<GameObject>(folderName + "/");
for (int i = 0; i < prefabs.Length; i++)
{
string name = prefabs[i].name;
prefabs[i] = GameObject.Instantiate(prefabs[i], parent);
prefabs[i].name = name;
}
}
public GameObject GetPrefab(string name)
{
for (int i = 0; i < prefabs.Length; i++)
{
if (prefabs[i].name.ToLower() == name.ToLower())
{
return prefabs[i];
}
}
Debug.LogWarning("Prefab not found: " + name);
return null;
}
}
[Serializable]
public class Contract
{
Monolith mono;
string url = "http://localhost:7545"; // set your rpc url here
string privateKey = "d838218fe7f406ad746a3eb70d5f8095f73f0d6f0e254f824323e0ef6fcbdd01";
string[] accounts = {
"0x03b60D1303328a2a1dae344D4A317ee26a2aaf04",
"0x8250C318c76a336fC9FE6Eb39c115bBad62ed8a0",
"0x81B6e80037FDa721aC96d6D38DD65d24463559C2"
};
string contractAddress = "0x58c58B56EC30628005823062A2238266e477f9e4";
public void Start(Monolith mono)
{
this.mono = mono;
mono.StartCoroutine(GetAccountBalance());
}
public void Update()
{
}
public IEnumerator GetAccountBalance()
{
// var getBalanceRequest = new EthGetBalanceUnityRequest(url);
// yield return getBalanceRequest.SendRequest(account, Nethereum.RPC.Eth.DTOs.BlockParameter.CreateLatest());
// if (getBalanceRequest.Exception == null)
// {
// var balance = getBalanceRequest.Result.Value;
// var n = Nethereum.Util.UnitConversion.Convert.FromWei(balance, 18).ToString("n8");
// mono.Log(n);
// }
// else
// {
// mono.Log(getBalanceRequest.Exception.Message);
// }
// var newExpense = new QueryUnityRequest<NewExpenseFunction, NewExpenseFunctionOutput>(url, accounts[0]);
// yield return newExpense.Query(new NewExpenseFunction()
// {
// PayTo = accounts[2],
// Description = "test expense",
// Amount = 1000000000
// }, contractAddress);
// mono.Log(newExpense.Result.Index);
var signExpense = new QueryUnityRequest<SignExpenseFunction, SignExpenseFunctionOutput>(url, accounts[1]);
yield return signExpense.Query(new SignExpenseFunction()
{
Index = 0,
Amount = 1000000000
}, contractAddress);
mono.Log(signExpense.Result.Message);
}
[Function("newExpense", "uint256")]
public class NewExpenseFunction : FunctionMessage
{
[Parameter("address", "payTo", 1)]
public string PayTo { get; set; }
[Parameter("string", "description", 2)]
public string Description { get; set; }
[Parameter("uint256", "amount", 3)]
public int Amount { get; set; }
}
[FunctionOutput]
public class NewExpenseFunctionOutput : IFunctionOutputDTO
{
[Parameter("uint256", 1)]
public int Index { get; set; }
}
[Function("signExpense", "string")]
public class SignExpenseFunction : FunctionMessage
{
[Parameter("uint256", "index", 1)]
public int Index { get; set; }
[Parameter("uint256", "amount", 2)]
public int Amount { get; set; }
}
[FunctionOutput]
public class SignExpenseFunctionOutput : IFunctionOutputDTO
{
[Parameter("string", 1)]
public string Message { get; set; }
}
}
[Serializable]
public class Peer
{
Monolith mono;
string name;
public bool connect;
public bool disconnect;
public NetworkDriver m_Driver;
private List<Connection> connections = new List<Connection>();
[Serializable]
public class Connection
{
NetworkConnection connection;
public IPAddress ip;
public Connection(NetworkConnection connection, IPAddress ip)
{
this.connection = connection;
this.ip = ip;
}
}
private string puncherHost
{
get { return "139.177.201.219"; }
}
private ushort puncherPort = 6776;
private List<Punch> punchList = new List<Punch>();
[Serializable]
public class Punch
{
public bool ping;
public string ip;
public Punch(bool ping, string ip)
{
this.ping = ping;
this.ip = ip;
}
}
[HideInInspector] public string newPeerIP;
private string publicIP;
private ushort port = 9000;
public void Start(Monolith mono, string name)
{
this.mono = mono;
this.name = name;
// publicIP = new WebClient().DownloadString("https://ipv4.icanhazip.com/").TrimEnd();
// Task.Factory.StartNew(() =>
// {
// try
// {
// mono.Log(name + " is listening for a Punch");
// using (PuncherClient listenPunch = new PuncherClient(puncherHost, puncherPort))
// {
// while (true)
// {
// IPEndPoint endpoint = listenPunch.ListenForSinglePunch(new IPEndPoint(IPAddress.Any, port));
// mono.Log(name + " was punched");
// }
// }
// }
// catch (Exception e)
// {
// mono.Log(e.Message);
// }
// });
// m_Driver = NetworkDriver.Create();
// mono.Log(name + " is allocated");
// var endpoint = NetworkEndPoint.AnyIpv4;
// endpoint.Port = port;
// if (m_Driver.Bind(endpoint) != 0)
// {
// mono.Log(name + " failed to bind to port " + endpoint.Port);
// }
// else
// {
// m_Driver.Listen();
// mono.Log(name + " is listening on port " + endpoint.Port);
// }
}
public void Connect()
{
// // check for validity
// // check for duplicates
// mono.Log(name + " is winding up...");
// Task.Factory.StartNew(() =>
// {
// Punch punch = new Punch(true, newPeerIP);
// punchList.Add(punch);
// using (PuncherClient punchPeer = new PuncherClient(puncherHost, puncherPort))
// {
// while (true)
// {
// if (!punch.ping) { continue; }
// if (punchPeer.TryPunch(IPAddress.Parse(punch.ip), out IPEndPoint punchResult))
// {
// mono.Log(name + " punched through to port " + punchResult.Port);
// var endpoint = NetworkEndPoint.LoopbackIpv4;
// endpoint.Port = port;
// if (newPeerIP != publicIP)
// {
// endpoint = NetworkEndPoint.Parse(punchResult.Address.ToString(), (ushort)punchResult.Port);
// }
// connections.Add(m_Driver.Connect(endpoint));
// mono.Log(name + " attempting to connect to the punched");
// }
// else
// {
// mono.Log(name + " failed to punch");
// }
// }
// }
// });
}
public void Disconnect()
{
// for (int i = 0; i < connections.Length; i++)
// {
// if (connections[i].IsCreated)
// {
// connections[i].Disconnect(m_Driver);
// connections[i] = default(NetworkConnection);
// }
// }
// mono.Log(name + " is disconnecting");
}
public void Stop()
{
// m_Driver.Dispose();
// mono.Log(name + " is disposed of");
}
public void Update()
{
// if (connect)
// {
// Connect();
// connect = false;
// }
// if (disconnect)
// {
// Disconnect();
// disconnect = false;
// }
// m_Driver.ScheduleUpdate().Complete();
// AcceptNewConnections();
// void AcceptNewConnections()
// {
// NetworkConnection c;
// while ((c = m_Driver.Accept()) != default(NetworkConnection))
// {
// // check NetworkConnection ip address
// IPAddress ip = c.RemoteEndPoint.Ipv4Address;
// System.Net.Sockets.UdpReceiveResult result;
// connections.Add(new Connection(c, ip));
// mono.Log(name + " accepted a connection");
// // what if both peers are punching
// }
// }
// DataStreamReader reader;
// for (int i = 0; i < connections.Length; i++)
// {
// if (!connections[i].IsCreated)
// {
// connections.RemoveAtSwapBack(i);
// --i;
// continue;
// }
// NetworkEvent.Type cmd;
// while ((cmd = m_Driver.PopEventForConnection(connections[i], out reader)) != 0)
// {
// switch (cmd)
// {
// case NetworkEvent.Type.Connect:
// mono.Log(name + " connected to peer");
// m_Driver.BeginSend(NetworkPipeline.Null, connections[i], out var writer);
// writer.WriteUInt(1);
// m_Driver.EndSend(writer);
// mono.Log(name + " sent 1 to peer");
// break;
// case NetworkEvent.Type.Data:
// mono.Log(name + " received data from peer");
// uint value = reader.ReadUInt();
// mono.Log(name + " received " + value);
// break;
// case NetworkEvent.Type.Disconnect:
// mono.Log(name + " disconnected from a peer");
// connections[i] = default(NetworkConnection);
// break;
// default:
// mono.Log(name + " received an unknown network event");
// break;
// }
// }
// }
}
}
[Serializable]
public class Rig
{
Monolith mono;
[HideInInspector]
public Transform headset;
public PhysicalInput lHand, rHand;
public PhysicalInput offHand, mainHand;
public void Start(Monolith mono)
{
this.mono = mono;
headset = mono.goManager.GetPrefab("headset").transform;
// convert to goManager
lHand.Start();
rHand.Start();
bool lefty = false;
if (lefty)
{
offHand = rHand;
mainHand = lHand;
}
else
{
offHand = lHand;
mainHand = rHand;
}
}
XRHMD hmd;
XRController lCon, rCon;
public void Update()
{
Vector3 height = new Vector3(0, 0.67f, 0);
RaycastHit hit;
// raycast down to find the floor
if (Physics.Raycast(headset.position, Vector3.down, out hit, Mathf.Infinity, LayerMask.GetMask("Ground")))
{
height += hit.point;
}
if (hmd != null && hmd.wasUpdatedThisFrame)
{
headset.position = height + hmd.centerEyePosition.ReadValue();
headset.rotation = hmd.centerEyeRotation.ReadValue();
}
else
{
hmd = InputSystem.GetDevice<XRHMD>();
}
if (lCon != null && lCon.wasUpdatedThisFrame)
{
lHand.pos = height + (Vector3)lCon.TryGetChildControl("pointerPosition").ReadValueAsObject();
lHand.rot = (Quaternion)lCon.TryGetChildControl("pointerRotation").ReadValueAsObject();
lHand.faceBtn.Set(lCon.TryGetChildControl("primarybutton").IsPressed());
lHand.triggerBtn.Set(lCon.TryGetChildControl("triggerpressed").IsPressed());
lHand.joystick = (Vector2)lCon.TryGetChildControl("joystick").ReadValueAsObject();
// Debug.Log all the controls
// UnityEngine.InputSystem.Utilities.ReadOnlyArray<InputControl> controls = lCon.allControls;
// foreach (InputControl control in controls)
// {
// Debug.Log(control.name + ": " + control.ReadValueAsObject());
// }
}
else
{
lCon = XRController.leftHand;
}
if (rCon != null && rCon.wasUpdatedThisFrame)
{
rHand.pos = height + (Vector3)rCon.TryGetChildControl("pointerPosition").ReadValueAsObject();
rHand.rot = (Quaternion)rCon.TryGetChildControl("pointerRotation").ReadValueAsObject();
rHand.faceBtn.Set(rCon.TryGetChildControl("primarybutton").IsPressed());
rHand.triggerBtn.Set(rCon.TryGetChildControl("triggerpressed").IsPressed());
rHand.joystick = (Vector2)rCon.TryGetChildControl("joystick").ReadValueAsObject();
}
else
{
rCon = XRController.rightHand;
}
}
}
[Serializable]
public class PhysicalInput
{
public Vector3 pos;
public Quaternion rot;
public void Start()
{
this.pos = Vector3.zero;
this.rot = Quaternion.identity;
}
// trigger
// triggerTouch
public Btn triggerBtn;
public Btn faceBtn;
public Vector2 joystick;
}
[Serializable]
public class Btn
{
public bool down;
public bool held;
public bool up;
public void Set(bool held)
{
down = up = false;
if (this.held)
{
if (!held)
{
up = true;
}
}
else
{
if (held)
{
down = true;
}
}
this.held = held;
}
}
[Serializable]
public class Oriel
{
Monolith mono;
public Vector3 pos;
public Quaternion rot;
public Vector3 size;
// oriels do not exist on their own
// an project creates one to be seen by the user
// its a way to manage multiple spatial apps simultaneously
// without conflicts
// the fullscreen equivalent is either
// a orbital view oriel
// or a maximized oriel
public void Start(Monolith mono)
{
this.mono = mono;
size = new Vector3(0.3f, 0.2f, 0.2f);
}
public void Update()
{
}
public void Render()
{
}
}
[Serializable]
public class StretchCursor
{
Monolith mono;
public Vector3 cursor;
public float stretch;
float deadZone = 0.1f;
public void Start(Monolith mono)
{
this.mono = mono;
}
public void Update()
{
PhysicalInput offHand = mono.rig.offHand;
PhysicalInput mainHand = mono.rig.mainHand;
stretch = Mathf.Max((offHand.pos - mainHand.pos).magnitude - deadZone, 0);
cursor = mainHand.pos + mainHand.rot * Vector3.forward * stretch * 3;
}
}
[Serializable]
public class TwistCursor
{
Monolith mono;
PhysicalInput hand;
public Vector3 cursor;
public float sensitivity;
public float twist;
public bool outty;
public void Start(Monolith mono, PhysicalInput hand)
{
this.mono = mono;
this.hand = hand;
this.sensitivity = 3.5f;
}
public void Update(Vector3 origin)
{
// the z twist of the mainHand relative to where its pointing
Quaternion rel = Quaternion.LookRotation(hand.rot * Vector3.forward);
twist = Vector3.Angle(rel * Vector3.up, hand.rot * Vector3.up) / 180;
// detect if twist is left or right
outty = (Vector3.Dot(Vector3.up, hand.rot * Vector3.left) > 0);
// twist = Mathf.Max(twist - 0.05f, 0);
cursor = origin + hand.rot * Vector3.forward * twist * sensitivity;
}
}
[Serializable]
public class Grabber
{
Monolith mono;
PhysicalInput hand;
public Vector3 cursor;
public Vector3 origin;
public Vector3 originWorldPos;
public float stretch;
public void Start(Monolith mono, PhysicalInput hand)
{
this.mono = mono;
this.hand = hand;
}
public void Update()
{
Transform head = mono.rig.headset;
Quaternion headTurn = Quaternion.Euler(0, head.rotation.eulerAngles.y, 0);
if (mono.rig.mainHand.triggerBtn.down)
{
origin = hand.pos - head.position;
origin = Quaternion.Inverse(headTurn) * origin;
}
originWorldPos = head.position + headTurn * origin;
Vector3 dir = (hand.pos - originWorldPos).normalized;
stretch = Vector3.Distance(hand.pos, originWorldPos);
cursor = hand.pos + dir * stretch * 3;
}
}
[Serializable]
public class Latent
{
Monolith mono;
// space.add(relative possible position)
// direction = (space[x] - from).normalized
// position += direction * (forward - back)
// every couple months
public string[] questions = new string[] {
"what are the same problems that im running into repeatedly",
"if i take a leveraged risk, what is the worst thing that could happen",
"what are the most critical things im missing",
"how do we 10x our results",
"what do i need to increase the value of what im doing 10x",
"how do we take our 1-3-5 year plans and turn them into 1-3-5 month plans",
"if i only worked 2 hours a week on my business/venture/goal, what would i do",
"am i delegating appropriately",
"am i investing a certain % of my income (the highest possible) back into making more / my business",
"what if i only could subtract things from my life"
};
// monthly
public string[] directions = new string[] {
"what has had the greatest negative emotional impact on my life in the last month",
"what 20% of activities / people are taking 80% of my time",
"what are 20% of the activities and people that are producting 80% of my problems",
"what has had the greatest positive emotional impact on my life in the last month",
"what 20% of activities / people are making the most 80% of my time",
"what are 20% of the activities / people that are producting 80% of what I want"
};
// weekly
public string[] todo = new string[5];
public string[] nodo = new string[5];
// respond to all these prompts in a pseudo code fashion
public void Start(Monolith mono)
{
this.mono = mono;
}
public void Update()
{
// I want the higher level visualization to be very spatial
// as you respond to the prompts, you'll place the responses in a space relative to your position
// the todo nodo are just vectors drawn from your position toward the responses *not always connected*
// when you review
// the actions you made can be immediately visualized by having your position change
// by the sum of vectors acted upon
// its all persistent!
// drag the space around to move
// zoomed out = points
// zoomed in = text
// dofs
// vien systems
}
}
[Serializable]
public class Alpha
{
Monolith mono;
// GOAL: to layout the patterns of the alphabet to were I can better optimize them
// for a lower key count input device for VR / mobile
// making the alphabet more phoenetically consistant would be cool as a thing to tackle after
public GameObject textPrefab;
public Material textMaterial;
public Transform[,,] textMeshes = new Transform[3, 3, 3];
Data data = null;
public void Start(Monolith mono)
{
this.mono = mono;
data = DataManager.Deserialize();
if (data == null)
{
data = new Data();
data.map = new char[3, 3, 3] {
{
{'a', 'b', 'c'},
{'d', 'e', 'f'},
{'g', 'h', 'i'}
},
{
{'j', 'k', 'l'},
{'m', 'n', 'o'},
{'p', 'q', 'r'}
},
{
{'s', 't', 'u'},
{'v', 'w', 'x'},
{'y', 'z', ' '}
}
};
}
// setup text meshes in 3d space
for (int i = 0; i < data.map.GetLength(0); i++)
{
for (int j = 0; j < data.map.GetLength(1); j++)
{
for (int k = 0; k < data.map.GetLength(2); k++)
{
GameObject textObj = GameObject.Instantiate(textPrefab);
textObj.transform.position = new Vector3(i, j, k);
TextMeshPro textMesh = textObj.transform.GetComponent<TextMeshPro>();
// set color based on position xyz -> rgb
textMesh.color = new Color(
i / ((float)data.map.GetLength(0) - 1),
j / ((float)data.map.GetLength(1) - 1),
k / ((float)data.map.GetLength(2) - 1)
);
// set material
textMesh.fontMaterial = textMaterial;
textMeshes[i, j, k] = textObj.transform;
}
}
}
}
public void Stop()
{
DataManager.Serialize(data);
}
Vector3Int cursor = new Vector3Int(0, 0, 0);
Quaternion viewRot = Quaternion.identity;
public void Update()
{
// if (SceneView.HasOpenInstances<SceneView>())
// {
// SceneView view = SceneView.lastActiveSceneView;
// if (view != null)
// {
// viewRot = view.rotation;
// }
// }
Vector3Int oldCursor = cursor;
// move cursor WASD
// and wrap around
// increment relative to viewRot
// by rotating the vector by viewRot
Keyboard keeb = Keyboard.current;
if (keeb.aKey.wasPressedThisFrame)
{
Vector3 v = viewRot * Vector3.left;
cursor += new Vector3Int(Mathf.RoundToInt(v.x), Mathf.RoundToInt(v.y), Mathf.RoundToInt(v.z));
}
if (keeb.dKey.wasPressedThisFrame)
{
Vector3 v = viewRot * Vector3.right;
cursor += new Vector3Int(Mathf.RoundToInt(v.x), Mathf.RoundToInt(v.y), Mathf.RoundToInt(v.z));
}
if (keeb.wKey.wasPressedThisFrame)
{
Vector3 v = viewRot * Vector3.up;
cursor += new Vector3Int(Mathf.RoundToInt(v.x), Mathf.RoundToInt(v.y), Mathf.RoundToInt(v.z));
}
if (keeb.sKey.wasPressedThisFrame)
{
Vector3 v = viewRot * Vector3.down;
cursor += new Vector3Int(Mathf.RoundToInt(v.x), Mathf.RoundToInt(v.y), Mathf.RoundToInt(v.z));
}
// wrap around
if (cursor.x >= data.map.GetLength(0)) { cursor.x = 0; }
if (cursor.x < 0) { cursor.x = data.map.GetLength(0) - 1; }
if (cursor.y >= data.map.GetLength(1)) { cursor.y = 0; }
if (cursor.y < 0) { cursor.y = data.map.GetLength(1) - 1; }
if (cursor.z >= data.map.GetLength(2)) { cursor.z = 0; }
if (cursor.z < 0) { cursor.z = data.map.GetLength(2) - 1; }
// shift character
// by moving the character in the data.map
// based on oldCursor and cursor
if (oldCursor != cursor && keeb.leftShiftKey.isPressed)
{
char oldChar = data.map[oldCursor.x, oldCursor.y, oldCursor.z];
char newChar = data.map[cursor.x, cursor.y, cursor.z];
data.map[oldCursor.x, oldCursor.y, oldCursor.z] = newChar;
data.map[cursor.x, cursor.y, cursor.z] = oldChar;
}
// this is 3d shit, use your VR shit ^-^
// textMeshes face camera
for (int i = 0; i < textMeshes.GetLength(0); i++)
{
for (int j = 0; j < textMeshes.GetLength(1); j++)
{
for (int k = 0; k < textMeshes.GetLength(2); k++)
{
TextMeshPro textMesh = textMeshes[i, j, k].GetComponent<TextMeshPro>();
// set text to char from data.map
textMesh.text = data.map[i, j, k].ToString();
textMeshes[i, j, k].transform.rotation = viewRot;
if (i == cursor.x && j == cursor.y && k == cursor.z)
{
// bold
textMesh.fontStyle = FontStyles.Bold;
textMesh.outlineWidth = 0.1f;
// inverted color
textMesh.outlineColor = new Color(1 - textMesh.color.r, 1 - textMesh.color.g, 1 - textMesh.color.b);
}
else
{
// normal
textMesh.fontStyle = FontStyles.Normal;
textMesh.outlineWidth = 0;
}
}
}
}
}
}
[Serializable]
public class Render
{
Monolith mono;
Material[] materials;
Mesh[] meshes;
public void Start(Monolith mono)
{
this.mono = mono;
materials = Resources.LoadAll<Material>("Materials/");
meshes = Resources.LoadAll<Mesh>("Meshes/");
spectator = mono.goManager.GetPrefab("spectator").transform;
}
Transform spectator;
public void DrawShapes(Camera cam)
{
using (Draw.Command(cam))
{
Draw.LineGeometry = LineGeometry.Volumetric3D;
Draw.ThicknessSpace = ThicknessSpace.Meters;
// Draw.ZTest = UnityEngine.Rendering.CompareFunction.Less;
// Draw.ZOffsetFactor = 0
Draw.Matrix = mono.transform.localToWorldMatrix;
// put it in camera space? to fix order issues?
// draw lines
// Draw.Sphere(mono.leftTwistCursor.cursor, 0.1f, Color.black);
// float stretch = (1 - mono.leftGrabber.stretch) * (1 - mono.leftTwistCursor.twist);
// Draw.Thickness = 0.2f * stretch;
// Draw.Line(mono.rig.lHand.pos, mono.leftGrabber.cursor, Color.white);
// Draw.Line(mono.leftGrabber.cursor, mono.leftTwistCursor.cursor, Color.white);
Draw.Thickness = 0.01f;
// Draw.Line(mono.rig.rHand.pos, mono.rightTwistCursor.cursor, Color.white);
// Draw.Sphere(mono.rightTwistCursor.cursor, 0.1f, Color.black);
// stretch = (1 - mono.rightGrabber.stretch) * (1 - mono.rightTwistCursor.twist);
// Draw.Thickness = 0.2f * stretch;
// Draw.Line(mono.rig.rHand.pos, mono.rightGrabber.cursor, Color.white);
// Draw.Line(mono.rightGrabber.cursor, mono.rightTwistCursor.cursor, Color.white);
// Draw.Line(mosno.rig.lHand.pos, mono.leftTwistCursor.cursor, Color.white);
// just hands with twist cursors
// deadzone 0)
if (mono.rig.rHand.triggerBtn.down)
{
toggle = !toggle;
}
Vector3 p0 = mono.rig.lHand.pos;
Vector3 p1 = mono.leftTwistCursor.cursor;
Vector3 p2 = mono.rightTwistCursor.cursor;
Vector3 p3 = mono.rig.rHand.pos;
if (toggle && !mono.leftTwistCursor.outty)
{
Vector3 pp = p0;
p0 = p1;
p1 = pp;
}
if (toggle && mono.rightTwistCursor.outty)
{
Vector3 pp = p2;
p2 = p3;
p3 = pp;
}
Vector3 lightPos = p0;
Vector3 pastPos = p0;
for (int i = 0; i < 64; i++)
{
float t = i / 63.0f;
Vector3 a = Vector3.Lerp(p0, p1, t);
Vector3 b = Vector3.Lerp(p1, p2, t);
Vector3 c = Vector3.Lerp(p2, p3, t);
Vector3 pos = Vector3.Lerp(Vector3.Lerp(a, b, t), Vector3.Lerp(b, c, t), t);
Draw.Line(pastPos, pos, Color.blue);
pastPos = pos;
if (i == lightIndex)
{
lightPos = pos;
}
}
Draw.Sphere(lightPos, 0.02f, Color.white);
lightStep += Time.deltaTime;
if (lightStep > 0.0333f)
{
if (lightLeft)
{
if (lightIndex < 63)
{
lightIndex++;
lightStep = 0;
}
}
else
{
if (lightIndex > 0)
{
lightIndex--;
lightStep = 0;
}
}
}
if (mono.rig.lHand.faceBtn.down)
{
lightLeft = true;
}
if (mono.rig.rHand.faceBtn.down)
{
lightLeft = false;
}
}
}
bool toggle = false;
int lightIndex = 0;
float lightStep = 0;
bool lightLeft;
public void Update()
{
// draw out the hands
DrawMesh("controller", "default", mono.rig.lHand.pos, mono.rig.lHand.rot, 2);
DrawMesh("controller", "default", mono.rig.rHand.pos, mono.rig.rHand.rot, 2);
// draw out the cursor
// DrawMesh("controller", "default", mono.stretchCursor.cursor, Quaternion.identity, 0.5f);
DrawMesh("cursor", "default", mono.leftTwistCursor.cursor, Quaternion.identity, 0.02f);
DrawMesh("cursor", "default", mono.rightTwistCursor.cursor, Quaternion.identity, 0.02f);
// DrawMesh("cursor", "default", mono.leftGrabber.cursor, Quaternion.identity, 0.02f);
// DrawMesh("cursor", "default", mono.rightGrabber.cursor, Quaternion.identity, 0.02f);
spectator.position = mono.rig.headset.position + mono.rig.headset.rotation * Vector3.back * 0.666f;
spectator.rotation = mono.rig.headset.rotation;
}
Matrix4x4 m4 = new Matrix4x4();
void DrawMesh(string mesh, string mat, Vector3 pos, Quaternion rot, float scale)
{
m4.SetTRS(pos, rot, Vector3.one * scale);
Graphics.DrawMesh(Mesh(mesh), m4, Mat(mat), 0);
}
public Material Mat(string name)
{
for (int i = 0; i < materials.Length; i++)
{
if (name.ToLower() == materials[i].name.ToLower())
{
return materials[i];
}
}
Debug.LogWarning("Material not found: " + name);
return null;
}
public Mesh Mesh(string name)
{
for (int i = 0; i < meshes.Length; i++)
{
if (meshes[i].name.ToLower() == name.ToLower())
{
return meshes[i];
}
}
Debug.LogWarning("Mesh not found: " + name);
return null;
}
}
[Serializable]
public class Noise
{
const uint CAP = 4294967295;
const uint BIT_NOISE1 = 0xB5297A4D;
const uint BIT_NOISE2 = 0x68E31DA4;
const uint BIT_NOISE3 = 0x1B56C4E9;
public uint seed;
public Noise(uint seed)
{
this.seed = seed;
}
int position;
public float value
{
get
{
float v = RNG(position, seed) / (float)CAP;
position++;
return v;
}
}
public float D1(int position)
{
return RNG(position, seed) / (float)CAP;
}
public float D2(int x, int y)
{
// large prime number with non-boring bits
const int PRIME = 198491317;
return RNG(x + (PRIME * y), seed) / (float)CAP;
}
public float D3(int x, int y, int z)
{
// large prime number with non-boring bits
const int PRIME1 = 198491317;
const int PRIME2 = 6542989;
return RNG(x + (PRIME1 * y) + (PRIME2 * z), seed) / (float)CAP;
}
public uint RNG(int position, uint seed)
{
uint mangled = (uint)position;
mangled *= BIT_NOISE1;
mangled += seed;
mangled ^= mangled >> 8;
mangled += BIT_NOISE2;
mangled ^= mangled << 8;
mangled *= BIT_NOISE3;
mangled ^= mangled >> 8;
return mangled;
}
}