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().mesh; // set vertex colors to green List colors = new List(); 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 verts = new List(); 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(); 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(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(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(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 connections = new List(); [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 punchList = new List(); [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(); } 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 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(); // 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 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(); // 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("Materials/"); meshes = Resources.LoadAll("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; } }