/// <inheritdoc/>
        public GameObject GetTrackedAreaVisualization()
        {
            if (!Application.isPlaying)
            {
                return(null);
            }

            if (currentTrackedAreaObject != null)
            {
                return(currentTrackedAreaObject);
            }

            MixedRealityBoundaryVisualizationProfile profile = ConfigurationProfile as MixedRealityBoundaryVisualizationProfile;

            if (profile == null)
            {
                return(null);
            }

            if (Bounds.Length == 0)
            {
                // If we do not have boundary edges, we cannot render them.
                return(null);
            }

            // Get the line vertices
            List <Vector3> lineVertices = new List <Vector3>();

            for (int i = 0; i < Bounds.Length; i++)
            {
                lineVertices.Add(new Vector3(Bounds[i].PointA.x, 0f, Bounds[i].PointA.y));
            }
            // Add the first vertex again to ensure the loop closes.
            lineVertices.Add(lineVertices[0]);

            // We use an empty object and attach a line renderer.
            currentTrackedAreaObject       = new GameObject("Tracked Area");
            currentTrackedAreaObject.layer = ignoreRaycastLayerValue;
            currentTrackedAreaObject.AddComponent <LineRenderer>();
            currentTrackedAreaObject.transform.Translate(new Vector3(
                                                             MixedRealityPlayspace.Position.x,
                                                             boundaryObjectRenderOffset,
                                                             MixedRealityPlayspace.Position.z));
            currentPlayAreaObject.layer = TrackedAreaPhysicsLayer;

            // Configure the renderer properties.
            float        lineWidth    = 0.01f;
            LineRenderer lineRenderer = currentTrackedAreaObject.GetComponent <LineRenderer>();

            lineRenderer.sharedMaterial = profile.TrackedAreaMaterial;
            lineRenderer.useWorldSpace  = false;
            lineRenderer.startWidth     = lineWidth;
            lineRenderer.endWidth       = lineWidth;
            lineRenderer.positionCount  = lineVertices.Count;
            lineRenderer.SetPositions(lineVertices.ToArray());

            currentTrackedAreaObject.transform.parent = BoundaryVisualizationParent.transform;

            return(currentTrackedAreaObject);
        }
 public MixedRealityBoundarySystem(
     IMixedRealityServiceRegistrar registrar,
     MixedRealityBoundaryVisualizationProfile profile,
     ExperienceScale scale) : base(registrar, profile)
 {
     Scale = scale;
 }
Example #3
0
        /// <inheritdoc/>
        public GameObject GetBoundaryWallVisualization()
        {
            if (!Application.isPlaying)
            {
                return(null);
            }

            if (currentBoundaryWallObject != null)
            {
                return(currentBoundaryWallObject);
            }

            MixedRealityBoundaryVisualizationProfile profile = ConfigurationProfile as MixedRealityBoundaryVisualizationProfile;

            if (profile == null)
            {
                return(null);
            }

            if (!FloorHeight.HasValue)
            {
                // We need a floor on which to place the walls.
                return(null);
            }

            if (Bounds.Length == 0)
            {
                // If we do not have boundary edges, we cannot render walls.
                return(null);
            }

            currentBoundaryWallObject = new GameObject("Tracked Area Walls")
            {
                layer = BoundaryWallsPhysicsLayer
            };

            // Create and parent the child objects
            float wallDepth = boundaryObjectThickness;

            for (int i = 0; i < Bounds.Length; i++)
            {
                GameObject wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
                wall.name = $"Wall {i}";
                wall.GetComponent <Renderer>().sharedMaterial = profile.BoundaryWallMaterial;
                wall.transform.localScale = new Vector3((Bounds[i].PointB - Bounds[i].PointA).magnitude, BoundaryHeight, wallDepth);
                wall.layer = ignoreRaycastLayerValue;

                // Position and rotate the wall.
                Vector2 mid = Vector2.Lerp(Bounds[i].PointA, Bounds[i].PointB, 0.5f);
                wall.transform.position = new Vector3(mid.x, (BoundaryHeight * 0.5f), mid.y);
                float rotationAngle = MathUtilities.GetAngleBetween(Bounds[i].PointB, Bounds[i].PointA);
                wall.transform.rotation = Quaternion.Euler(0.0f, -rotationAngle, 0.0f);

                wall.transform.parent = currentBoundaryWallObject.transform;
            }

            currentBoundaryWallObject.transform.parent = BoundaryVisualizationParent.transform;

            return(currentBoundaryWallObject);
        }
