예제 #1
0
    // If an object has children, we place them here
    void PlaceChildren(GameObject surface, GameObject parent, SurfacePlane plane, Assessable assessable, PlacementPosition placementType)
    {
        assetCount += assessable.children.Length;

        // Set rotation to look towards room center
        Quaternion rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up);

        // Get Assessable component of child
        Assessable childAssessable = assessable.children[0].GetComponent <Assessable>();

        childAssessable.setPlane(plane);

        // Get Collider of child
        BoxCollider childCollider = assessable.children[0].GetComponent <BoxCollider>();

        if (childCollider == null)
        {
            Debug.Log("Child needs BoxCollider");
        }

        // Set initial position
        Vector3 position = surface.transform.position + ((plane.PlaneThickness + (.5f * Math.Abs(childCollider.size.z) * assessable.children[0].transform.localScale.z)) * plane.SurfaceNormal);

        if (placementType == PlacementPosition.WallFloor)
        {
            position.y = mainFloor.Plane.Bounds.Center.y + childCollider.size.y * .5f * childCollider.transform.localScale.y;
        }
        else if (placementType == PlacementPosition.MidWall)
        {
            position.y = position.y + childCollider.size.y * .5f;
        }

        Vector3 right = Vector3.Cross(surface.transform.forward, Vector3.up);

        position += (parent.transform.localScale.x * parent.GetComponent <BoxCollider>().size.x * .5f + assessable.children[0].transform.localScale.y * childCollider.size.x * .5f + .25f) * right;

        // Instantiate object
        GameObject childObject = Instantiate(assessable.children[0], position, rotation) as GameObject;

        if (CheckMenuPlace(position))
        {
            childObject.SetActive(false);
        }
        // Add object to list for later removal of scene
        instantiatedAssets.Add(childObject);

        if (assessable.children.Length > 1)
        {
            // Get Assessable component of child

            childAssessable = assessable.children[1].GetComponent <Assessable>();
            childAssessable.setPlane(plane);

            // Get Collider of child
            childCollider = assessable.children[1].GetComponent <BoxCollider>();
            if (childCollider == null)
            {
                Debug.Log("Child needs BoxCollider");
            }

            // Set initial position
            position = surface.transform.position + ((plane.PlaneThickness + (.5f * Math.Abs(childCollider.size.z) * assessable.children[1].transform.localScale.z)) * plane.SurfaceNormal);

            if (placementType == PlacementPosition.WallFloor)
            {
                position.y = mainFloor.Plane.Bounds.Center.y + childCollider.size.y * .5f * childCollider.transform.localScale.y;
            }
            else if (placementType == PlacementPosition.MidWall)
            {
                position.y = position.y + childCollider.size.y * .5f;
            }

            Vector3 left = Vector3.Cross(surface.transform.forward, -Vector3.up);
            position += (parent.transform.localScale.x * parent.GetComponent <BoxCollider>().size.x * .5f + assessable.children[1].transform.localScale.y * childCollider.size.x * .5f + .25f) * left;
            rotation  = Quaternion.LookRotation(surface.transform.forward, Vector3.up);

            // Instantiate object
            GameObject childObject2 = Instantiate(assessable.children[1], position, rotation) as GameObject;

            if (CheckMenuPlace(position))
            {
                childObject2.SetActive(false);
            }

            // Add object to list for later removal of scene
            instantiatedAssets.Add(childObject2);
        }
    }
