6 using System.Collections.Generic;
9 #if !UNITY_EDITOR && UNITY_WSA 11 using System.Threading.Tasks;
21 [Tooltip(
"Currently active planes found within the Spatial Mapping Mesh.")]
24 [Tooltip(
"Object used for creating and rendering Surface Planes.")]
27 [Tooltip(
"Minimum area required for a plane to be created.")]
28 public float MinArea = 0.025f;
48 public float FloorYPosition {
get;
private set; }
54 public float CeilingYPosition {
get;
private set; }
61 public delegate
void EventHandler(
object source, EventArgs args);
71 private GameObject planesParent;
76 private float snapToGravityThreshold = 5.0f;
81 private bool makingPlanes =
false;
83 #if UNITY_EDITOR || UNITY_STANDALONE 84 private static readonly
float FrameTime = .016f;
89 private static readonly
float FrameTime = .008f;
99 ActivePlanes =
new List<GameObject>();
100 planesParent =
new GameObject(
"SurfacePlanes");
101 planesParent.transform.position = Vector3.zero;
102 planesParent.transform.rotation = Quaternion.identity;
115 StartCoroutine(MakePlanesRoutine());
126 List<GameObject> typePlanes =
new List<GameObject>();
128 foreach (GameObject plane
in ActivePlanes)
132 if (surfacePlane != null)
136 typePlanes.Add(plane);
148 private IEnumerator MakePlanesRoutine()
151 for (
int index = 0; index < ActivePlanes.Count; index++)
153 Destroy(ActivePlanes[index]);
158 float start = Time.realtimeSinceStartup;
160 ActivePlanes.Clear();
166 for (
int index = 0; index < filters.Count; index++)
168 MeshFilter filter = filters[index];
169 if (filter != null && filter.sharedMesh != null)
172 filter.mesh.RecalculateNormals();
176 if ((Time.realtimeSinceStartup - start) > FrameTime)
180 start = Time.realtimeSinceStartup;
187 #if !UNITY_EDITOR && UNITY_WSA 189 Task<BoundedPlane[]> planeTask = Task.Run(() =>
PlaneFinding.
FindPlanes(meshData, snapToGravityThreshold, MinArea));
191 while (planeTask.IsCompleted ==
false)
204 start = Time.realtimeSinceStartup;
206 float maxFloorArea = 0.0f;
207 float maxCeilingArea = 0.0f;
208 FloorYPosition = 0.0f;
209 CeilingYPosition = 0.0f;
210 float upNormalThreshold = 0.9f;
212 if (SurfacePlanePrefab != null && SurfacePlanePrefab.GetComponent<
SurfacePlane>() != null)
214 upNormalThreshold = SurfacePlanePrefab.GetComponent<
SurfacePlane>().UpNormalThreshold;
220 for (
int i = 0; i < planes.Length; i++)
223 if (boundedPlane.
Bounds.
Center.y < 0 && boundedPlane.
Plane.normal.y >= upNormalThreshold)
225 maxFloorArea = Mathf.Max(maxFloorArea, boundedPlane.
Area);
226 if (maxFloorArea == boundedPlane.
Area)
231 else if (boundedPlane.
Bounds.
Center.y > 0 && boundedPlane.
Plane.normal.y <= -(upNormalThreshold))
233 maxCeilingArea = Mathf.Max(maxCeilingArea, boundedPlane.
Area);
234 if (maxCeilingArea == boundedPlane.
Area)
242 for (
int index = 0; index < planes.Length; index++)
244 GameObject destinationPlane;
248 if (SurfacePlanePrefab != null && SurfacePlanePrefab.GetComponent<
SurfacePlane>() != null)
250 destinationPlane = Instantiate(SurfacePlanePrefab);
254 destinationPlane = GameObject.CreatePrimitive(PrimitiveType.Cube);
256 destinationPlane.GetComponent<Renderer>().shadowCastingMode =
UnityEngine.Rendering.ShadowCastingMode.Off;
259 destinationPlane.transform.parent = planesParent.transform;
260 var surfacePlane = destinationPlane.GetComponent<
SurfacePlane>();
263 surfacePlane.
Plane = boundedPlane;
265 SetPlaneVisibility(surfacePlane);
267 if ((destroyPlanesMask & surfacePlane.PlaneType) == surfacePlane.PlaneType)
269 DestroyImmediate(destinationPlane);
275 ActivePlanes.Add(destinationPlane);
279 if ((Time.realtimeSinceStartup - start) > FrameTime)
283 start = Time.realtimeSinceStartup;
287 Debug.Log(
"Finished making planes.");
290 EventHandler handler = MakePlanesComplete;
293 handler(
this, EventArgs.Empty);
296 makingPlanes =
false;
303 private void SetPlaneVisibility(
SurfacePlane surfacePlane)