Exemplo n.º 1
0
        public IReadOnlyList <Room> TransformRooms(IEnumerable <Room> roomsToRotate, RectTransformation transformation)
        {
            IReadOnlyList <Room> rooms       = roomsToRotate as IReadOnlyList <Room> ?? roomsToRotate.ToList();
            RectangleInt2        coveredArea = new RectangleInt2(int.MaxValue, int.MaxValue, int.MinValue, int.MinValue);

            foreach (Room room in rooms)
            {
                coveredArea = coveredArea.Union(room.WorldArea);
            }
            return(TransformRooms(rooms, transformation, new VectorInt2((coveredArea.X0 + coveredArea.X1) / 2, (coveredArea.Y0 + coveredArea.Y1) / 2)));
        }
Exemplo n.º 2
0
        public virtual void Transform(RectTransformation transformation, VectorInt2 oldRoomSize)
        {
            IRotateableY rotateableObject = this as IRotateableY;

            if (rotateableObject != null)
            {
                float newRotation = rotateableObject.RotationY;
                if (transformation.MirrorX)
                {
                    newRotation = -newRotation;
                }
                newRotation -= transformation.QuadrantRotation * 90;
                rotateableObject.RotationY = newRotation;
            }
        }
Exemplo n.º 3
0
        private static DiagonalSplit TransformDiagonalSplit(DiagonalSplit split, RectTransformation transformation)
        {
            if (transformation.MirrorX)
            {
                switch (split)
                {
                case DiagonalSplit.XnZn:
                    split = DiagonalSplit.XpZn;
                    break;

                case DiagonalSplit.XpZn:
                    split = DiagonalSplit.XnZn;
                    break;

                case DiagonalSplit.XnZp:
                    split = DiagonalSplit.XpZp;
                    break;

                case DiagonalSplit.XpZp:
                    split = DiagonalSplit.XnZp;
                    break;
                }
            }

            for (int i = 0; i < transformation.QuadrantRotation; ++i)
            {
                switch (split)
                {
                case DiagonalSplit.XpZp:
                    split = DiagonalSplit.XnZp;
                    break;

                case DiagonalSplit.XnZp:
                    split = DiagonalSplit.XnZn;
                    break;

                case DiagonalSplit.XnZn:
                    split = DiagonalSplit.XpZn;
                    break;

                case DiagonalSplit.XpZn:
                    split = DiagonalSplit.XpZp;
                    break;
                }
            }

            return(split);
        }
Exemplo n.º 4
0
        public override void Transform(RectTransformation transformation, VectorInt2 oldRoomSize)
        {
            base.Transform(transformation, oldRoomSize);

            if (transformation.MirrorX)
            {
                switch (Direction)
                {
                case PortalDirection.WallNegativeX:
                    Direction = PortalDirection.WallPositiveX;
                    break;

                case PortalDirection.WallPositiveX:
                    Direction = PortalDirection.WallNegativeX;
                    break;
                }
            }

            for (int i = 0; i < transformation.QuadrantRotation; ++i)
            {
                switch (Direction)
                {
                case PortalDirection.WallPositiveX:
                    Direction = PortalDirection.WallPositiveZ;
                    break;

                case PortalDirection.WallPositiveZ:
                    Direction = PortalDirection.WallNegativeX;
                    break;

                case PortalDirection.WallNegativeX:
                    Direction = PortalDirection.WallNegativeZ;
                    break;

                case PortalDirection.WallNegativeZ:
                    Direction = PortalDirection.WallPositiveX;
                    break;
                }
            }
        }
Exemplo n.º 5
0
 public override void Transform(RectTransformation transformation, VectorInt2 oldRoomSize)
 {
     base.Transform(transformation, oldRoomSize);
     Position = transformation.TransformVec3(Position, oldRoomSize.X * 1024.0f, oldRoomSize.Y * 1024.0f);
 }
Exemplo n.º 6
0
 public override void Transform(RectTransformation transformation, VectorInt2 oldRoomSize)
 {
     base.Transform(transformation, oldRoomSize);
     _area = transformation.TransformRect(_area, oldRoomSize);
 }
