public PortalTemplate(XmlNode xmlNode) { int pixel_x = Int32.Parse(xmlNode.Attributes["x"].Value); int pixel_y = Int32.Parse(xmlNode.Attributes["y"].Value); int pixel_width = (xmlNode.Attributes["width"] != null) ? Int32.Parse(xmlNode.Attributes["width"].Value) : (int)GameConstants.TILE_PIXEL_SIZE; int pixel_height = (xmlNode.Attributes["height"] != null) ? Int32.Parse(xmlNode.Attributes["height"].Value) : (int)GameConstants.TILE_PIXEL_SIZE; Point3d position0 = GameConstants.ConvertPixelPositionToRoomPosition(pixel_x, pixel_y); Point3d position1 = GameConstants.ConvertPixelPositionToRoomPosition(pixel_x + pixel_width, pixel_y + pixel_height); portal_id = Int32.Parse(xmlNode.Attributes["id"].Value); bounding_box = new AABB3d( Point3d.Min(position0, position1), Point3d.Max(position0, position1)); roomSide = (MathConstants.eSignedDirection)Enum.Parse(typeof(MathConstants.eSignedDirection), xmlNode.Attributes["Direction"].Value); portal_type = (ePortalType)Enum.Parse(typeof(ePortalType), xmlNode.Attributes["Type"].Value); }
public Portal() { portal_id= -1; target_portal_id = -1; room_x= 0; room_y= 0; room_z= 0; portal_type = ePortalType.door; room_side = MathConstants.eSignedDirection.positive_x; bounding_box = new AABB3d(); }
public AABB3d bounding_box; // Room Relative public Portal() { portal_id = -1; target_portal_id = -1; room_x = 0; room_y = 0; room_z = 0; portal_type = ePortalType.door; room_side = MathConstants.eSignedDirection.positive_x; bounding_box = new AABB3d(); }
private bool ValidatePortalTypeExpectedRoomSide( RoomTemplate roomTemplate) { bool success = true; foreach (PortalTemplate portalTempate in roomTemplate.PortalTemplates) { int portal_id = portalTempate.PortalID; MathConstants.eSignedDirection roomSide = portalTempate.PortalRoomSide; switch (portalTempate.PortalType) { case ePortalType.door: if (roomSide != MathConstants.eSignedDirection.positive_x && roomSide != MathConstants.eSignedDirection.negative_x && roomSide != MathConstants.eSignedDirection.positive_y && roomSide != MathConstants.eSignedDirection.negative_y) { _logger.LogError( string.Format( "RoomTemplateParser: Template {0}, door portal id={1} on unexpected side={2}", roomTemplate.TemplateName, portal_id, roomSide)); success = false; } break; case ePortalType.stairs: if (roomSide != MathConstants.eSignedDirection.positive_z && roomSide != MathConstants.eSignedDirection.negative_z) { _logger.LogError( string.Format( "RoomTemplateParser: Template {0}, stairs portal id={1} on unexpected side={2}", roomTemplate.TemplateName, portal_id, roomSide)); success = false; } break; case ePortalType.teleporter: if (roomSide != MathConstants.eSignedDirection.none) { _logger.LogError( string.Format( "RoomTemplateParser: Template {0}, teleporter portal id={1} on unexpected side={2}", roomTemplate.TemplateName, portal_id, roomSide)); success = false; } break; } } return(success); }
public static MathConstants.eSignedDirection GetOpposingRoomSide( MathConstants.eSignedDirection room_side) { MathConstants.eSignedDirection opposing_room_side = MathConstants.eSignedDirection.negative_x; switch (room_side) { case MathConstants.eSignedDirection.positive_x: { opposing_room_side = MathConstants.eSignedDirection.negative_x; } break; case MathConstants.eSignedDirection.negative_x: { opposing_room_side = MathConstants.eSignedDirection.positive_x; } break; case MathConstants.eSignedDirection.positive_y: { opposing_room_side = MathConstants.eSignedDirection.negative_y; } break; case MathConstants.eSignedDirection.negative_y: { opposing_room_side = MathConstants.eSignedDirection.positive_y; } break; case MathConstants.eSignedDirection.positive_z: { opposing_room_side = MathConstants.eSignedDirection.negative_z; } break; case MathConstants.eSignedDirection.negative_z: { opposing_room_side = MathConstants.eSignedDirection.positive_z; } break; } return(opposing_room_side); }
public RoomIndex GetOpposingRoomIndex(MathConstants.eSignedDirection room_side) { RoomIndex opposingRoomIndex = null; switch (room_side) { case MathConstants.eSignedDirection.positive_x: { opposingRoomIndex = this.Offset(1, 0, 0); } break; case MathConstants.eSignedDirection.negative_x: { opposingRoomIndex = this.Offset(-1, 0, 0); } break; case MathConstants.eSignedDirection.positive_y: { opposingRoomIndex = this.Offset(0, 1, 0); } break; case MathConstants.eSignedDirection.negative_y: { opposingRoomIndex = this.Offset(0, -1, 0); } break; case MathConstants.eSignedDirection.positive_z: { opposingRoomIndex = this.Offset(0, 0, 1); } break; case MathConstants.eSignedDirection.negative_z: { opposingRoomIndex = this.Offset(0, 0, -1); } break; } return(opposingRoomIndex); }
private bool VerifyRoomPortals( DungeonLayout layout, Dictionary<int, Portal> portalIdToPortalMap) { bool success = true; MathConstants.eSignedDirection[] roomSides = new MathConstants.eSignedDirection[] { MathConstants.eSignedDirection.positive_x, MathConstants.eSignedDirection.negative_x, MathConstants.eSignedDirection.positive_y, MathConstants.eSignedDirection.negative_y, MathConstants.eSignedDirection.positive_z, MathConstants.eSignedDirection.negative_z }; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Verify the the portal bitmask matches the existing portals foreach (MathConstants.eSignedDirection roomSide in roomSides) { if (room.RoomHasPortalOnSide(roomSide)) { if (room.portals.Count(p => p.room_side == roomSide) == 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected portal on room side {0} but found none!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { if (room.portals.Count(p => p.room_side == roomSide) != 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected no portal on room side {0} but found one!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } // Verify that the portals are the right expected type foreach (Portal portal in room.portals) { MathConstants.eSignedDirection roomSide = portal.room_side; switch (portal.portal_type) { case ePortalType.door: if (roomSide != MathConstants.eSignedDirection.positive_x && roomSide != MathConstants.eSignedDirection.negative_x && roomSide != MathConstants.eSignedDirection.positive_y && roomSide != MathConstants.eSignedDirection.negative_y) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Door portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.stairs: if (roomSide != MathConstants.eSignedDirection.positive_z && roomSide != MathConstants.eSignedDirection.negative_z) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Stairs portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.teleporter: if (roomSide != MathConstants.eSignedDirection.none) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Teleporter portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; } } // Verify that the portals connect to a valid target portal foreach (Portal portal in room.portals) { if (portalIdToPortalMap.ContainsKey(portal.target_portal_id)) { Portal targetPortal = portalIdToPortalMap[portal.target_portal_id]; if (targetPortal.target_portal_id != portal.portal_id) { _logger.WriteLine("DungeonValidator: FAILED: Target Portal is not connected to a valid portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { _logger.WriteLine("DungeonValidator: FAILED: Portal is not connected to a valid target portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } return success; }
private void DumpLayoutGeometry( string dumpGeometryPath, DungeonLayout layout) { GeometryFileWriter fileWriter = new GeometryFileWriter(); string filename = string.Format("DungeonLayout_Game{0}_Size{1}", layout.GameID, layout.LayoutWorldTemplate.dungeon_size); string header = string.Format("DungeonLayout for GameID:{0} DungeonSize: {1}", layout.GameID, layout.LayoutWorldTemplate.dungeon_size); string result = SuccessMessages.GENERAL_SUCCESS; Vector3d roomSize = new Vector3d(WorldConstants.ROOM_X_SIZE, WorldConstants.ROOM_Y_SIZE, WorldConstants.ROOM_Z_SIZE); for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); AABB3d roomAABB = new AABB3d(room.world_position, room.world_position + roomSize); AABB3d shrunkRoomAABB = roomAABB.ScaleAboutCenter(0.5f); AABB3d centerAABB = roomAABB.ScaleAboutCenter(0.05f); // Add the AABB for this room fileWriter.AppendAABB(shrunkRoomAABB); // Create portal AABBs to all adjacent rooms for (MathConstants.eSignedDirection roomSide = MathConstants.eSignedDirection.first; roomSide < MathConstants.eSignedDirection.count; ++roomSide) { if (room.RoomHasPortalOnSide(roomSide)) { DungeonLayout.RoomIndex neighborRoomIndex = null; switch (roomSide) { case MathConstants.eSignedDirection.positive_x: neighborRoomIndex = roomIndex.Offset(1, 0, 0); break; case MathConstants.eSignedDirection.negative_x: neighborRoomIndex = roomIndex.Offset(-1, 0, 0); break; case MathConstants.eSignedDirection.positive_y: neighborRoomIndex = roomIndex.Offset(0, 1, 0); break; case MathConstants.eSignedDirection.negative_y: neighborRoomIndex = roomIndex.Offset(0, -1, 0); break; case MathConstants.eSignedDirection.positive_z: neighborRoomIndex = roomIndex.Offset(0, 0, 1); break; case MathConstants.eSignedDirection.negative_z: neighborRoomIndex = roomIndex.Offset(0, 0, -1); break; } Room neighborRoom = layout.GetRoomByIndex(neighborRoomIndex); AABB3d neighborRoomAABB = new AABB3d(neighborRoom.world_position, neighborRoom.world_position + roomSize); AABB3d neighborCenterAABB = neighborRoomAABB.ScaleAboutCenter(0.05f); AABB3d portalAABB = centerAABB.EncloseAABB(neighborCenterAABB); fileWriter.AppendAABB(portalAABB); } } // TODO: DumpLayoutGeometry: Color the rooms by teleporter pair } if (!fileWriter.SaveFile(dumpGeometryPath, filename, header, out result)) { _logger.WriteLine("DungeonValidator: WARNING: Failed to save layout geometry file"); _logger.WriteLine(result); } }
private bool VerifyRoomPortals( DungeonLayout layout, Dictionary <int, Portal> portalIdToPortalMap) { bool success = true; MathConstants.eSignedDirection[] roomSides = new MathConstants.eSignedDirection[] { MathConstants.eSignedDirection.positive_x, MathConstants.eSignedDirection.negative_x, MathConstants.eSignedDirection.positive_y, MathConstants.eSignedDirection.negative_y, MathConstants.eSignedDirection.positive_z, MathConstants.eSignedDirection.negative_z }; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Verify the the portal bitmask matches the existing portals foreach (MathConstants.eSignedDirection roomSide in roomSides) { if (room.RoomHasPortalOnSide(roomSide)) { if (room.portals.Count(p => p.room_side == roomSide) == 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected portal on room side {0} but found none!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { if (room.portals.Count(p => p.room_side == roomSide) != 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected no portal on room side {0} but found one!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } // Verify that the portals are the right expected type foreach (Portal portal in room.portals) { MathConstants.eSignedDirection roomSide = portal.room_side; switch (portal.portal_type) { case ePortalType.door: if (roomSide != MathConstants.eSignedDirection.positive_x && roomSide != MathConstants.eSignedDirection.negative_x && roomSide != MathConstants.eSignedDirection.positive_y && roomSide != MathConstants.eSignedDirection.negative_y) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Door portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.stairs: if (roomSide != MathConstants.eSignedDirection.positive_z && roomSide != MathConstants.eSignedDirection.negative_z) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Stairs portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.teleporter: if (roomSide != MathConstants.eSignedDirection.none) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Teleporter portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; } } // Verify that the portals connect to a valid target portal foreach (Portal portal in room.portals) { if (portalIdToPortalMap.ContainsKey(portal.target_portal_id)) { Portal targetPortal = portalIdToPortalMap[portal.target_portal_id]; if (targetPortal.target_portal_id != portal.portal_id) { _logger.WriteLine("DungeonValidator: FAILED: Target Portal is not connected to a valid portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { _logger.WriteLine("DungeonValidator: FAILED: Portal is not connected to a valid target portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } return(success); }
public void RoomFlagPortalOnSide(MathConstants.eSignedDirection side, bool flag) { portalRoomSideBitmask.Set(side, flag); }
public bool RoomHasPortalOnSide(MathConstants.eSignedDirection side) { return(portalRoomSideBitmask.Test(side)); }
private bool CreateNormalPortals(out string result) { bool success = true; result = SuccessMessages.GENERAL_SUCCESS; // Create portals in each room for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid); iterator.Valid; iterator.Next()) { RoomIndex roomIndex = iterator.Current; RoomKey roomKey = GetRoomKeyForRoomIndex(roomIndex); RoomLayout room = GetRoomByIndex(roomIndex); RoomTemplate roomTemplate = m_roomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name); foreach (PortalTemplate portalTemplate in roomTemplate.PortalTemplates) { if (portalTemplate.PortalType != ePortalType.teleporter) { Portal portal = new Portal(); portal.bounding_box = portalTemplate.BoundingBox; portal.room_side = portalTemplate.PortalRoomSide; portal.room_x = roomKey.x; portal.room_y = roomKey.y; portal.room_z = roomKey.z; portal.portal_type = portalTemplate.PortalType; // This is a temp ID for the purpose of portal connection. // A new ID will get assigned when inserting this portal into the DB. portal.portal_id = m_nextPortalId; ++m_nextPortalId; // This get sets in the next pass portal.target_portal_id = -1; room.portals.Add(portal); } } } // Connect neighboring portals for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid); success && iterator.Valid; iterator.Next()) { RoomIndex roomIndex = iterator.Current; RoomLayout room = GetRoomByIndex(roomIndex); foreach (Portal portal in room.portals) { MathConstants.eSignedDirection opposingRoomSide = RoomKey.GetOpposingRoomSide(portal.room_side); RoomIndex opposingRoomIndex = roomIndex.GetOpposingRoomIndex(portal.room_side); RoomLayout opposingRoom = GetRoomByIndex(opposingRoomIndex); Portal opposingPortal = opposingRoom.portals.Find(p => p.room_side == opposingRoomSide); if (opposingPortal != null) { portal.target_portal_id = opposingPortal.portal_id; opposingPortal.target_portal_id = portal.portal_id; } else { result = ErrorMessages.DUNGEON_LAYOUT_ERROR; success = false; break; } } } return(success); }
private void JoinAdjacentDisjointRoomSets( Dictionary <int, List <RoomIndex> > connectivityIdToRoomIndexMap) { // Look for any null room that neighboring at least two disjoint sets of rooms for (RoomIndexIterator iterator = new RoomIndexIterator(m_roomGrid, RoomIndexIterator.eIterationType.nullRooms); iterator.Valid; iterator.Next()) { RoomIndex nullRoomIndex = iterator.Current; RoomIndex[] neighboringIndices = new RoomIndex[4] { nullRoomIndex.Offset(1, 0, 0), nullRoomIndex.Offset(-1, 0, 0), nullRoomIndex.Offset(0, 1, 0), nullRoomIndex.Offset(0, -1, 0) }; MathConstants.eSignedDirection[] neighborSideFlags = new MathConstants.eSignedDirection[4] { MathConstants.eSignedDirection.positive_x, MathConstants.eSignedDirection.negative_x, MathConstants.eSignedDirection.positive_y, MathConstants.eSignedDirection.negative_y }; bool createNewRoom = false; TypedFlags <MathConstants.eSignedDirection> nullRoomNeighborFlags = new TypedFlags <MathConstants.eSignedDirection>(); int lastConnectivityId = -1; for (int side_index = 0; side_index < 4; ++side_index) { MathConstants.eSignedDirection neighborSide = neighborSideFlags[side_index]; RoomIndex neighborRoomIndex = neighboringIndices[side_index]; // See if an adjacent room exists on this side RoomLayout neighborRoom = TryGetRoomByIndex(neighborRoomIndex); if (neighborRoom != null) { // Record that a neighboring room was found in this side nullRoomNeighborFlags.Set(neighborSide, true); // See if the neighboring room is actually disjoint from a previous neighbor // we have found on another side (different connectivity_id) int roomConnectivityId = neighborRoom.connectivity_id; if (lastConnectivityId != -1 && roomConnectivityId != lastConnectivityId) { List <RoomIndex> roomSet = connectivityIdToRoomIndexMap[roomConnectivityId]; List <RoomIndex> lastRoomSet = connectivityIdToRoomIndexMap[lastConnectivityId]; // Make the connectivity ids match for rooms in both sets roomSet.ForEach(rIndex => GetRoomByIndex(rIndex).connectivity_id = lastConnectivityId); // Merge the rooms in the set into the previous set lastRoomSet.AddRange(roomSet); // Remove the set connectivityIdToRoomIndexMap.Remove(roomConnectivityId); // Since we have merged two adjacent sets we now need a new room // to bridge the disjoin sets createNewRoom = true; } // Keep track of the last valid connectivity we found for the next iteration lastConnectivityId = neighborRoom.connectivity_id; } } if (createNewRoom) { // Create a new room at the null room index location RoomLayout newRoom = new RoomLayout(GetRoomKeyForRoomIndex(nullRoomIndex)); // Record which neighbors the null room has newRoom.portalRoomSideBitmask = nullRoomNeighborFlags; // All neighbors should have the same connectivity id now // so just get the connectivity id from the last valid neighbor newRoom.connectivity_id = lastConnectivityId; // Finally store the new room in the room grid m_roomGrid[nullRoomIndex.X, nullRoomIndex.Y, nullRoomIndex.Z] = newRoom; // Add the new room to the connectivity set it's helping to bridge { List <RoomIndex> lastRoomSet = connectivityIdToRoomIndexMap[lastConnectivityId]; lastRoomSet.Add(new RoomIndex(nullRoomIndex)); } // Tell all neighboring rooms about the new room adjacent to it for (int side_index = 0; side_index < 4; ++side_index) { MathConstants.eSignedDirection neighborSide = neighborSideFlags[side_index]; RoomIndex neighborRoomIndex = neighboringIndices[side_index]; // See if an adjacent room exists on this side if (newRoom.portalRoomSideBitmask.Test(neighborSide)) { RoomLayout neighborRoom = GetRoomByIndex(neighborRoomIndex); MathConstants.eSignedDirection opposingNeighborSide = RoomKey.GetOpposingRoomSide(neighborSide); neighborRoom.RoomFlagPortalOnSide(opposingNeighborSide, true); } } } } }
public static Portal CreatePortal(Room room, MathConstants.eSignedDirection roomSide) { Portal newPortal = new Portal(); newPortal.portal_id = -1; // portal ID not set until this portal gets saved into the DB newPortal.target_portal_id = -1; newPortal.room_side = roomSide; newPortal.room_x = room.room_key.x; newPortal.room_y = room.room_key.y; newPortal.room_z = room.room_key.z; switch (roomSide) { case MathConstants.eSignedDirection.positive_x: { Point3d p1 = WorldConstants.ROOM_BOUNDS.Max; Point3d p0 = p1 - Vector3d.I * WorldConstants.PORTAL_WIDTH - Vector3d.J * WorldConstants.ROOM_Y_SIZE; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.negative_x: { Point3d p0 = WorldConstants.ROOM_BOUNDS.Min; Point3d p1 = p0 + Vector3d.I * WorldConstants.PORTAL_WIDTH + Vector3d.J * WorldConstants.ROOM_Y_SIZE; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.positive_y: { Point3d p1 = WorldConstants.ROOM_BOUNDS.Max; Point3d p0 = p1 - Vector3d.I * WorldConstants.ROOM_X_SIZE - Vector3d.J * WorldConstants.PORTAL_WIDTH; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.negative_y: { Point3d p0 = WorldConstants.ROOM_BOUNDS.Min; Point3d p1 = p0 + Vector3d.I * WorldConstants.ROOM_X_SIZE + Vector3d.J * WorldConstants.PORTAL_WIDTH; newPortal.bounding_box = new AABB3d(p0, p1); } break; case MathConstants.eSignedDirection.positive_z: case MathConstants.eSignedDirection.negative_z: { int column = RNGUtilities.RandomInt(WorldConstants.ROOM_X_TILES / 3, 2 * WorldConstants.ROOM_X_TILES / 3); int row = RNGUtilities.RandomInt(WorldConstants.ROOM_Y_TILES / 3, 2 * WorldConstants.ROOM_Y_TILES / 3); Point3d p0 = WorldConstants.GetTilePosition(column, row); Point3d p1 = p0 + Vector3d.I * WorldConstants.ROOM_TILE_SIZE + Vector3d.J * WorldConstants.ROOM_TILE_SIZE; newPortal.bounding_box = new AABB3d(p0, p1); } break; } return(newPortal); }