Ejemplo n.º 1
0
        private static void TestSimplePlane(int dimension, Vector3 bounds, Matrix4x4 vertDataTransform, Matrix4x4 meshTransform)
        {
            List <PlaneFinding.MeshData> meshes = new List <PlaneFinding.MeshData>();

            meshes.Add(Util.CreateSimpleMesh(dimension, bounds, vertDataTransform, meshTransform));

            BoundedPlane[] planes = PlaneFinding.FindPlanes(meshes, 0.0f, 0.0f);
            Assert.AreEqual(1, planes.Length);
            AssertExpectedPlane(planes[0], bounds, vertDataTransform, meshTransform);
        }
Ejemplo n.º 2
0
        private void Update()
        {
            // Grab the necessary mesh data from the current set of surfaces that we want to run
            // PlaneFinding against.  This must be done on the main UI thread.
            meshData.Clear();
            foreach (MeshFilter mesh in GetComponentsInChildren <MeshFilter>())
            {
                meshData.Add(new PlaneFinding.MeshData(mesh));
            }

            // Now call FindPlanes().  NOTE: In a real application, this MUST be executed on a
            // background thread (i.e.: via ThreadPool.QueueUserWorkItem) so that it doesn't stall the
            // rendering thread while running plane finding.  Maintaining a solid 60fps is crucial
            // to a good user experience.
            planes = (VisualizeSubPlanes) ?
                     PlaneFinding.FindSubPlanes(meshData, SnapToGravityThreshold) :
                     PlaneFinding.FindPlanes(meshData, SnapToGravityThreshold, MinArea);
        }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            List <PlaneFinding.MeshData> meshes = new List <PlaneFinding.MeshData>();

            meshes.Add(Util.CreateSimpleMesh(10, new Vector3(5, 5, 0)));

            BoundedPlane[] planes = PlaneFinding.FindPlanes(meshes, 0.0f, 0.0f);

            Console.WriteLine("Found {0} meshes", planes.Length);
            for (int i = 0; i < planes.Length; ++i)
            {
                Console.WriteLine("{0}:", i);
                Console.WriteLine("   Area:    {0}", planes[i].Area.ToString("0.000"));
                Console.WriteLine("   Center:  {0}", planes[i].Bounds.Center.ToString("0.000"));
                Console.WriteLine("   Extents: {0}", planes[i].Bounds.Extents.ToString("0.000"));
                Console.WriteLine("   Normal:  {0}", planes[i].Plane.normal.ToString("0.000"));
                Console.WriteLine();
            }
        }
Ejemplo n.º 4
0
        static void Main()
        {
            List <PlaneFinding.MeshData> meshes = new List <PlaneFinding.MeshData>
            {
                Util.CreateSimpleMesh(10, new Vector3(5, 5, 0))
            };

            BoundedPlane[] planes = PlaneFinding.FindPlanes(meshes, 0.0f, 0.0f);

            Console.WriteLine($"Found {planes.Length} plane{(planes.Length != 1 ? "s" : "")}");
            for (int i = 0; i < planes.Length; ++i)
            {
                Console.WriteLine("{0}:", i);
                Console.WriteLine("   Area:    {0}", planes[i].Area.ToString("0.000"));
                Console.WriteLine("   Center:  {0}", planes[i].Bounds.Center.ToString("0.000"));
                Console.WriteLine("   Extents: {0}", planes[i].Bounds.Extents.ToString("0.000"));
                Console.WriteLine("   Normal:  {0}", planes[i].Plane.normal.ToString("0.000"));
                Console.WriteLine();
            }
            Console.ReadKey();
        }
Ejemplo n.º 5
0
        private void FindMergedPlanes()
        {
            Vector3    hlWorldPosition = MixedRealityCamera.transform.position;
            Quaternion hlWorldRotation = MixedRealityCamera.transform.rotation;

            // Should not run plane finding on main Unity thread
            var planeFindingProcess = Task.Run(() => {
                m_mergedBoundingPlanes = PlaneFinding.FindPlanes(m_collectedMeshData, snapToGravityThreshold, MinimumPlaneArea).ToList();

                if (m_mergedBoundingPlanes.Count > 0)
                {
                    m_PlaneFindingSuccess.Set();
                }
                else
                {
                    m_PlaneFindingFailed.Set();
                }

                // Update Dictionary
                ParseRawPlaneData(hlWorldPosition);
            });
        }