Exemplo n.º 7
0
        public IReadOnlyList <Room> TransformRooms(IEnumerable <Room> roomsToRotate, RectTransformation transformation, VectorInt2 center)
        {
            roomsToRotate = roomsToRotate.SelectMany(room => room.Versions).Distinct();
            Room[] oldRooms    = roomsToRotate.ToArray();
            var    worldCenter = new VectorInt3(center.X, 0, center.Y) * 1024;

            // Copy rooms and sectors
            var newRooms = new Room[oldRooms.Length];

            for (int i = 0; i < oldRooms.Length; ++i)
            {
                var oldRoom = oldRooms[i];

                // Create room
                var newSize = transformation.QuadrantRotation % 2 == 0 ? oldRoom.SectorSize : new VectorInt2(oldRoom.NumZSectors, oldRoom.NumXSectors);
                var newRoom = oldRoom.Clone(this, obj => false); // This is a waste of computing power: All sectors are copied and immediately afterwards thrown away because the room needs to get resized.
                newRoom.Resize(this, new RectangleInt2(0, 0, newSize.X - 1, newSize.Y - 1));

                // Assign position
                var roomCenter = oldRoom.WorldPos + new VectorInt3(oldRoom.NumXSectors, 0, oldRoom.NumZSectors) * 512;
                roomCenter      -= worldCenter;
                roomCenter       = transformation.TransformVecInt3(roomCenter, oldRoom.NumXSectors, oldRoom.NumZSectors);
                roomCenter      += worldCenter;
                newRoom.WorldPos = roomCenter - new VectorInt3(newSize.X, 0, newSize.Y) * 512;

                // Copy sectors
                for (int z = 0; z < oldRoom.NumZSectors; ++z)
                {
                    for (int x = 0; x < oldRoom.NumXSectors; ++x)
                    {
                        VectorInt2 newSectorPosition = transformation.Transform(new VectorInt2(x, z), oldRoom.SectorSize);
                        newRoom.Blocks[newSectorPosition.X, newSectorPosition.Y] = oldRoom.Blocks[x, z].Clone();
                        newRoom.Blocks[newSectorPosition.X, newSectorPosition.Y].Transform(transformation, null,
                                                                                           oldFace => oldRoom.GetFaceShape(x, z, oldFace));
                    }
                }
                newRooms[i] = newRoom;
            }

            // Move objects to new rooms
            for (int i = 0; i < oldRooms.Length; ++i)
            {
                Room oldRoom = oldRooms[i];
                Room newRoom = newRooms[i];

                // Copy objects
                List <ObjectInstance> objects = oldRoom.AnyObjects.ToList();
                foreach (ObjectInstance @object in objects)
                {
                    oldRoom.RemoveObjectAndSingularPortalAndKeepAlive(this, @object);
                    @object.Transform(transformation, oldRoom.SectorSize);
                    @object.TransformRoomReferences(room =>
                    {
                        int index = Array.IndexOf(oldRooms, room);
                        if (index == -1)
                        {
                            return(room);
                        }
                        else
                        {
                            return(newRooms[index]);
                        }
                    });
                    newRoom.AddObjectAndSingularPortal(this, @object);
                }
            }

            // Assign new rooms
            for (int i = 0; i < oldRooms.Length; ++i)
            {
                if (oldRooms[i].AlternateRoom != null)
                {
                    newRooms[i].AlternateRoom = newRooms[Array.IndexOf(oldRooms, oldRooms[i].AlternateRoom)];
                }
                if (oldRooms[i].AlternateBaseRoom != null)
                {
                    newRooms[i].AlternateBaseRoom = newRooms[Array.IndexOf(oldRooms, oldRooms[i].AlternateBaseRoom)];
                }
            }
            for (int i = 0; i < oldRooms.Length; ++i)
            {
                int roomIndex = Array.IndexOf(Rooms, oldRooms[i]);
                Rooms[roomIndex] = newRooms[i];
            }

            return(newRooms);
        }
