Esempio n. 1
0
    /// <summary>
    /// Creates and positions a collection of Placeable space objects on SurfacePlanes in the environment.
    /// </summary>
    /// <param name="spaceObjects">Collection of prefab GameObjects that have the Placeable component.</param>
    /// <param name="surfaces">Collection of SurfacePlane objects in the world.</param>
    /// <param name="surfaceType">Type of objects and planes that we are trying to match-up.</param>
    private void CreateSpaceObjects(List <GameObject> spaceObjects, List <GameObject> surfaces, PlacementSurfaces surfaceType)
    {
        List <int> UsedPlanes = new List <int>();

        // Sort the planes by distance to user.
        surfaces.Sort((lhs, rhs) =>
        {
            Vector3 headPosition   = Camera.main.transform.position;
            Collider rightCollider = rhs.GetComponent <Collider>();
            Collider leftCollider  = lhs.GetComponent <Collider>();

            // This plane is big enough, now we will evaluate how far the plane is from the user's head.
            // Since planes can be quite large, we should find the closest point on the plane's bounds to the
            // user's head, rather than just taking the plane's center position.
            Vector3 rightSpot = rightCollider.ClosestPointOnBounds(headPosition);
            Vector3 leftSpot  = leftCollider.ClosestPointOnBounds(headPosition);

            return(Vector3.Distance(leftSpot, headPosition).CompareTo(Vector3.Distance(rightSpot, headPosition)));
        });

        foreach (GameObject item in spaceObjects)
        {
            int      index    = -1;
            Collider collider = item.GetComponent <Collider>();

            if (surfaceType == PlacementSurfaces.Vertical)
            {
                index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, true);
            }
            else
            {
                index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, false);
            }

            // If we can't find a good plane we will put the object floating in space.
            Vector3    position = Camera.main.transform.position + Camera.main.transform.forward * 2.0f + Camera.main.transform.right * (Random.value - 1.0f) * 2.0f;
            Quaternion rotation = Quaternion.identity;

            // If we do find a good plane we can do something smarter.
            if (index >= 0)
            {
                UsedPlanes.Add(index);
                GameObject   surface = surfaces[index];
                SurfacePlane plane   = surface.GetComponent <SurfacePlane>();
                position = surface.transform.position + (plane.PlaneThickness * plane.SurfaceNormal);
                position = AdjustPositionWithSpatialMap(position, plane.SurfaceNormal);
                rotation = Camera.main.transform.localRotation;

                if (surfaceType == PlacementSurfaces.Vertical)
                {
                    // Vertical objects should face out from the wall.
                    rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up);
                }
                else
                {
                    // Horizontal objects should face the user.
                    rotation   = Quaternion.LookRotation(Camera.main.transform.position);
                    rotation.x = 0f;
                    rotation.z = 0f;
                }
            }

            //Vector3 finalPosition = AdjustPositionWithSpatialMap(position, surfaceType);
            GameObject spaceObject = Instantiate(item, position, rotation) as GameObject;
            spaceObject.transform.parent = gameObject.transform;
            if (spaceObjects.Count == 1)
            {
                spaceObject.SendMessage("OnSelect");
            }
        }
    }