Ejemplo n.º 6
0
        //-----------------------------------------------------------------------------------------------

        #region Private Functions

        /// <summary>
        /// Iterator block, analyzes surface meshes to find planes and create new 3D cubes to represent each plane.
        /// </summary>
        /// <returns>Yield result.</returns>
        private IEnumerator MakePlanesRoutine(List <HoloToolkit.Unity.SpatialMapping.PlaneFinding.MeshData> meshData)
        {
            MakingPlanes = true;
#if UNITY_WSA && !UNITY_EDITOR
            // When not in the unity editor we can use a cool background task to help manage FindPlanes().
            Task <BoundedPlane[]> planeTask = Task.Run(() => PlaneFinding.FindPlanes(meshData, snapToGravityThreshold, m_MinArea));

            while (planeTask.IsCompleted == false)
            {
                yield return(null);
            }

            BoundedPlane[] planes = planeTask.Result;
#else
            // In the unity editor, the task class isn't available, but perf is usually good, so we'll just wait for FindPlanes to complete.
            BoundedPlane[] planes = PlaneFinding.FindPlanes(meshData, snapToGravityThreshold, m_MinArea);
#endif

            // Pause our work here, and continue on the next frame.
            yield return(null);

            float start = Time.realtimeSinceStartup;

            float maxFloorArea   = 0.0f;
            float maxCeilingArea = 0.0f;
            FloorYPosition   = 0.0f;
            CeilingYPosition = 0.0f;

            // Find the floor and ceiling.
            // We classify the floor as the maximum horizontal surface below the user's head.
            // We classify the ceiling as the maximum horizontal surface above the user's head.
            for (int i = 0; i < planes.Length; i++)
            {
                BoundedPlane boundedPlane = planes[i];
                if (boundedPlane.Bounds.Center.y < 0 && boundedPlane.Plane.normal.y >= m_UpNormalThreshold)
                {
                    maxFloorArea = Mathf.Max(maxFloorArea, boundedPlane.Area);
                    if (maxFloorArea == boundedPlane.Area)
                    {
                        FloorYPosition = boundedPlane.Bounds.Center.y;
                    }
                }
                else if (boundedPlane.Bounds.Center.y > 0 && boundedPlane.Plane.normal.y <= -(m_UpNormalThreshold))
                {
                    maxCeilingArea = Mathf.Max(maxCeilingArea, boundedPlane.Area);
                    if (maxCeilingArea == boundedPlane.Area)
                    {
                        CeilingYPosition = boundedPlane.Bounds.Center.y;
                    }
                }
            }

            int newPlanes = 0;
            List <SurfacePlane> oldPlanes = new List <SurfacePlane>(m_ActivePlanes);
            // Create SurfacePlane objects to represent each plane found in the Spatial Mapping mesh.
            for (int index = 0; index < planes.Length; index++)
            {
                BoundedPlane boundedPlane = planes[index];
                boundedPlane.Bounds.Extents.z = m_PlaneThickness / 2.0f;
                SurfacePlane plane        = CheckForExistingPlane(oldPlanes, boundedPlane);
                bool         planeExisted = plane != null;

                if (plane == null)
                {
                    newPlanes++;
                    // This is a new plane.
                    GameObject newPlaneObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    plane = newPlaneObj.AddComponent <SurfacePlane>();
                    newPlaneObj.GetComponent <Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
                    newPlaneObj.transform.parent = planesParent.transform;

                    newPlaneObj.name = "Plane " + m_PlaneId;
                    m_PlaneId++;

                    plane.PlaneType = GetPlaneType(boundedPlane);
                    SetPlaneMaterial(plane);
                }
                else
                {
                    oldPlanes.Remove(plane);
                }

                // Set the Plane property to adjust transform position/scale/rotation and determine plane type.
                plane.PlaneThickness = m_PlaneThickness;
                plane.Plane          = boundedPlane;

                // Set the plane to use the same layer as the SpatialMapping mesh.  Do this every time incase the layer has changed.
                plane.gameObject.layer = SpatialMappingManager.Instance.PhysicsLayer;


                SetPlaneVisibility(plane);

                if ((m_DestroyPlanesMask & plane.PlaneType) == plane.PlaneType)
                {
                    DestroyImmediate(plane.gameObject);
                }
                else if (!planeExisted)
                {
                    AddPlane(plane);
                }

                // If too much time has passed, we need to return control to the main game loop.
                if ((Time.realtimeSinceStartup - start) > FrameTime)
                {
                    // Pause our work here, and continue making additional planes on the next frame.
                    yield return(null);

                    start = Time.realtimeSinceStartup;
                }
            }

            for (int index = 0; index < oldPlanes.Count; index++)
            {
                RemovePlane(oldPlanes[index]);
                Destroy(oldPlanes[index].gameObject);
            }

            // We are done creating planes, trigger an event.
            EventHandler handler = MakePlanesComplete;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }

            MakingPlanes = false;
        }