using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Collections.Generic; using ProceduralToolkit; using System.IO; public class Remote_Paint_Controller : MonoBehaviour { StreamWriter sWrite; public float minPaintLen = 0.01f; public class CursorTran { public Vector3 pos; public Transform normProjTrans; public Transform screenProjTrans; public bool bValid = false; }; private CursorTran _cursorTran; public CursorTran cursorTran { get { return _cursorTran; } } public Text SlideVal; public GameObject retSphere; //PreFabs for Types of Mesh Instancing public PaintElement paintElement; public PaintElement LLQuadElement; public PaintElement HexElement; public SpawnElement spawnElement; //public UserMovement userMovement; public GameObject argos_SphereGO; public ArgosSphere_Indexing argos_Sphere; GameObject netCam; public bool isCursorValid() { return _cursorTran.bValid; } private bool bPaintOn = false; private int iStartPaint = 0; private bool bLLQuadOn = false; private bool bHexOn = false; //spawn on not needed - instanced private int nDrawnLLQuadIdx = -1; private int nDrawnHexQuadIdx = -1; List<PaintElement> paintList = new List<PaintElement>(); List<PaintElement> LLQuadList = new List<PaintElement>(); List<PaintElement> HexQuadList = new List<PaintElement>(); List<SpawnElement> SpawnList = new List<SpawnElement>(); int currPE_Idx = -1; int currQE_Idx = -1; int currHE_Idx = -1; int currSpn_Idx = -1; Vector3 vLastLoc; Vector3 vCurrLoc; Vector3 v1curr; Vector3 v2curr; Vector3 v1last; Vector3 v2last; float lineWidth = 0.025f; Quaternion myPaintRotation; Quaternion myQuadRotation; Quaternion myHexRotation; MeshDraft mdScratch; //Watch out for stepping on template Hex Quads // Use this for initialization void Start() { retSphere = GameObject.Find("RetSphere"); argos_SphereGO = GameObject.Find("Argos_Sphere"); argos_Sphere = argos_SphereGO.GetComponent<ArgosSphere_Indexing>(); netCam = GameObject.Find("ArgosNet_Remote"); mdScratch = new MeshDraft(); _cursorTran = new CursorTran(); //sWrite = new StreamWriter("Argos_Cursor_Paint.txt"); } private bool IsRayIntersecting(Transform mPose) { //Let s be the start point of the ray, and d a unit vector in the direction of the ray. //Let c be the center point of the sphere, and r its radius. Vector3 s = mPose.transform.position; Vector3 d = mPose.transform.forward; Vector3 c = argos_Sphere.transform.position; float r = argos_Sphere.GetComponent<ArgosSphere_Indexing>().radius; // Calculate ray's start offset from the sphere center Vector3 p = s - c; float rSquared = r * r; float p_d = Vector3.Dot(p, d); // The sphere is behind or surrounding the start point. //if (p_d < 0 || Vector3.Dot(p, p) < rSquared) // return false; // Flatten p into the plane passing through c perpendicular to the ray. // This gives the closest approach of the ray to the center. Vector3 a = p - p_d * d; float aSquared = Vector3.Dot(a, a); // Closest approach is outside the sphere. if (aSquared > rSquared) return false; return true; } void OnApplicationQuit() { //sWrite.Close(); } public void OnSliderChanged() { //lineWidth = widthSlide.value; //SlideVal.text = lineWidth.ToString("F2"); } public void onPaintTogSwitched(bool isOn) { Debug.Log("Remote Paint Switched"); bPaintOn = isOn; if (isOn) { OnPaintButtonDown(); } else { OnPaintButtonUp(); } } public void onQuadTogSwitched(bool isOn) { Debug.Log("Remote Quad Switched"); if (isOn) { OnLLQuadButtonDown(); } else { OnLLQuadButtonUp(); } } public void onHexTogSwitched(bool isOn) { Debug.Log("Remote Hex Switched"); if (isOn) { OnHexButtonDown(); } else { OnHexButtonUp(); } } public void OnPaintButtonDown() { bPaintOn = true; if (isCursorValid()) { bPaintOn = true; iStartPaint = 0; //txtButtonState.text = "Paint On"; currPE_Idx++; //txtNumPaintElements.text = currPE_Idx.ToString(); paintList.Add(Instantiate(paintElement)); paintList[currPE_Idx].transform.SetParent(argos_Sphere.transform); paintList[currPE_Idx].transform.localPosition = Vector3.zero; Quaternion LocalRotation = Quaternion.Inverse(argos_Sphere.transform.rotation); vLastLoc = cursorTran.pos - argos_Sphere.transform.position; Vector3 vRotated = LocalRotation * vLastLoc; vLastLoc = vRotated; //sWrite.WriteLine("-------------------------"); myPaintRotation = argos_Sphere.transform.rotation; } } public void OnPaintButtonUp() { bPaintOn = false; //txtButtonState.text = "Paint Off"; } public void OnLLQuadButtonDown() { if (isCursorValid()) { bLLQuadOn = true; //txtButtonState.text = "LLQuad On"; currQE_Idx++; //txtNumLLQuadElements.text = currQE_Idx.ToString(); PaintElement rectLLQuads = Instantiate(LLQuadElement); rectLLQuads.transform.SetParent(argos_Sphere.transform); rectLLQuads.transform.localPosition = Vector3.zero; LLQuadList.Add(rectLLQuads); Quaternion LocalRotation = Quaternion.Inverse(argos_Sphere.transform.rotation); vLastLoc = cursorTran.pos - argos_Sphere.transform.position; Vector3 vRotated = LocalRotation * vLastLoc; vLastLoc = vRotated; myQuadRotation = argos_Sphere.transform.rotation; } } public void OnLLQuadButtonUp() { bLLQuadOn = false; //txtButtonState.text = "LLQuad Off"; } public void OnHexButtonDown() { if (isCursorValid()) { bHexOn = true; //txtButtonState.text = "Hexagonal On"; currHE_Idx++; //txtHexElements.text = currHE_Idx.ToString(); PaintElement HObj = Instantiate(HexElement); HObj.transform.SetParent(argos_Sphere.transform); HObj.transform.localPosition = Vector3.zero; HexQuadList.Add(HObj); Quaternion LocalRotation = Quaternion.Inverse(argos_Sphere.transform.rotation); vLastLoc = cursorTran.pos - argos_Sphere.transform.position; Vector3 vRotated = LocalRotation * vLastLoc; vLastLoc = vRotated; myHexRotation = argos_Sphere.transform.rotation; } } public void OnHexButtonUp() { bHexOn = false; //txtButtonState.text = "Hexagonal Off"; } public void onSpawnButtonDown() { if (isCursorValid()) { currSpn_Idx++; //txtNumSpawnElements.text = currSpn_Idx.ToString(); SpawnElement SObj = Instantiate(spawnElement); SObj.transform.SetParent(argos_Sphere.transform); SObj.transform.localPosition = Vector3.zero; SpawnList.Add(SObj); vCurrLoc = cursorTran.pos - argos_Sphere.transform.position; Quaternion LocalRotation = Quaternion.Inverse(argos_Sphere.transform.rotation); Vector3 vRotated = LocalRotation * vCurrLoc; int cSpnHexGridIdxStart = argos_Sphere.getHexIdx(vRotated); mdScratch.Copy_MeshDraft(argos_Sphere.HexQuads[cSpnHexGridIdxStart].mdH); Quaternion snapRotation; snapRotation = argos_Sphere.transform.rotation; mdScratch.Rotate(snapRotation); SpawnList[currSpn_Idx].AddMeshDraft(mdScratch, cSpnHexGridIdxStart, currSpn_Idx % 6, snapRotation); //txtButtonState.text = "Spawned at Reticle"; } } public void MoveScreenIndicator(Vector3 pos, Transform mPose, Vector3 vR) { retSphere.transform.position = pos; //vPaddleVel = (pos - vPaddlePos_Last)/Time.deltaTime; //vPaddlePos_Last = pos; Quaternion rotation = Quaternion.LookRotation(vR.normalized, mPose.up); retSphere.transform.rotation = rotation; _cursorTran.screenProjTrans = retSphere.transform; } public void OnPoseUpdated(Transform mPose) { _cursorTran.bValid = IsRayIntersecting(mPose); if (_cursorTran.bValid) { float R = 1.5f;/*ArgosSphere.m_GridScale*/; Vector3 vPC = argos_Sphere.transform.position - mPose.position; Vector3 vBpos = mPose.position + Vector3.Dot(vPC, mPose.forward) * mPose.forward; Vector3 vBC = vBpos - argos_Sphere.transform.position; float BClen = vBC.magnitude; float BDlen = Mathf.Sqrt(R * R - BClen * BClen); Vector3 D = vBpos + mPose.forward * BDlen; //d_Position.text = D.ToString(); retSphere.transform.position = D; _cursorTran.pos = D; Vector3 vR = D - argos_Sphere.transform.position; Quaternion rotation = Quaternion.LookRotation(vR.normalized, Vector3.up); retSphere.transform.rotation = rotation; _cursorTran.normProjTrans = retSphere.transform; MoveScreenIndicator(D, mPose, vR); } //MoveBall(); } // Update is called once per frame void Update() { if (netCam != null) { OnPoseUpdated(netCam.transform); if (isCursorValid()) { Vector3 v = cursorTran.pos - argos_Sphere.transform.position; int H = argos_Sphere.getHexIdx(v); if (currSpn_Idx > -1) { foreach (SpawnElement s in SpawnList) { s.update_from_PaintCtrl(v, H); } } if (bPaintOn) { vCurrLoc = cursorTran.pos - argos_Sphere.transform.position; Quaternion LocalRotation = myPaintRotation * Quaternion.Inverse(argos_Sphere.transform.rotation); vCurrLoc = LocalRotation * vCurrLoc; if (vCurrLoc != vLastLoc) { Vector3 len = vCurrLoc - vLastLoc; if (len.magnitude > minPaintLen || iStartPaint < 2) { Vector3 vFwd = cursorTran.screenProjTrans.forward; Vector3 vFwdRtd = LocalRotation * vFwd; Vector3 vUp = Vector3.Cross(vFwdRtd, len); vUp.Normalize(); v1curr = vCurrLoc + (lineWidth / 2f) * vUp; v2curr = vCurrLoc - (lineWidth / 2f) * vUp; //sWrite.WriteLine("len =" + v2last.ToString("F3") + " vFwdRtd =" + vFwdRtd.ToString("F3") + " vUp =" + vUp.ToString("F3") + " vLastLoc =" + vLastLoc.ToString("F3") + " vCurrLoc =" + vCurrLoc.ToString("F3")); if (++iStartPaint > 2) //don't write 2 times though { paintList[currPE_Idx].AddQuad(v2last, v1last, v1curr, v2curr); //sWrite.WriteLine("v0 =" + v2last.ToString("F3") + "v1 =" + v1last.ToString("F3") + "v2 =" + v1curr.ToString("F3") + "v3 =" + v2curr.ToString("F3")); } vLastLoc = vCurrLoc; v1last = v1curr; v2last = v2curr; //if (currPE_Idx > -1 && paintList[currPE_Idx].Mdraft != null) // InfoLineTxt.text = " Pn = " + (paintList[currPE_Idx].Mdraft.triangles.Count / 2).ToString(); } } } if (bLLQuadOn) { vCurrLoc = cursorTran.pos - argos_Sphere.transform.position; Quaternion LocalRotation = Quaternion.Inverse(argos_Sphere.transform.rotation); vCurrLoc = LocalRotation * vCurrLoc; if (vCurrLoc != vLastLoc) { int currLatLong_Idx = argos_Sphere.getLLQuadIdx(vCurrLoc); if (currLatLong_Idx != nDrawnLLQuadIdx) { mdScratch.Copy_MeshDraft(argos_Sphere.LLQuads[currLatLong_Idx].mdQuad); mdScratch.Rotate(myQuadRotation); LLQuadList[currQE_Idx].AddMeshDraft(mdScratch); nDrawnLLQuadIdx = currLatLong_Idx; } } vLastLoc = vCurrLoc; //if (currQE_Idx > -1 && LLQuadList[currQE_Idx].Mdraft != null) // InfoLineTxt.text = " Qn = " + (LLQuadList[currQE_Idx].Mdraft.triangles.Count / 2).ToString(); } if (bHexOn) { vCurrLoc = cursorTran.pos - argos_Sphere.transform.position; Quaternion LocalRotation = Quaternion.Inverse(argos_Sphere.transform.rotation); vCurrLoc = LocalRotation * vCurrLoc; if (vCurrLoc != vLastLoc) { int cHIdx = argos_Sphere.getHexIdx(vCurrLoc); if (cHIdx != nDrawnHexQuadIdx) { mdScratch.Copy_MeshDraft(argos_Sphere.HexQuads[cHIdx].mdH); mdScratch.Rotate(myHexRotation); HexQuadList[currHE_Idx].AddMeshDraft(mdScratch); nDrawnHexQuadIdx = cHIdx; //if (currHE_Idx > -1 && HexQuadList[currHE_Idx].Mdraft != null) // InfoLineTxt.text = " Hn = " + (HexQuadList[currHE_Idx].Mdraft.triangles.Count / 2).ToString(); } vLastLoc = vCurrLoc; } } } } } }