Ejemplo n.º 1
0
        /// <summary>
        /// Creates a RoomPlane of the current planetype.
        /// </summary>
        public void FinishRoomPlane()
        {
            // first create the polygon
            PolygonManager.Instance.ClosePolygon();
            Polygon   polygon   = PolygonManager.Instance.CurrentPolygon;
            RoomPlane roomPlane = null;

            switch (CurrentPlaneType)
            {
            // for now we assume that the floor has no stairs or ramps,
            // so it should consist of points approx. on the same plane
            case PlaneType.Floor:
                roomPlane = createFloor(polygon.Center);
                roomPlane.Setup(polygon, CurrentPlaneType.Value);
                FloorTransformOperator.Instance.Create();
                break;

            case PlaneType.Ceiling:
            case PlaneType.Wall:
            default:
                break;
            }
            if (roomPlane == null)
            {
                return;
            }
            CurrentPlaneType = null;
            InputManager.Instance.PopModalInputHandler();
            TextManager.Instance.HideTutorial();
            MenuHub.Instance.ShowDefaultMenu();
            if (SpatialMappingManager.IsInitialized)
            {
                SpatialMappingManager.Instance.DrawVisualMeshes = false;
            }
        }
Ejemplo n.º 2
0
        private RoomPlane createFloor(Vector3 position)
        {
            RoomPlane floor = Instantiate(RoomPlanePrefab, position, Quaternion.identity);

            floor.gameObject.name = "Floor";
            Floor = floor;
            return(floor);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Spawns an object which has the chosen tile spawned on the roomPlane with a mask around it.
        /// </summary>
        /// <param name="tileData"></param>
        /// <param name="roomPlane"></param>
        /// <param name="spawnPoint"></param>
        /// <param name="directionPoint"></param>
        private bool createTileFloorInternal(TileData tileData, RoomPlane roomPlane, Transform spawnPoint, Transform directionPoint)
        {
            // first create the copy so we do not mess with the original spawnpoint, we will destroy this object later on
            var spawnPointCopy = new GameObject("SpawnPointCopy");

            spawnPointCopy.transform.position = spawnPoint.position;
            spawnPointCopy.transform.rotation = spawnPoint.rotation;
            spawnPointCopy.transform.forward  = directionPoint.position - spawnPoint.position;
            // now find the min and max values of the plane
            float maxZ, maxX, minZ, minX;

            maxZ = maxX = minZ = minX = 0f;
            for (int i = 0; i < roomPlane.MeshPolygon.Points.Count; i++)
            {
                // transform the point into the local space of the plane
                Vector3 localPosition = spawnPointCopy.transform.InverseTransformPoint(roomPlane.MeshPolygon.Points[i].transform.position);
                // adjust min and max values
                if (localPosition.x > maxX)
                {
                    maxX = localPosition.x;
                }
                else if (localPosition.x < minX)
                {
                    minX = localPosition.x;
                }
                if (localPosition.z > maxZ)
                {
                    maxZ = localPosition.z;
                }
                else if (localPosition.z < minZ)
                {
                    minZ = localPosition.z;
                }
            }

            // create the border points of the plane given by the min and max values
            var minXminZ_Point = new GameObject();

            minXminZ_Point.transform.position = spawnPointCopy.transform.TransformPoint(new Vector3(minX, 0f, minZ));

            var minXmaxZ_Point = new GameObject();

            minXmaxZ_Point.transform.position = spawnPointCopy.transform.TransformPoint(new Vector3(minX, 0f, maxZ));

            var maxXminZ_Point = new GameObject();

            maxXminZ_Point.transform.position = spawnPointCopy.transform.TransformPoint(new Vector3(maxX, 0f, minZ));

            var maxXmaxZ_Point = new GameObject();

            maxXmaxZ_Point.transform.position = spawnPointCopy.transform.TransformPoint(new Vector3(maxX, 0f, maxZ));

            // create a parent object for all the tiles
            var tilePlane = new GameObject("TilePlane");

            tilePlane.transform.position = roomPlane.MeshPolygon.Center;

            var jointSize  = tileData.JointSize * 0.5f;
            var tileWidth  = (tileData.Width + jointSize);
            var tileHeight = (tileData.Height + jointSize);

            // calculate how many rows and columns are needed for the tile creation, we go one row and column further because of the offset
            int columns = Mathf.CeilToInt((minXminZ_Point.transform.position - maxXminZ_Point.transform.position).magnitude / tileWidth) + 1;
            int rows    = Mathf.CeilToInt((minXminZ_Point.transform.position - minXmaxZ_Point.transform.position).magnitude / tileHeight) + 1;

            // adjust forward and right vector of the starting vertex of the plane
            minXminZ_Point.transform.forward = (minXmaxZ_Point.transform.position - minXminZ_Point.transform.position).normalized;
            minXminZ_Point.transform.right   = (maxXminZ_Point.transform.position - minXminZ_Point.transform.position).normalized;
            Vector3 startPosition = minXminZ_Point.transform.position + minXminZ_Point.transform.right * tileWidth / 2f + minXminZ_Point.transform.forward * tileHeight / 2f;
            // calculate the offset needed so that the tiles align perfectely at the spawn point
            Vector3 minToSpawn = minXminZ_Point.transform.InverseTransformPoint(spawnPoint.position);
            // we need to move the whole tile plane at least a little so it cannot happen that a floor edge lies on the surrounding mask edge
            // because the mesh creation algorithm in MeshUtility cannot create a mesh with overlapping edges => Mathf.Max(...)
            float xOffset = Mathf.Max(tileWidth - Mathf.Repeat(minToSpawn.x, tileWidth), 0.001f);
            float zOffset = Mathf.Max(tileHeight - Mathf.Repeat(minToSpawn.z, tileHeight), 0.001f);

            startPosition -= xOffset * minXminZ_Point.transform.right + zOffset * minXminZ_Point.transform.forward;
            // place the tiles
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < columns; j++)
                {
                    Vector3 offset      = i * tileHeight * minXminZ_Point.transform.forward + j * tileWidth * minXminZ_Point.transform.right;
                    var     currentTile = Instantiate(DefaultTilePrefab, startPosition + offset, minXminZ_Point.transform.rotation);
                    currentTile.transform.parent = tilePlane.transform;
                    currentTile.LinkTile(tileData);
                }
            }

            // create the mask plane with has the room plane polygon as a hole
            var maskPlaneVertices = new List <Vector2>();
            // max and min points as boundary points
            Vector3 mask_minXminZ = startPosition - (minXminZ_Point.transform.right * tileWidth / 2f + minXminZ_Point.transform.forward * tileHeight / 2f);
            Vector3 mask_minXmaxZ = mask_minXminZ + minXminZ_Point.transform.forward * tileHeight * rows;
            Vector3 mask_maxXminZ = mask_minXminZ + minXminZ_Point.transform.right * tileWidth * columns;
            Vector3 mask_maxXmaxZ = mask_minXminZ + minXminZ_Point.transform.forward * tileHeight * rows + minXminZ_Point.transform.right * tileWidth * columns;
            Vector3 mask_center   = (mask_minXminZ + mask_minXmaxZ + mask_maxXminZ + mask_maxXmaxZ) / 4f;
            // add the outer mask boundary as list for later uses
            List <Vector3> maskBoundaries = new List <Vector3> {
                mask_minXminZ, mask_minXmaxZ, mask_maxXmaxZ, mask_maxXminZ
            };

            maskPlaneVertices.Add(new Vector2(mask_minXminZ.x - mask_center.x, mask_minXminZ.z - mask_center.z));
            maskPlaneVertices.Add(new Vector2(mask_minXmaxZ.x - mask_center.x, mask_minXmaxZ.z - mask_center.z));
            maskPlaneVertices.Add(new Vector2(mask_maxXmaxZ.x - mask_center.x, mask_maxXmaxZ.z - mask_center.z));
            maskPlaneVertices.Add(new Vector2(mask_maxXminZ.x - mask_center.x, mask_maxXminZ.z - mask_center.z));
            var maskPlaneHoles = new List <List <Vector2> >();
            var maskPlaneHole  = new List <Vector2>();

            // room plane as hole
            foreach (var point in roomPlane.MeshPolygon.Points)
            {
                maskPlaneHole.Add(new Vector2(point.transform.position.x - mask_center.x, point.transform.position.z - mask_center.z));
            }
            maskPlaneHoles.Add(maskPlaneHole);
            // this method can fail for intersecting constraints therefore we need a try/catch block
            Mesh maskPlaneMesh = null;

            try
            {
                maskPlaneMesh = MeshUtility.CreatePolygonMesh(maskPlaneVertices, maskPlaneHoles);
            }
            catch
            {
                // indicate that the tile creation process was not successful
                Destroy(minXminZ_Point);
                Destroy(minXmaxZ_Point);
                Destroy(maxXminZ_Point);
                Destroy(maxXmaxZ_Point);
                Destroy(spawnPointCopy);
                Destroy(tilePlane);
                return(false);
            }
            var maskPlane           = new GameObject("MaskPlane");
            var maskPlaneMeshFilter = maskPlane.AddComponent <MeshFilter>();

            maskPlaneMeshFilter.mesh = maskPlaneMesh;
            var maskPlaneMeshRenderer = maskPlane.AddComponent <MeshRenderer>();

            maskPlane.transform.position   = (mask_minXminZ + mask_minXmaxZ + mask_maxXminZ + mask_maxXmaxZ) / 4f;
            maskPlane.transform.position  += new Vector3(0f, tileData.TileThickness * 0.5f + 0.0001f, 0f);
            maskPlane.transform.localScale = new Vector3(1f, -1f, 1f);
            maskPlane.GetComponent <Renderer>().material = DepthMaskMaterial;

            // create mask planes at the outer boundary of the maskplane so we mask the border tile joints as well
            for (int i = 0; i < maskBoundaries.Count; i++)
            {
                var point1 = maskBoundaries[i];
                var point2 = maskBoundaries[MathUtility.WrapArrayIndex(i + 1, maskBoundaries.Count)];
                var point3 = point1 - new Vector3(0f, tileData.TileThickness, 0f);
                // create the joint plane in the center of two points
                var jointMaskPlanePosition = (point1 + point2) * 0.5f;
                // lower it depending on the tile thickness
                //jointPlanePosition -= new Vector3(0f, TileDimensionsLibrary.GetTileThickness(tileData.TileThickness) * 0.5f, 0f);
                var jointMaskPlaneScale = new Vector3((point2 - point1).magnitude, 0.001f, (point3 - point1).magnitude);
                // create joint plane
                var jointMaskPlane = GameObject.CreatePrimitive(PrimitiveType.Cube);
                // adjust position and forward vector
                jointMaskPlane.transform.position                 = jointMaskPlanePosition;
                jointMaskPlane.transform.right                    = (point2 - point1).normalized;
                jointMaskPlane.transform.localEulerAngles         = new Vector3(90f, jointMaskPlane.transform.localEulerAngles.y, jointMaskPlane.transform.localEulerAngles.z);
                jointMaskPlane.transform.localScale               = jointMaskPlaneScale;
                jointMaskPlane.GetComponent <Renderer>().material = DepthMaskMaterial;
                jointMaskPlane.name             = "jointMaskPlane";
                jointMaskPlane.transform.parent = maskPlane.transform;
            }

            // create planes at the corner of the roomplane so it looks like these are the tiles ends so we can see the joints from the side
            for (int i = 0; i < roomPlane.MeshPolygon.Points.Count; i++)
            {
                var point1 = roomPlane.MeshPolygon.Points[i].transform.position;
                var point2 = roomPlane.MeshPolygon.Points[MathUtility.WrapArrayIndex(i + 1, roomPlane.MeshPolygon.Points.Count)].transform.position;
                var point3 = point1 - new Vector3(0f, tileData.TileThickness, 0f);
                // create the joint plane in the center of two points
                var jointPlanePosition = (point1 + point2) * 0.5f;
                // lower it depending on the tile thickness
                //jointPlanePosition -= new Vector3(0f, TileDimensionsLibrary.GetTileThickness(tileData.TileThickness) * 0.5f, 0f);
                var jointPlaneScale = new Vector3((point2 - point1).magnitude, 0.001f, (point3 - point1).magnitude);
                // create joint plane
                var jointPlane = GameObject.CreatePrimitive(PrimitiveType.Cube);
                // adjust position and forward vector
                jointPlane.transform.position                 = jointPlanePosition;
                jointPlane.transform.right                    = (point2 - point1).normalized;
                jointPlane.transform.localEulerAngles         = new Vector3(90f, jointPlane.transform.localEulerAngles.y, jointPlane.transform.localEulerAngles.z);
                jointPlane.transform.localScale               = jointPlaneScale;
                jointPlane.GetComponent <Renderer>().material = MaskResistentMaterial;
                jointPlane.name             = "jointPlane";
                jointPlane.transform.parent = maskPlane.transform;
            }
            // create a parent for overview purposes
            if (FinishedTileFloor != null)
            {
                Destroy(FinishedTileFloor);
            }

            FinishedTileFloor = new GameObject("finishedTileFloor");
            FinishedTileFloor.transform.position = tilePlane.transform.position;
            tilePlane.transform.parent           = FinishedTileFloor.transform;
            maskPlane.transform.parent           = FinishedTileFloor.transform;

            // cleanup
            Destroy(minXminZ_Point);
            Destroy(minXmaxZ_Point);
            Destroy(maxXminZ_Point);
            Destroy(maxXmaxZ_Point);
            Destroy(spawnPointCopy);
            return(true);
        }