123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 |
-
- using UnityEngine;
- using System.Collections.Generic;
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
- [DisallowMultipleComponent]
- public class ZEDPlaneDetectionManager : MonoBehaviour
- {
-
-
-
- private GameObject holder;
-
-
-
-
- private bool hasDetectedFloor = false;
-
-
-
- public bool HasDetectedFloor
- {
- get { return hasDetectedFloor; }
- }
-
-
-
- private GameObject floorPlaneGO;
-
-
-
-
- private ZEDPlaneGameObject floorPlane = null;
-
-
-
- public ZEDPlaneGameObject getFloorPlane
- {
- get { return floorPlane; }
- }
-
-
-
-
- private int planeHitCount = 0;
-
-
-
- public List<ZEDPlaneGameObject> hitPlaneList = null;
-
-
-
- private Vector3[] planeMeshVertices;
-
-
-
- private int[] planeMeshTriangles;
-
-
-
- public static bool isSceneDisplay = true;
-
-
-
-
- public static bool isGameDisplay = false;
-
-
-
-
- public bool planesHavePhysics
- {
- get
- {
- return addPhysicsOption;
- }
- set
- {
- if (addPhysicsOption != value)
- {
- willUpdatePhysics = true;
- addPhysicsOption = value;
- }
- }
- }
-
-
-
-
- [SerializeField]
- private bool addPhysicsOption = true;
-
-
-
-
- private bool willUpdatePhysics = false;
-
-
-
-
- public bool planesVisibleInScene
- {
- get
- {
- return isVisibleInSceneOption;
- }
- set
- {
- if (value != isVisibleInSceneOption)
- {
- isVisibleInSceneOption = value;
- willUpdateSceneVisibility = true;
- }
- }
- }
-
-
-
-
- [SerializeField]
- private bool isVisibleInSceneOption = true;
-
-
-
-
- private bool willUpdateSceneVisibility = true;
-
-
-
- public bool planesVisibleInGame
- {
- get
- {
- return isVisibleInGameOption;
- }
- set
- {
- if (value != isVisibleInGameOption)
- {
- isVisibleInGameOption = value;
- willUpdateGameVisibility = true;
- }
- }
- }
-
-
-
-
- [SerializeField]
- private bool isVisibleInGameOption = true;
-
-
-
-
- private bool willUpdateGameVisibility = true;
-
-
-
-
- public Material overrideMaterial = null;
-
-
-
- private float estimatedPlayerHeight = 0.0f;
-
-
-
- public float GetEstimatedPlayerHeight
- {
- get { return estimatedPlayerHeight; }
- }
-
-
-
- private void Start()
- {
-
- holder = new GameObject();
- holder.name = "[ZED Planes]";
- holder.transform.parent = this.transform;
- holder.transform.position = Vector3.zero;
- holder.transform.rotation = Quaternion.identity;
- StaticBatchingUtility.Combine(holder);
-
- planeMeshVertices = new Vector3[65000];
- planeMeshTriangles = new int[65000];
-
- hitPlaneList = new List<ZEDPlaneGameObject>();
- }
- public void OnDisable()
- {
- foreach (Transform child in holder.transform)
- {
- Destroy(child.gameObject);
- Destroy(holder);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
- private void TransformCameraToLocalMesh(Transform camera, Vector3[] srcVertices, int[] srcTriangles, Vector3[] dstVertices, int[] dstTriangles, int numVertices, int numTriangles, Vector3 centerpos)
- {
- if (numVertices == 0 || numTriangles == 0)
- return;
- System.Array.Copy(srcVertices, dstVertices, numVertices);
- System.Buffer.BlockCopy(srcTriangles, 0, dstTriangles, 0, numTriangles * sizeof(int));
- for (int i = 0; i < numVertices; i++)
- {
- dstVertices[i] -= centerpos;
- dstVertices[i] = camera.transform.rotation * dstVertices[i];
- }
- }
-
-
-
-
-
-
- public bool DetectFloorPlane(bool auto)
- {
-
- List<ZEDManager> managers = ZEDManager.GetInstances();
- if (managers.Count == 0) return false;
- else return DetectFloorPlane(managers[0], auto);
- }
-
-
-
-
-
-
-
- public bool DetectFloorPlane(ZEDManager manager, bool auto)
- {
- if (!manager.IsZEDReady)
- return false;
- sl.ZEDCamera zedcam = manager.zedCamera;
- Camera cam = manager.GetMainCamera();
- ZEDPlaneGameObject.PlaneData plane = new ZEDPlaneGameObject.PlaneData();
- if (zedcam.findFloorPlane(ref plane, out estimatedPlayerHeight, Quaternion.identity, Vector3.zero) == sl.ERROR_CODE.SUCCESS)
- {
- int numVertices, numTriangles = 0;
- zedcam.convertFloorPlaneToMesh(planeMeshVertices, planeMeshTriangles, out numVertices, out numTriangles);
- if (numVertices > 0 && numTriangles > 0)
- {
- Vector3[] worldPlaneVertices = new Vector3[numVertices];
- int[] worldPlaneTriangles = new int[numTriangles];
- TransformCameraToLocalMesh(cam.transform, planeMeshVertices, planeMeshTriangles, worldPlaneVertices, worldPlaneTriangles, numVertices, numTriangles, plane.PlaneCenter);
- hasDetectedFloor = true;
- if (!floorPlaneGO)
- {
- floorPlaneGO = new GameObject("Floor Plane");
- floorPlaneGO.transform.SetParent(holder.transform);
- }
- if (!floorPlaneGO)
- {
- floorPlaneGO = new GameObject("Floor Plane");
- floorPlaneGO.transform.SetParent(holder.transform);
- }
-
- floorPlaneGO.transform.position = cam.transform.position;
- floorPlaneGO.transform.position += cam.transform.rotation * plane.PlaneCenter;
- if (!floorPlane)
- {
- floorPlane = floorPlaneGO.AddComponent<ZEDPlaneGameObject>();
- }
- if (!floorPlane.IsCreated)
- {
- if (overrideMaterial != null) floorPlane.Create(cam, plane, worldPlaneVertices, worldPlaneTriangles, 0, overrideMaterial);
- else floorPlane.Create(cam, plane, worldPlaneVertices, worldPlaneTriangles, 0);
- floorPlane.SetPhysics(addPhysicsOption);
- }
- else
- {
- floorPlane.UpdateFloorPlane(!auto, plane, worldPlaneVertices, worldPlaneTriangles, overrideMaterial);
- floorPlane.SetPhysics(addPhysicsOption);
- }
- return true;
- }
- }
- return false;
- }
-
-
-
-
-
-
- public bool DetectPlaneAtHit(Vector2 screenPos)
- {
-
- List<ZEDManager> managers = ZEDManager.GetInstances();
- if (managers.Count == 0) return false;
- else if (managers.Count > 1)
- {
- Debug.LogWarning("Using DetectPlaneAtHit without specifying a manager while multiple ZEDManagers are present. " +
- "This can cause planes to be calculated by the wrong camera. It's recommended to use the (ZEDManager, Vector2) overload.");
- }
- return DetectPlaneAtHit(managers[0], screenPos);
- }
-
-
-
-
-
- public bool DetectPlaneAtHit(ZEDManager manager, Vector2 screenPos)
- {
- if (!manager.IsZEDReady)
- return false;
- sl.ZEDCamera zedcam = manager.zedCamera;
- Camera cam = manager.GetMainCamera();
- ZEDPlaneGameObject.PlaneData plane = new ZEDPlaneGameObject.PlaneData();
- if (zedcam.findPlaneAtHit(ref plane, screenPos) == sl.ERROR_CODE.SUCCESS)
- {
- int numVertices, numTriangles = 0;
- zedcam.convertHitPlaneToMesh(planeMeshVertices, planeMeshTriangles, out numVertices, out numTriangles);
- if (numVertices > 0 && numTriangles > 0)
- {
- GameObject newhitGO = new GameObject();
- newhitGO.transform.SetParent(holder.transform);
- Vector3[] worldPlaneVertices = new Vector3[numVertices];
- int[] worldPlaneTriangles = new int[numTriangles];
- TransformCameraToLocalMesh(cam.transform, planeMeshVertices, planeMeshTriangles, worldPlaneVertices, worldPlaneTriangles, numVertices, numTriangles, plane.PlaneCenter);
-
- newhitGO.transform.position = cam.transform.position;
- newhitGO.transform.position += cam.transform.rotation * plane.PlaneCenter;
- ZEDPlaneGameObject hitPlane = newhitGO.AddComponent<ZEDPlaneGameObject>();
- if (overrideMaterial != null) hitPlane.Create(cam, plane, worldPlaneVertices, worldPlaneTriangles, planeHitCount + 1, overrideMaterial);
- else hitPlane.Create(cam, plane, worldPlaneVertices, worldPlaneTriangles, planeHitCount + 1);
- hitPlane.SetPhysics(addPhysicsOption);
-
- hitPlaneList.Add(hitPlane);
- planeHitCount++;
- return true;
- }
- }
- return false;
- }
-
-
-
- void Update()
- {
-
- if (Input.GetMouseButtonDown(0))
- {
- Vector2 ScreenPosition = Input.mousePosition;
- List<ZEDManager> managers = ZEDManager.GetInstances();
- if (managers.Count == 1)
- DetectPlaneAtHit(managers[0], ScreenPosition);
- else if (managers.Count > 1)
- {
-
- float highestdepth = Mathf.NegativeInfinity;
- ZEDManager highestmanager = managers[0];
- foreach (ZEDManager manager in managers)
- {
- float depth = manager.GetMainCamera().depth;
- if (depth >= highestdepth)
- {
- highestdepth = depth;
- highestmanager = manager;
- }
- }
- DetectPlaneAtHit(highestmanager, ScreenPosition);
- }
- }
-
- if (willUpdatePhysics)
- {
- if (floorPlane != null && floorPlane.IsCreated)
- {
- floorPlane.SetPhysics(addPhysicsOption);
- }
- if (hitPlaneList != null)
- {
- foreach (ZEDPlaneGameObject c in hitPlaneList)
- {
- if (c.IsCreated)
- c.SetPhysics(addPhysicsOption);
- }
- }
- willUpdatePhysics = false;
- }
-
- if (willUpdateSceneVisibility)
- {
-
- SwitchSceneDisplay();
- willUpdateSceneVisibility = false;
- }
-
- if (willUpdateGameVisibility)
- {
- SwitchGameDisplay();
- willUpdateGameVisibility = false;
- }
- }
-
-
-
- public void SwitchSceneDisplay()
- {
- isSceneDisplay = isVisibleInSceneOption;
- }
-
-
-
- public void SwitchGameDisplay()
- {
- isGameDisplay = isVisibleInGameOption;
- }
- #if UNITY_EDITOR
-
-
-
- void OnValidate()
- {
- if (floorPlane != null && floorPlane.IsCreated)
- {
- floorPlane.SetPhysics(addPhysicsOption);
-
- }
- if (hitPlaneList != null)
- foreach (ZEDPlaneGameObject c in hitPlaneList)
- {
- if (c.IsCreated)
- c.SetPhysics(addPhysicsOption);
-
- }
- SwitchSceneDisplay();
- SwitchGameDisplay();
- }
- #endif
- }
- #if UNITY_EDITOR
- [CustomEditor(typeof(ZEDPlaneDetectionManager))]
- public class ZEDPlaneDetectionEditor : Editor
- {
-
-
-
- private ZEDPlaneDetectionManager planeDetector;
-
-
-
-
- private SerializedProperty addPhysicsOption;
-
-
-
- private SerializedProperty isVisibleInSceneOption;
-
-
-
- private SerializedProperty isVisibleInGameOption;
-
-
-
- private SerializedProperty overrideMaterialOption;
- private ZEDPlaneDetectionManager Target
- {
- get { return (ZEDPlaneDetectionManager)target; }
- }
- public void OnEnable()
- {
-
- planeDetector = (ZEDPlaneDetectionManager)target;
- addPhysicsOption = serializedObject.FindProperty("addPhysicsOption");
- isVisibleInSceneOption = serializedObject.FindProperty("isVisibleInSceneOption");
- isVisibleInGameOption = serializedObject.FindProperty("isVisibleInGameOption");
- overrideMaterialOption = serializedObject.FindProperty("overrideMaterial");
- }
- public override void OnInspectorGUI()
- {
-
- serializedObject.Update();
- GUILayout.Space(20);
- EditorGUILayout.BeginHorizontal();
- GUILayout.Label("Detection Parameters", EditorStyles.boldLabel);
- GUILayout.FlexibleSpace();
- EditorGUILayout.EndHorizontal();
-
- EditorGUILayout.BeginHorizontal();
- GUIContent floordetectionlabel = new GUIContent("Single-shot Floor Detection", "Attempt to detect a floor plane in the current view.");
- GUILayout.Label(floordetectionlabel); GUILayout.Space(20);
- GUIContent floordetectbuttonlabel = new GUIContent("Detect", "Attempt to detect a floor plane in the current view.");
- if (GUILayout.Button(floordetectbuttonlabel))
- {
- planeDetector.DetectFloorPlane(false);
- }
- GUILayout.FlexibleSpace();
- EditorGUILayout.EndHorizontal();
- GUI.enabled = true;
- GUILayout.Space(20);
- EditorGUILayout.BeginHorizontal();
- GUILayout.Label("Visualization", EditorStyles.boldLabel);
- GUILayout.FlexibleSpace();
- EditorGUILayout.EndHorizontal();
- GUIContent visiblescenelabel = new GUIContent("Visible in Scene", "Whether the planes are drawn in Unity's Scene view.");
- GUIContent visiblegamelabel = new GUIContent("Visible in Game", "Whether the planes are drawn in Unity's Game view.");
- isVisibleInSceneOption.boolValue = EditorGUILayout.Toggle(visiblescenelabel, isVisibleInSceneOption.boolValue);
- #if !UNITY_2018_1_OR_NEWER
- if (!isVisibleInSceneOption.boolValue)
- {
-
- GUIStyle warningmessagestyle = new GUIStyle(EditorStyles.label);
- warningmessagestyle.normal.textColor = Color.gray;
- warningmessagestyle.wordWrap = true;
- warningmessagestyle.fontSize = 9;
- string warningtext = "Warning: Disabling Visible in Scene causes Unity versions 2017 and lower to spam error messages. This is due to a Unity bug and does not effect the scene.";
- Rect labelrect = GUILayoutUtility.GetRect(new GUIContent(warningtext, ""), warningmessagestyle);
- EditorGUI.LabelField(labelrect, warningtext, warningmessagestyle);
- }
- #endif
- isVisibleInGameOption.boolValue = EditorGUILayout.Toggle(visiblegamelabel, isVisibleInGameOption.boolValue);
- GUIContent overridematlabel = new GUIContent("Override Material: ", "Material applied to all planes if visible. If left empty, default materials will be applied depending on the plane type.");
- planeDetector.overrideMaterial = (Material)EditorGUILayout.ObjectField(overridematlabel, planeDetector.overrideMaterial, typeof(Material), false);
- planeDetector.SwitchGameDisplay();
- GUILayout.Space(20);
- GUI.enabled = true;
- EditorGUILayout.BeginHorizontal();
- GUILayout.Label("Physics", EditorStyles.boldLabel);
- GUILayout.FlexibleSpace();
- EditorGUILayout.EndHorizontal();
- GUIContent physicslabel = new GUIContent("Collisions", "Whether the planes can be collided with using physics.");
- addPhysicsOption.boolValue = EditorGUILayout.Toggle(physicslabel, addPhysicsOption.boolValue);
- serializedObject.ApplyModifiedProperties();
-
- Repaint();
- }
- }
- #endif
|