Esempio n. 2
0
    //Used in atof to spawn and place objects on the walls and playfield on the floor.
    /// <summary>
    /// Creates and positions a collection of Placeable game objects on SurfacePlanes in the environment.
    /// </summary>
    /// <param name="gameObjects">Collection of prefab GameObjects that have the Placeable component.</param>
    /// <param name="surfaces">Collection of SurfacePlane objects in the world.</param>
    /// <param name="surfaceType">Type of objects and planes that we are trying to match-up.</param>
    private void CreateGameObjects(List <GameObject> gameObjects, List <GameObject> surfaces, PlacementSurfaces surfaceType)
    {
        List <int> UsedPlanes = new List <int>();

        // Sort the planes by distance to user.
        surfaces.Sort((lhs, rhs) =>
        {
            Vector3 headPosition   = Camera.main.transform.position;
            Collider rightCollider = rhs.GetComponent <Collider>();
            Collider leftCollider  = lhs.GetComponent <Collider>();

            // This plane is big enough, now we will evaluate how far the plane is from the user's head.
            // Since planes can be quite large, we should find the closest point on the plane's bounds to the
            // user's head, rather than just taking the plane's center position.
            Vector3 rightSpot = rightCollider.ClosestPointOnBounds(headPosition);
            Vector3 leftSpot  = leftCollider.ClosestPointOnBounds(headPosition);

            return(Vector3.Distance(leftSpot, headPosition).CompareTo(Vector3.Distance(rightSpot, headPosition)));
        });

        foreach (GameObject item in gameObjects)
        {
            int      index    = -1;
            Collider collider = item.GetComponent <Collider>();

            if (surfaceType == PlacementSurfaces.Vertical)
            {
                index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, true);
            }
            else
            {
                index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, false);
            }

            // If we can't find a good plane could put the object floating in space. (then we can instantiate it or not, see ending of the code)
            Vector3    position = Camera.main.transform.position + Camera.main.transform.forward * 2.0f + Camera.main.transform.right * (Random.value - 1.0f) * 2.0f;
            Quaternion rotation = Quaternion.identity;

            // If we do find a good plane we can do something smarter.
            if (index >= 0)
            {
                UsedPlanes.Add(index); //We spawn only one object for each plane (for example, for each wall), in the nearest point of it wrt the player
                GameObject   surface = surfaces[index];
                SurfacePlane plane   = surface.GetComponent <SurfacePlane>();
                position = surface.transform.position + (plane.PlaneThickness * plane.SurfaceNormal);
                position = AdjustPositionWithSpatialMap(position, plane.SurfaceNormal);
                rotation = Camera.main.transform.localRotation;

                if (surfaceType == PlacementSurfaces.Vertical)
                {
                    // Vertical objects should face out from the wall.
                    rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up);
                }
                else
                {
                    // Horizontal objects should face the user.
                    rotation   = Quaternion.LookRotation(Camera.main.transform.position);
                    rotation.x = 0f;
                    rotation.z = 0f;
                }
            }

            //Vector3 finalPosition = AdjustPositionWithSpatialMap(position, surfaceType);

            //If it's the Playfield, we don't instantiate any prefab (the game object is already in hierarchy), we position it .
            if (item.CompareTag("Playfield"))
            {
                item.transform.position = position;

                //I case I would want to spawn directly the playfield exactly where the player is (without considering anything else), slightly different from previous method
                //float yfloorPosition = position.y;
                //item.transform.position = new Vector3(Camera.main.transform.position.x, yfloorPosition, Camera.main.transform.position.z);


                List <GameObject> tables = new List <GameObject>();
                tables = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Table);

                //Deactivating tables (useful just to avoid Playfield is placed inside them) to not see them anymore
                foreach (GameObject table in tables)
                {
                    table.layer = 10; //We set the layer to IGNORE GAZE, in this way even if there are unexpected problems (colliders of tables detected by gaze) we ignore them setting this layer
                    table.SetActive(false);
                }


                //item.transform.rotation = rotation;

                Vector3    relativeDistance     = position - Camera.main.transform.position;
                Quaternion playfieldNewRotation = Quaternion.LookRotation(relativeDistance);
                playfieldNewRotation.x  = 0f;
                playfieldNewRotation.z  = 0f;
                item.transform.rotation = playfieldNewRotation;


                if (item.activeInHierarchy == false)
                {
                    item.SetActive(true);
                }
            } //Here we decide if we want to instantiate the object only if we found a good plane (case index>=0) or anyway (in this last case you should remove the "else if" and leave just "Else")
            else if (index >= 0)
            {
                //Standard procedure to instantiate the prefabs
                GameObject gameItemObject = Instantiate(item, position, rotation) as GameObject;
                gameItemObject.transform.parent = gameObject.transform;

                if (gameItemObject.GetComponent <Placeable>().PlacementSurface == PlacementSurfaces.Vertical)
                {
                    spawnedWallsObjects.Add(gameItemObject);
                }
                else if (gameItemObject.GetComponent <Placeable>().PlacementSurface == PlacementSurfaces.Horizontal)
                {
                    spawnedFloorObjects.Add(gameItemObject);
                }
            }
            else if (index == -1)
            {
                //Due to the fact these are just decoration objects, if we can't find a plane to fit the objects, we don't instantiate them
                //Debug.Log("The object/decoration " + item.name + " could not be instantiated because there's no good plane that fits it (or they all have been already used to instantiate other objects)");
            }
        }
    }