예제 #2
0
    private void PlaceWallFloorObjects(List <GameObject> spaceObjects, List <GameObject> surfaces, PlacementPosition placementType)
    {
        #region Placement Technique Utilizing Spatial Mapping

        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>();

            // Order planes by distance to user
            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)
        {
            assetCount++;

            int index = -1;

            BoxCollider collider = item.GetComponent <BoxCollider>();

            if (collider == null)
            {
                Debug.Log("Object needs BoxCollider");
            }

            index = FindNearestPlane(surfaces, item.transform.localScale, placementType, UsedPlanes);

            UsedPlanes.Add(index);

            Quaternion rotation = Quaternion.identity;
            Vector3    position;

            // If there is somewhere to put the object
            if (index >= 0)
            {
                GameObject   surface = surfaces[index];
                SurfacePlane plane   = surface.GetComponent <SurfacePlane>();

                // Generate postion by taking middle point of plane and then offseting by the width of the asset
                position = surface.transform.position + ((plane.PlaneThickness + (.5f * Math.Abs(collider.size.z) * item.transform.localScale.z)) * plane.SurfaceNormal);

                if (placementType == PlacementPosition.WallFloor)
                {
                    position.y = mainFloor.Plane.Bounds.Center.y + collider.size.y * .5f * item.transform.localScale.y;
                }

                if (placementType == PlacementPosition.HighWall || placementType == PlacementPosition.MidWall || placementType == PlacementPosition.Ceiling)
                {
                    // Vertical objects should face out from the wall.
                    position.y = position.y + collider.size.y * .5f;
                    rotation   = Quaternion.LookRotation(surface.transform.forward, Vector3.up);
                }
                else
                {
                    rotation = Quaternion.LookRotation(surface.transform.forward, Vector3.up);
                }


                //Vector3 finalPosition = AdjustPositionWithSpatialMap(position, placementType);
                GameObject spaceObject = Instantiate(item, position, rotation) as GameObject;

                // Add object to list for later removal of scene
                instantiatedAssets.Add(spaceObject);

                Assessable assessable = spaceObject.GetComponent <Assessable>();
                assessable.setPlane(plane);
                if (CheckMenuPlace(position))
                {
                    spaceObject.SetActive(false);
                }
                // CHeck to see if object has children to place
                if (assessable.children.Length > 0)
                {
                    PlaceChildren(surface, item, plane, assessable, placementType);
                }
            }
        }

        #endregion

        #region Spatial Understanding API Technique

        /*
         * List<LevelSolver.PlacementQuery> placementQuery = new List<LevelSolver.PlacementQuery>();
         *
         * foreach (GameObject obj in spaceObjects)
         * {
         *  BoxCollider collider = obj.GetComponent<BoxCollider>();
         *
         *  //Debug.Log("x: " + (Math.Abs(collider.size.x) * obj.transform.localScale.x));
         *  //Debug.Log("y: " + (Math.Abs(collider.size.y) * obj.transform.localScale.y));
         *  //Debug.Log("z: " + (Math.Abs(collider.size.z) * obj.transform.localScale.z));
         *
         *  placementQuery.Add(levelSolver.Query_OnWall(((Math.Abs(collider.size.x) * obj.transform.localScale.x)) / 2.0f, ((Math.Abs(collider.size.y) * obj.transform.localScale.y)) / 2.0f, ((Math.Abs(collider.size.z) * obj.transform.localScale.z)) / 2.0f, 0.0f, Math.Abs(collider.size.y) * obj.transform.localScale.y + .5f));
         * }
         * LevelSolver.Instance.PlaceObjectAsync("OnWall", placementQuery);
         *
         * int returnedVal;
         *
         *      do
         *      {
         *          returnedVal = levelSolver.ProcessPlacementResults();
         *      }
         *      while (returnedVal == -1);
         *
         *      if(returnedVal == -2)
         *      {
         *          Debug.Log("Mapp is too small");
         *      }
         *      else
         *      {
         *
         *  for (int i = 0; i < levelSolver.placementResults.Count; i++)
         *  {*/
        //Debug.Log(levelSolver.placementResults[i].Result.Position.x + " " + levelSolver.placementResults[i].Result.Position.y + " " + levelSolver.placementResults[i].Result.Position.z);

        /*
         * float mindiff = 100.0f;
         *
         * GameObject minplane = new GameObject();
         * foreach (GameObject s in surfaces)
         * {
         *  float diff = Math.Abs((s.transform.position.x - levelSolver.result.Position.x) + (s.transform.position.z - levelSolver.result.Position.z));
         *  Debug.Log("diff " + diff);
         *  if (diff < mindiff)
         *  {
         *      diff = mindiff;
         *      minplane = s;
         *  }
         * }
         * Vector3 querypos = levelSolver.result.
         * querypos = levelSolver.result.Position;// + ((.5f * Math.Abs(collider.size.z) * obj.transform.localScale.z)) * -minplane.GetComponent<SurfacePlane>().SurfaceNormal;
         * querypos.y = mainFloor.Plane.Bounds.Center.y + collider.size.y * .5f * obj.transform.localScale.y;
         *
         * GameObject spaceObject = Instantiate(obj, querypos, Quaternion.LookRotation(-levelSolver.result.Forward, Vector3.up)) as GameObject;
         * spaceObject.SetActive(true);
         * }
         */

        //  }
        // }
        #endregion
    }