using System; using UnityEngine; [Serializable] public class Input { public OculusInject oculusInject; // have to use a transform for the head (and put it in a rig :/) public Transform rig, head; // two controllers (chiral) public bool leftHanded; // tells the input injector the handedness public Con mainCon, offCon; [HideInInspector] public Vector3 twistCursor; [HideInInspector] public Vector3 stretchCursor; [HideInInspector] public Vector3 dragCursor; Vector3 mainCalibDir; Quaternion mainCalibRot; float calibDist, calibZ; public void Frame() { oculusInject.Frame(this); rig.position = -head.localPosition; // that zeros us out for an offset rig.position += head.localRotation * Vector3.back * 0.666f; // Calibrate/Recenter if (offCon.one.held) // temporary mapping { mainCalibDir = Vector3.zero - WorldPos(mainCon).normalized; mainCalibRot = mainCon.physical.Rot(); calibDist = Vector3.Distance(Vector3.zero, WorldPos(mainCon)); calibZ = Vector3.Angle( offCon.physical.Rot() * Vector3.up, WorldPos(mainCon) - WorldPos(offCon) ) / 90f; } float zValue = Vector3.Angle( offCon.physical.Rot() * Vector3.up, WorldPos(mainCon) - WorldPos(offCon) ) / 90f; // 0in - 1neutral - 2out zValue = 1 + zValue - calibZ; Quaternion rot = mainCon.physical.Rot() * Quaternion.Inverse(mainCalibRot); twistCursor = WorldPos(mainCon) + rot * mainCalibDir * calibDist * zValue; if (mainCon.grip.held) { dragCursor += mainCon.physical.PosVel() * 3 * Time.deltaTime; // clamp // oriel class ! // new Vector3(0.6f, 0.4f, 0.4f); dragCursor.x = Mathf.Clamp(dragCursor.x, -0.3f, 0.3f); dragCursor.y = Mathf.Clamp(dragCursor.y, -0.2f, 0.2f); dragCursor.z = Mathf.Clamp(dragCursor.z, -0.2f, 0.2f); } float stretch = Vector3.Distance(WorldPos(mainCon), WorldPos(offCon)); stretchCursor = WorldPos(mainCon) + mainCon.physical.Rot() * Vector3.forward * stretch * 3; // Some way to switch between // based on implementation (where switching needs to occur) } public Vector3 WorldPos(Con con) { return rig.TransformPoint(con.physical.Pos()); } } [Serializable] public class Con { public Physical physical; public Btn trigger, grip, one, two; [Serializable] public class Btn { public bool down, held, up; } } [Serializable] public class Physical { Vector3 pos, posVel; Quaternion rot, rotVel; public Vector3 Pos() { return pos; } public Vector3 PosVel() { return posVel; } public Quaternion Rot() { return rot; } public Quaternion RotVel() { return rotVel; } float lastSet = 0; public void Set(Vector3 pos, Quaternion rot, float delta) { // Vel time since last set? and throw away anything = 0 or greater then x float setDelta = Time.time - lastSet; if (setDelta == 0 || setDelta > 1) { this.posVel = Vector3.zero; this.rotVel = Quaternion.identity; } else { this.posVel = (pos - this.pos) / delta; this.rotVel = Quaternion.SlerpUnclamped(Quaternion.identity, rot * Quaternion.Inverse(this.rot), 1 / delta); } this.pos = pos; this.rot = rot; lastSet = Time.time; } } [Serializable] public class OculusInject { float lastTime, delta; public void Frame(Input input) { delta = Time.time - lastTime; Controller(input.offCon, input.leftHanded ? OVRInput.Controller.RTouch : OVRInput.Controller.LTouch); Controller(input.mainCon, input.leftHanded ? OVRInput.Controller.LTouch : OVRInput.Controller.RTouch); lastTime = Time.time; } void Controller(Con con, OVRInput.Controller touchCon) { con.physical.Set( OVRInput.GetLocalControllerPosition(touchCon), OVRInput.GetLocalControllerRotation(touchCon), delta ); con.trigger.down = con.trigger.up = false; if (OVRInput.Get(OVRInput.Button.PrimaryIndexTrigger, touchCon)) { if (!con.trigger.held) { con.trigger.down = true; } con.trigger.held = true; } else { if (con.trigger.held) { con.trigger.up = true; } con.trigger.held = false; } con.grip.down = con.grip.up = false; if (OVRInput.Get(OVRInput.Button.PrimaryHandTrigger, touchCon)) { if (!con.grip.held) { con.grip.down = true; } con.grip.held = true; } else { if (con.grip.held) { con.grip.up = true; } con.grip.held = false; } con.one.down = con.one.up = false; if (OVRInput.Get(OVRInput.Button.One, touchCon)) { if (!con.one.held) { con.one.down = true; } con.one.held = true; } else { if (con.one.held) { con.one.up = true; } con.one.held = false; } con.two.down = con.two.up = false; if (OVRInput.Get(OVRInput.Button.Two, touchCon)) { if (!con.two.held) { con.two.down = true; } con.two.held = true; } else { if (con.two.held) { con.two.up = true; } con.two.held = false; } } }