Esempio n. 3
0
    /// <summary>
    /// Creates and positions a collection of Placeable space objects on SurfacePlanes in the environment.
    /// </summary>
    /// <param name="spaceObjects">Collection of prefab GameObjects that have the Placeable component.</param>
    /// <param name="surfaces">Collection of SurfacePlane objects in the world.</param>
    /// <param name="surfaceType">Type of objects and planes that we are trying to match-up.</param>
    private bool CreateSpaceObjects(GameObject spaceObjects, List <GameObject> surfaces, PlacementSurfaces surfaceType)
    {
        List <int> UsedPlanes = new List <int>();

        // Sort the planes by distance to user.
        surfaces.Sort((lhs, rhs) =>
        {
            Vector3 headPosition   = Camera.main.transform.position;
            Collider rightCollider = rhs.GetComponent <Collider>();
            Collider leftCollider  = lhs.GetComponent <Collider>();

            // This plane is big enough, now we will evaluate how far the plane is from the user's head.
            // Since planes can be quite large, we should find the closest point on the plane's bounds to the
            // user's head, rather than just taking the plane's center position.
            Vector3 rightSpot = rightCollider.ClosestPointOnBounds(headPosition);
            Vector3 leftSpot  = leftCollider.ClosestPointOnBounds(headPosition);

            return(Vector3.Distance(leftSpot, headPosition).CompareTo(Vector3.Distance(rightSpot, headPosition)));
        });

        debug.text = "" + (int)minAngle;

        // If we can't find a good plane we will put the object floating in space.
        Vector3 position = Camera.main.transform.position + Camera.main.transform.forward * 2.0f + Camera.main.transform.right * (Random.value - 1.0f) * 2.0f;

        while (UsedPlanes.Count < surfaces.Count)
        {
            int      index    = -1;
            Collider collider = spaceObjects.GetComponent <Collider> ();
            index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, false);

            // If we do find a good plane we can do something smarter.
            if (index >= 0)
            {
                UsedPlanes.Add(index);
                GameObject   surface = surfaces [index];
                SurfacePlane plane   = surface.GetComponent <SurfacePlane> ();
                position = surface.transform.position + (plane.PlaneThickness * plane.SurfaceNormal);
                position = AdjustPositionWithSpatialMap(position, plane.SurfaceNormal);

                //Check angle
                Vector3 targetDir = position - Camera.main.transform.position;
                float   angle     = Vector3.Angle(targetDir, Camera.main.transform.forward);

                if (Mathf.Abs(angle) < minAngle)
                {
                    minAngle   = Mathf.Abs(angle);
                    debug.text = "" + (int)minAngle;
                }

                float angleDelta = 15;
                if (totalAttempts >= 3)
                {
                    angleDelta = 360;
                }

                if (Mathf.Abs(angle) <= angleDelta)
                {
                    // Horizontal objects should face the user.
                    PlacePlayground(position);
                    debug.text = "angle placed = " + (int)minAngle;
                    return(true);
                }
                //
            }
            else
            {
                if (totalAttempts >= 3)
                {
                    PlacePlayground(position);
                    debug.text = "placed in the air";
                    return(true);
                }

                return(false);
            }
        }

        if (totalAttempts >= 3)
        {
            PlacePlayground(position);
            debug.text = "placed in the air";
            return(true);
        }

        return(false);
    }
Esempio n. 4
0
 /// <summary>
 /// Creates and positions a collection of Placeable space objects on SurfacePlanes in the environment.
 /// </summary>
 /// <param name="spaceObjects">Collection of prefab GameObjects that have the Placeable component.</param>
 /// <param name="surfaces">Collection of SurfacePlane objects in the world.</param>
 /// <param name="surfaceType">Type of objects and planes that we are trying to match-up.</param>
 private void CreateWidgets(List <GameObject> widgets, List <GameObject> surfaces, PlacementSurfaces surfaceType)
 {
     InstantiateWidgetsWithCalculatedPlacement(widgets, surfaces, surfaceType);
 }