Exemplo n.º 8
0
        // Rotates and mirrors a sector according to a given transformation. The transformation can be combination of rotations and mirrors
        // but all possible transformation essentially are boiled down to a mirror on the x axis and a rotation afterwards.
        // Thus all that needs to be handled is mirroring on x and a single counterclockwise rotation (perhaps multiple times in a row).
        // When mirroring is done, a oldFaceIsTriangle must be provided that can return the previous shape of texture faces.
        // Set "onlyFloor" to true, to only modify the floor.
        // Set "onlyFloor" to false, to only modify the ceiling.
        public void Transform(RectTransformation transformation, bool?onlyFloor = null, Func <BlockFace, BlockFaceShape> oldFaceIsTriangle = null)
        {
            // Rotate sector flags
            if (transformation.MirrorX)
            {
                Flags =
                    (Flags & ~(BlockFlags.ClimbPositiveX | BlockFlags.ClimbNegativeX)) |
                    ((Flags & BlockFlags.ClimbPositiveX) != BlockFlags.None ? BlockFlags.ClimbNegativeX : BlockFlags.None) |
                    ((Flags & BlockFlags.ClimbNegativeX) != BlockFlags.None ? BlockFlags.ClimbPositiveX : BlockFlags.None);
            }

            for (int i = 0; i < transformation.QuadrantRotation; ++i)
            {
                Flags =
                    (Flags & ~(BlockFlags.ClimbPositiveX | BlockFlags.ClimbPositiveZ | BlockFlags.ClimbNegativeX | BlockFlags.ClimbNegativeZ)) |
                    ((Flags & BlockFlags.ClimbPositiveX) != BlockFlags.None ? BlockFlags.ClimbPositiveZ : BlockFlags.None) |
                    ((Flags & BlockFlags.ClimbPositiveZ) != BlockFlags.None ? BlockFlags.ClimbNegativeX : BlockFlags.None) |
                    ((Flags & BlockFlags.ClimbNegativeX) != BlockFlags.None ? BlockFlags.ClimbNegativeZ : BlockFlags.None) |
                    ((Flags & BlockFlags.ClimbNegativeZ) != BlockFlags.None ? BlockFlags.ClimbPositiveX : BlockFlags.None);
            }

            // Rotate sector geometry
            bool diagonalChange = transformation.MirrorX != (transformation.QuadrantRotation % 2 != 0);
            bool oldFloorSplitDirectionIsXEqualsZReal = Floor.SplitDirectionIsXEqualsZWithDiagonalSplit;

            if (onlyFloor != false)
            {
                bool requiredFloorSplitDirectionIsXEqualsZ = Floor.SplitDirectionIsXEqualsZ != diagonalChange;
                Floor.DiagonalSplit = TransformDiagonalSplit(Floor.DiagonalSplit, transformation);
                transformation.TransformValueDiagonalQuad(ref Floor.XpZp, ref Floor.XnZp, ref Floor.XnZn, ref Floor.XpZn);
                transformation.TransformValueDiagonalQuad(ref _ed[(int)BlockEdge.XpZp], ref _ed[(int)BlockEdge.XnZp], ref _ed[(int)BlockEdge.XnZn], ref _ed[(int)BlockEdge.XpZn]);
                if (requiredFloorSplitDirectionIsXEqualsZ != Floor.SplitDirectionIsXEqualsZ)
                {
                    Floor.SplitDirectionToggled = !Floor.SplitDirectionToggled;
                }

                if (HasGhostBlock)
                {
                    transformation.TransformValueDiagonalQuad(ref GhostBlock.Floor.XpZp, ref GhostBlock.Floor.XnZp, ref GhostBlock.Floor.XnZn, ref GhostBlock.Floor.XpZn);
                }
            }

            bool oldCeilingSplitDirectionIsXEqualsZReal = Ceiling.SplitDirectionIsXEqualsZWithDiagonalSplit;

            if (onlyFloor != true)
            {
                bool requiredCeilingSplitDirectionIsXEqualsZ = Ceiling.SplitDirectionIsXEqualsZ != diagonalChange;
                Ceiling.DiagonalSplit = TransformDiagonalSplit(Ceiling.DiagonalSplit, transformation);
                transformation.TransformValueDiagonalQuad(ref Ceiling.XpZp, ref Ceiling.XnZp, ref Ceiling.XnZn, ref Ceiling.XpZn);
                transformation.TransformValueDiagonalQuad(ref _rf[(int)BlockEdge.XpZp], ref _rf[(int)BlockEdge.XnZp], ref _rf[(int)BlockEdge.XnZn], ref _rf[(int)BlockEdge.XpZn]);
                if (requiredCeilingSplitDirectionIsXEqualsZ != Ceiling.SplitDirectionIsXEqualsZ)
                {
                    Ceiling.SplitDirectionToggled = !Ceiling.SplitDirectionToggled;
                }

                if (HasGhostBlock)
                {
                    transformation.TransformValueDiagonalQuad(ref GhostBlock.Ceiling.XpZp, ref GhostBlock.Ceiling.XnZp, ref GhostBlock.Ceiling.XnZn, ref GhostBlock.Ceiling.XpZn);
                }
            }

            // Rotate applied textures
            if (onlyFloor != false)
            {
                // Fix lower wall textures
                if (transformation.MirrorX)
                {
                    MirrorWallTexture(BlockFace.PositiveX_QA, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.PositiveZ_QA, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeX_QA, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeZ_QA, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.DiagonalQA, oldFaceIsTriangle);

                    MirrorWallTexture(BlockFace.PositiveX_ED, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.PositiveZ_ED, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeX_ED, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeZ_ED, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.DiagonalED, oldFaceIsTriangle);
                }
                transformation.TransformValueQuad(
                    ref _faceTextures[(int)BlockFace.PositiveX_QA],
                    ref _faceTextures[(int)BlockFace.PositiveZ_QA],
                    ref _faceTextures[(int)BlockFace.NegativeX_QA],
                    ref _faceTextures[(int)BlockFace.NegativeZ_QA]);
                transformation.TransformValueQuad(
                    ref _faceTextures[(int)BlockFace.PositiveX_ED],
                    ref _faceTextures[(int)BlockFace.PositiveZ_ED],
                    ref _faceTextures[(int)BlockFace.NegativeX_ED],
                    ref _faceTextures[(int)BlockFace.NegativeZ_ED]);

                // Fix floor textures
                if (Floor.IsQuad)
                {
                    _faceTextures[(int)BlockFace.Floor] = _faceTextures[(int)BlockFace.Floor].Transform(transformation * new RectTransformation {
                        QuadrantRotation = 2
                    });
                }
                else
                {
                    // Mirror
                    if (transformation.MirrorX)
                    {
                        Swap.Do(ref _faceTextures[(int)BlockFace.Floor], ref _faceTextures[(int)BlockFace.FloorTriangle2]);
                        Swap.Do(ref _faceTextures[(int)BlockFace.Floor].TexCoord0, ref _faceTextures[(int)BlockFace.Floor].TexCoord2);
                        Swap.Do(ref _faceTextures[(int)BlockFace.FloorTriangle2].TexCoord0, ref _faceTextures[(int)BlockFace.FloorTriangle2].TexCoord2);
                        if (Floor.DiagonalSplit != DiagonalSplit.None) // REMOVE this when we have better diaognal steps.
                        {
                            Swap.Do(ref _faceTextures[(int)BlockFace.Floor], ref _faceTextures[(int)BlockFace.FloorTriangle2]);
                        }
                    }

                    // Rotation
                    for (int i = 0; i < transformation.QuadrantRotation; ++i)
                    {
                        if (!oldFloorSplitDirectionIsXEqualsZReal)
                        {
                            Swap.Do(ref _faceTextures[(int)BlockFace.Floor], ref _faceTextures[(int)BlockFace.FloorTriangle2]);
                        }
                        if (Floor.DiagonalSplit != DiagonalSplit.None) // REMOVE this when we have better diaognal steps.
                        {
                            Swap.Do(ref _faceTextures[(int)BlockFace.Floor], ref _faceTextures[(int)BlockFace.FloorTriangle2]);
                        }
                        oldFloorSplitDirectionIsXEqualsZReal = !oldFloorSplitDirectionIsXEqualsZReal;
                    }
                }
            }
            if (onlyFloor != true)
            {
                // Fix upper wall textures
                if (transformation.MirrorX)
                {
                    MirrorWallTexture(BlockFace.PositiveX_WS, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.PositiveZ_WS, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeX_WS, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeZ_WS, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.DiagonalWS, oldFaceIsTriangle);

                    MirrorWallTexture(BlockFace.PositiveX_RF, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.PositiveZ_RF, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeX_RF, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeZ_RF, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.DiagonalRF, oldFaceIsTriangle);
                }
                transformation.TransformValueQuad(
                    ref _faceTextures[(int)BlockFace.PositiveX_WS],
                    ref _faceTextures[(int)BlockFace.PositiveZ_WS],
                    ref _faceTextures[(int)BlockFace.NegativeX_WS],
                    ref _faceTextures[(int)BlockFace.NegativeZ_WS]);
                transformation.TransformValueQuad(
                    ref _faceTextures[(int)BlockFace.PositiveX_RF],
                    ref _faceTextures[(int)BlockFace.PositiveZ_RF],
                    ref _faceTextures[(int)BlockFace.NegativeX_RF],
                    ref _faceTextures[(int)BlockFace.NegativeZ_RF]);

                // Fix ceiling textures
                if (Ceiling.IsQuad)
                {
                    _faceTextures[(int)BlockFace.Ceiling] = _faceTextures[(int)BlockFace.Ceiling].Transform(transformation * new RectTransformation {
                        QuadrantRotation = 2
                    });
                }
                else
                {
                    // Mirror
                    if (transformation.MirrorX)
                    {
                        Swap.Do(ref _faceTextures[(int)BlockFace.Ceiling], ref _faceTextures[(int)BlockFace.CeilingTriangle2]);
                        Swap.Do(ref _faceTextures[(int)BlockFace.Ceiling].TexCoord0, ref _faceTextures[(int)BlockFace.Ceiling].TexCoord2);
                        Swap.Do(ref _faceTextures[(int)BlockFace.CeilingTriangle2].TexCoord0, ref _faceTextures[(int)BlockFace.CeilingTriangle2].TexCoord2);
                        if (Ceiling.DiagonalSplit != DiagonalSplit.None) // REMOVE this when we have better diaognal steps.
                        {
                            Swap.Do(ref _faceTextures[(int)BlockFace.Ceiling], ref _faceTextures[(int)BlockFace.CeilingTriangle2]);
                        }
                    }

                    // Rotation
                    for (int i = 0; i < transformation.QuadrantRotation; ++i)
                    {
                        if (!oldCeilingSplitDirectionIsXEqualsZReal)
                        {
                            Swap.Do(ref _faceTextures[(int)BlockFace.Ceiling], ref _faceTextures[(int)BlockFace.CeilingTriangle2]);
                        }
                        if (Ceiling.DiagonalSplit != DiagonalSplit.None) // REMOVE this when we have better diaognal steps.
                        {
                            Swap.Do(ref _faceTextures[(int)BlockFace.Ceiling], ref _faceTextures[(int)BlockFace.CeilingTriangle2]);
                        }
                        oldCeilingSplitDirectionIsXEqualsZReal = !oldCeilingSplitDirectionIsXEqualsZReal;
                    }
                }
            }
            if (onlyFloor == null)
            {
                if (transformation.MirrorX)
                {
                    MirrorWallTexture(BlockFace.PositiveX_Middle, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.PositiveZ_Middle, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeX_Middle, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.NegativeZ_Middle, oldFaceIsTriangle);
                    MirrorWallTexture(BlockFace.DiagonalMiddle, oldFaceIsTriangle);
                }

                transformation.TransformValueQuad(
                    ref _faceTextures[(int)BlockFace.PositiveX_Middle],
                    ref _faceTextures[(int)BlockFace.PositiveZ_Middle],
                    ref _faceTextures[(int)BlockFace.NegativeX_Middle],
                    ref _faceTextures[(int)BlockFace.NegativeZ_Middle]);
            }
        }