Example #4
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="profile">The configuration profile for the service.</param>
 /// <param name="scale">The application's configured <see cref="Utilities.ExperienceScale"/>.</param>
 protected BaseBoundarySystem(
     MixedRealityBoundaryVisualizationProfile profile,
     ExperienceScale scale) : base(profile)
 {
     Scale           = scale;
     BoundaryProfile = profile;
 }
 public MixedRealityBoundarySystem(
     IMixedRealityServiceRegistrar registrar,
     MixedRealityBoundaryVisualizationProfile profile,
     ExperienceScale scale) : this(profile, scale)
 {
     Registrar = registrar;
 }
        /// <inheritdoc/>
        public override void Initialize()
        {
            if (!Application.isPlaying || !XRDevice.isPresent)
            {
                return;
            }

            MixedRealityBoundaryVisualizationProfile profile = ConfigurationProfile as MixedRealityBoundaryVisualizationProfile;

            if (profile == null)
            {
                return;
            }

            boundaryEventData = new BoundaryEventData(EventSystem.current);

            BoundaryHeight = profile.BoundaryHeight;

            SetTrackingSpace();
            CalculateBoundaryBounds();
            UnityBoundary.visible = true;

            ShowFloor                 = profile.ShowFloor;
            FloorPhysicsLayer         = profile.FloorPhysicsLayer;
            ShowPlayArea              = profile.ShowPlayArea;
            PlayAreaPhysicsLayer      = profile.PlayAreaPhysicsLayer;
            ShowTrackedArea           = profile.ShowTrackedArea;
            TrackedAreaPhysicsLayer   = profile.TrackedAreaPhysicsLayer;
            ShowBoundaryWalls         = profile.ShowBoundaryWalls;
            BoundaryWallsPhysicsLayer = profile.BoundaryWallsPhysicsLayer;
            ShowBoundaryCeiling       = profile.ShowBoundaryCeiling;
            CeilingPhysicsLayer       = profile.CeilingPhysicsLayer;

            if (ShowFloor)
            {
                GetFloorVisualization();
            }
            if (ShowPlayArea)
            {
                GetPlayAreaVisualization();
            }
            if (ShowTrackedArea)
            {
                GetTrackedAreaVisualization();
            }
            if (ShowBoundaryWalls)
            {
                GetBoundaryWallVisualization();
            }
            if (ShowBoundaryWalls)
            {
                GetBoundaryCeilingVisualization();
            }

            RaiseBoundaryVisualizationChanged();
        }
        /// <inheritdoc/>
        public GameObject GetBoundaryCeilingVisualization()
        {
            if (!Application.isPlaying)
            {
                return(null);
            }

            if (currentCeilingObject != null)
            {
                return(currentCeilingObject);
            }

            MixedRealityBoundaryVisualizationProfile profile = ConfigurationProfile as MixedRealityBoundaryVisualizationProfile;

            if (profile == null)
            {
                return(null);
            }

            if (Bounds.Length == 0)
            {
                // If we do not have boundary edges, we cannot render a ceiling.
                return(null);
            }

            // Get the smallest rectangle that contains the entire boundary.
            Bounds boundaryBoundingBox = new Bounds();

            for (int i = 0; i < Bounds.Length; i++)
            {
                // The boundary geometry is a closed loop. As such, we can encapsulate only PointA of each Edge.
                boundaryBoundingBox.Encapsulate(new Vector3(Bounds[i].PointA.x, BoundaryHeight * 0.5f, Bounds[i].PointA.y));
            }

            // Render the ceiling.
            float ceilingDepth = boundaryObjectThickness;

            currentCeilingObject       = GameObject.CreatePrimitive(PrimitiveType.Cube);
            currentCeilingObject.name  = "Ceiling";
            currentCeilingObject.layer = ignoreRaycastLayerValue;
            currentCeilingObject.transform.localScale = new Vector3(boundaryBoundingBox.size.x, ceilingDepth, boundaryBoundingBox.size.z);
            currentCeilingObject.transform.Translate(new Vector3(
                                                         boundaryBoundingBox.center.x,
                                                         BoundaryHeight + (currentCeilingObject.transform.localScale.y * 0.5f),
                                                         boundaryBoundingBox.center.z));
            currentCeilingObject.GetComponent <Renderer>().sharedMaterial = profile.BoundaryCeilingMaterial;
            currentCeilingObject.layer            = CeilingPhysicsLayer;
            currentCeilingObject.transform.parent = BoundaryVisualizationParent.transform;

            return(currentCeilingObject);
        }
        /// <inheritdoc/>
        public GameObject GetPlayAreaVisualization()
        {
            if (!Application.isPlaying)
            {
                return(null);
            }

            if (currentPlayAreaObject != null)
            {
                return(currentPlayAreaObject);
            }

            MixedRealityBoundaryVisualizationProfile profile = ConfigurationProfile as MixedRealityBoundaryVisualizationProfile;

            if (profile == null)
            {
                return(null);
            }

            // Get the rectangular bounds.
            Vector2 center;
            float   angle;
            float   width;
            float   height;

            if (!TryGetRectangularBoundsParams(out center, out angle, out width, out height))
            {
                // No rectangular bounds, therefore cannot create the play area.
                return(null);
            }

            // Render the rectangular bounds.
            if (!EdgeUtilities.IsValidPoint(center))
            {
                // Invalid rectangle / play area not found
                return(null);
            }

            currentPlayAreaObject       = GameObject.CreatePrimitive(PrimitiveType.Quad);
            currentPlayAreaObject.name  = "Play Area";
            currentPlayAreaObject.layer = PlayAreaPhysicsLayer;
            currentPlayAreaObject.transform.Translate(new Vector3(center.x, boundaryObjectRenderOffset, center.y));
            currentPlayAreaObject.transform.Rotate(new Vector3(90, -angle, 0));
            currentPlayAreaObject.transform.localScale = new Vector3(width, height, 1.0f);
            currentPlayAreaObject.GetComponent <Renderer>().sharedMaterial = profile.PlayAreaMaterial;

            currentPlayAreaObject.transform.parent = BoundaryVisualizationParent.transform;

            return(currentPlayAreaObject);
        }
        public MixedRealityBoundarySystem(
            IMixedRealityServiceRegistrar registrar,
            MixedRealityBoundaryVisualizationProfile profile,
            Transform playspace,
            ExperienceScale scale) : base(registrar, profile)
        {
            Scale = scale;

            if (playspace == null)
            {
                Debug.LogError("The MixedRealityBoundarySystem object requires a valid playspace Transform.");
            }
            Playspace = playspace;
        }
        /// <inheritdoc/>
        public GameObject GetFloorVisualization()
        {
            if (!Application.isPlaying)
            {
                return(null);
            }

            if (currentFloorObject != null)
            {
                return(currentFloorObject);
            }

            MixedRealityBoundaryVisualizationProfile profile = ConfigurationProfile as MixedRealityBoundaryVisualizationProfile;

            if (profile == null)
            {
                return(null);
            }

            if (!FloorHeight.HasValue)
            {
                // We were unable to locate the floor.
                return(null);
            }

            Vector2 floorScale = profile.FloorScale;

            // Render the floor.
            currentFloorObject      = GameObject.CreatePrimitive(PrimitiveType.Cube);
            currentFloorObject.name = "Boundary System Floor";
            currentFloorObject.transform.localScale = new Vector3(floorScale.x, boundaryObjectThickness, floorScale.y);
            currentFloorObject.transform.Translate(new Vector3(
                                                       MixedRealityPlayspace.Position.x,
                                                       FloorHeight.Value - (currentFloorObject.transform.localScale.y * 0.5f),
                                                       MixedRealityPlayspace.Position.z));
            currentFloorObject.layer = FloorPhysicsLayer;
            currentFloorObject.GetComponent <Renderer>().sharedMaterial = profile.FloorMaterial;

            return(currentFloorObject);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="profile">The configuration profile for the service.</param>
 /// <param name="scale">The application's configured <see cref="Utilities.ExperienceScale"/>.</param>
 public MixedRealityBoundarySystem(
     MixedRealityBoundaryVisualizationProfile profile,
     ExperienceScale scale) : base(profile, scale)
 {
 }