Esempio n. 5
0
    // Update is called once per frame
    void Update()
    {
        switch (mode)
        {
        case Mode.AlignLookAt:
            if (psm.meshesProcessed)
            {
                List <GameObject> vertical   = new List <GameObject>();
                List <GameObject> horizontal = new List <GameObject>();
                horizontal = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Table);
                vertical   = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Wall);
                if (vertical.Count > 0)
                {
                    PlacementSurfaces surfaceType = PlacementSurfaces.Vertical;
                    vertical.Sort((lhs, rhs) => {
                        Vector3 headPosition   = Camera.main.transform.position;
                        Collider rightCollider = rhs.GetComponent <Collider>();
                        Collider leftCollider  = lhs.GetComponent <Collider>();

                        // This plane is big enough, now we will evaluate how far the plane is from the user's head.
                        // Since planes can be quite large, we should find the closest point on the plane's bounds to the
                        // user's head, rather than just taking the plane's center position.
                        Vector3 rightSpot = rightCollider.ClosestPointOnBounds(headPosition);
                        Vector3 leftSpot  = leftCollider.ClosestPointOnBounds(headPosition);

                        return(Vector3.Distance(leftSpot, headPosition).CompareTo(Vector3.Distance(rightSpot, headPosition)));
                    });
                    int      index    = -1;
                    Collider collider = gameObject.GetComponent <Collider>();
                    index = FindNearestPlane(vertical, collider.bounds.size);
                    Quaternion rotation = Quaternion.identity;
                    if (index >= 0)
                    {
                        GameObject   surface = vertical[index];
                        SurfacePlane plane   = surface.GetComponent <SurfacePlane>();
#if DEBUG
                        Debug.Log("Wall's surface normal with respect to starting camera direction: " + plane.SurfaceNormal);
#endif
                        aligned_forward = surface.transform.forward;
                        if (!SpatialMappingManager.Instance.IsObserverRunning())
                        {
                            // If running, Stop the observer by calling
                            // StopObserver() on the SpatialMappingManager.Instance.
                            SpatialMappingManager.Instance.StartObserver();
                        }
                        GameObject SpatialProcessing = GameObject.Find("SpatialProcessing");
                        SpatialProcessing.SetActive(false);
                        dbtext.text = "Tap anywhere to finish scanning";
                        mode        = Mode.ContinueScanning;
                    }
                }
            }
            break;

        case Mode.ContinueScanning:
            //Now it is waiting for a Tap event to happen. A state change will occur in the OnInputClicked function if mode equals to Mode.ContinueScanning
            break;

        case Mode.Placing:
            if (!ttp.IsBeingPlaced)
            {
                WorldAnchorManager.Instance.RemoveAnchor(gameObject);
                speechRecognition.SetActive(true);
                //transform.rotation = Quaternion.LookRotation(aligned_forward, Vector3.up);
                mode = Mode.SetRotation;
            }
            break;

        case Mode.SetRotation:
            Quaternion tmp = Quaternion.LookRotation(aligned_forward, Vector3.up);
            gameObject.transform.rotation = Quaternion.Euler(ttp.initial_rotation) * Quaternion.LookRotation(aligned_forward, Vector3.up);
            mode = Mode.Tuning;
            break;

        case Mode.Tuning:
            Tune();
            break;
        }
        UnityEngine.XR.WSA.HolographicSettings.SetFocusPointForFrame(transform.position - Camera.main.transform.position);
    }
    /// <summary>
    /// Creates and positions a collection of Placeable space objects on SurfacePlanes in the environment.
    /// </summary>
    /// <param name="spaceObjects">Collection of prefab GameObjects that have the Placeable component.</param>
    /// <param name="surfaces">Collection of SurfacePlane objects in the world.</param>
    /// <param name="surfaceType">Type of objects and planes that we are trying to match-up.</param>
    private void CreateSpaceObjects(List <GameObject> spaceObjects, List <GameObject> surfaces, PlacementSurfaces surfaceType)
    {
        List <int> UsedPlanes = new List <int>();

        // Sort the planes by distance to user.
        surfaces.Sort((lhs, rhs) =>
        {
            Vector3 headPosition   = Camera.main.transform.position;
            Collider rightCollider = rhs.GetComponent <Collider>();
            Collider leftCollider  = lhs.GetComponent <Collider>();

            // This plane is big enough, now we will evaluate how far the plane is from the user's head.
            // Since planes can be quite large, we should find the closest point on the plane's bounds to the
            // user's head, rather than just taking the plane's center position.
            /// Самая близкая точка на границе плоскости к голове пользователя.
            Vector3 rightSpot = rightCollider.ClosestPointOnBounds(headPosition);
            Vector3 leftSpot  = leftCollider.ClosestPointOnBounds(headPosition);

            return(Vector3.Distance(leftSpot, headPosition).CompareTo(Vector3.Distance(rightSpot, headPosition)));
        });

        for (int i = 0; i < spaceObjects.Count; i++)
        {
            int      index    = -1;
            Collider collider = spaceObjects[i].GetComponent <Collider>();

            if (surfaceType == PlacementSurfaces.Vertical)
            {
                // => ?
                index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, true);
            }
            else
            {
                index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, false);
            }

            // If we can't find a good plane we will put the object floating in space.
            Vector3    position = Camera.main.transform.position + Camera.main.transform.forward * 2.0f + Camera.main.transform.right * (Random.value - 1.0f) * 2.0f;
            Quaternion rotation = Quaternion.identity;

            // If we do find a good plane we can do something smarter.
            if (index >= 0)
            {
                UsedPlanes.Add(index);
                // Приравниваем к новой ссылке GameObject'а плоскость из списка, которая прошла проверку, т.е. переменная "index" является номером подходящей плосоксти.
                GameObject   surface = surfaces[index];
                SurfacePlane plane   = surface.GetComponent <SurfacePlane>();
                position = surface.transform.position + (plane.PlaneThickness * plane.SurfaceNormal);
                position = AdjustPositionWithSpatialMap(position, plane.SurfaceNormal);
                rotation = Camera.main.transform.localRotation;

                if (surfaceType == PlacementSurfaces.Vertical)
                {
                    // Vertical objects should face out from the wall.
                    rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up);
                }
                else
                {
                    // Horizontal objects should face the user.
                    rotation   = Quaternion.LookRotation(Camera.main.transform.position);
                    rotation.x = 0f;
                    rotation.z = 0f;
                }
            }

            if (i == 0 && surfaceType == PlacementSurfaces.Horizontal)
            {
                overrideObject.transform.position = position + new Vector3(0.0f, 0.2f, 0.0f);
                overrideObject.SetActive(true);
            }
            else
            {
                //Vector3 finalPosition = AdjustPositionWithSpatialMap(position, surfaceType);
                GameObject spaceObject = Instantiate(spaceObjects[i], position, rotation) as GameObject;
                spaceObject.transform.parent = gameObject.transform;
            }
        }

        /*
         * foreach (GameObject item in spaceObjects)
         * {
         *  int index = -1;
         *  Collider collider = item.GetComponent<Collider>();
         *
         *  if (surfaceType == PlacementSurfaces.Vertical)
         *  {
         *      // => ?
         *      index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, true);
         *  }
         *  else
         *  {
         *      index = FindNearestPlane(surfaces, collider.bounds.size, UsedPlanes, false);
         *  }
         *
         *  // If we can't find a good plane we will put the object floating in space.
         *  Vector3 position = Camera.main.transform.position + Camera.main.transform.forward * 2.0f + Camera.main.transform.right * (Random.value - 1.0f) * 2.0f;
         *  Quaternion rotation = Quaternion.identity;
         *
         *  // If we do find a good plane we can do something smarter.
         *  if (index >= 0)
         *  {
         *      UsedPlanes.Add(index);
         *      // Приравниваем к новой ссылке GameObject'а плоскость из списка, которая прошла проверку, т.е. переменная "index" является номером подходящей плосоксти.
         *      GameObject surface = surfaces[index];
         *      SurfacePlane plane = surface.GetComponent<SurfacePlane>();
         *      position = surface.transform.position + (plane.PlaneThickness * plane.SurfaceNormal);
         *      position = AdjustPositionWithSpatialMap(position, plane.SurfaceNormal);
         *      rotation = Camera.main.transform.localRotation;
         *
         *      if (surfaceType == PlacementSurfaces.Vertical)
         *      {
         *          // Vertical objects should face out from the wall.
         *          rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up);
         *      }
         *      else
         *      {
         *          // Horizontal objects should face the user.
         *          rotation = Quaternion.LookRotation(Camera.main.transform.position);
         *          rotation.x = 0f;
         *          rotation.z = 0f;
         *      }
         *  }
         *
         *  //Vector3 finalPosition = AdjustPositionWithSpatialMap(position, surfaceType);
         *  GameObject spaceObject = Instantiate(item, position, rotation) as GameObject;
         *  spaceObject.transform.parent = gameObject.transform;
         * }
         */
    }