// 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); } }
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 }