internal static IEnumerable <Prim> LoadPrims(string rdbConnectionString, Guid regionId) { using (var conn = DBHelpers.GetConnection(rdbConnectionString)) { if (conn == null) { LOG.Warn($"Could not get connection to DB for region '{regionId}'."); return(null); } using (var cmd = conn.CreateCommand()) { cmd.CommandText = @"SELECT pr.UUID, pr.SceneGroupID, pr.LinkNumber, pr.Name, pr.ObjectFlags, ps.State, pr.PositionX, pr.PositionY, pr.PositionZ, pr.GroupPositionX, pr.GroupPositionY, pr.GroupPositionZ, ps.ScaleX, ps.ScaleY, ps.ScaleZ, pr.RotationX, pr.RotationY, pr.RotationZ, pr.RotationW, ps.Texture FROM prims pr INNER JOIN primshapes ps USING (UUID) WHERE pr.GroupPositionZ < 766 /* = max terrain height (510) + render height (256) */ AND LENGTH(ps.Texture) > 0 AND pr.ObjectFlags & (0 | 0x40000 | 0x20000) = 0 AND ps.ScaleX > 1.0 AND ps.ScaleY > 1.0 AND ps.ScaleZ > 1.0 AND ps.PCode NOT IN (255, 111, 95) AND RegionUUID = @region_id ORDER BY GroupPositionZ, PositionZ " ; cmd.Parameters.AddWithValue("region_id", regionId); cmd.CommandTimeout = 600; cmd.Prepare(); IDataReader reader = null; try { reader = DBHelpers.ExecuteReader(cmd); } catch (Exception e) { LOG.Warn($"Prims DB reader query threw an error when attempting to get prims for region '{regionId}'.", e); } if (reader == null) { LOG.Warn($"Prims DB reader query returned nothing for region '{regionId}'."); return(null); } var prims = new List <Prim>(); // List was chosen because it guarantees that insertion order will be preserved unless explictly sorted. var rootPrims = new Dictionary <Guid, Prim>(); var childPrims = new List <Prim>(); // List was chosen because it guarantees that insertion order will be preserved unless explictly sorted. try { while (reader.Read()) { // Nullables start here var groupPosX = RDBMap.GetDBValueOrNull <double>(reader, "GroupPositionX"); var groupPosY = RDBMap.GetDBValueOrNull <double>(reader, "GroupPositionY"); var groupPosZ = RDBMap.GetDBValueOrNull <double>(reader, "GroupPositionZ"); var posX = RDBMap.GetDBValueOrNull <double>(reader, "PositionX"); var posY = RDBMap.GetDBValueOrNull <double>(reader, "PositionY"); var posZ = RDBMap.GetDBValueOrNull <double>(reader, "PositionZ"); var rotW = RDBMap.GetDBValueOrNull <double>(reader, "RotationW"); var rotX = RDBMap.GetDBValueOrNull <double>(reader, "RotationX"); var rotY = RDBMap.GetDBValueOrNull <double>(reader, "RotationY"); var rotZ = RDBMap.GetDBValueOrNull <double>(reader, "RotationZ"); var prim = new Prim { GroupPosition = groupPosX != null && groupPosY != null && groupPosZ != null ? new Vector3( (float)groupPosX, (float)groupPosY, (float)groupPosZ ) : (Vector3?)null, Id = Guid.Parse(RDBMap.GetDBValue(reader, "UUID")), Name = RDBMap.GetDBValue(reader, "Name"), ObjectFlags = RDBMap.GetDBValue <int>(reader, "ObjectFlags"), Position = posX != null && posY != null && posZ != null ? new Vector3( (float)posX, (float)posY, (float)posZ ) : (Vector3?)null, RegionId = regionId, RootRotation = null, Rotation = rotW != null && rotX != null && rotY != null && rotZ != null ? new Quaternion( (float)rotX, (float)rotY, (float)rotZ, (float)rotW ) : (Quaternion?)null, Scale = new Vector3( (float)RDBMap.GetDBValue <double>(reader, "ScaleX"), (float)RDBMap.GetDBValue <double>(reader, "ScaleY"), (float)RDBMap.GetDBValue <double>(reader, "ScaleZ") ), State = RDBMap.GetDBValue <int>(reader, "State"), Texture = (byte[])reader["Texture"], }; prims.Add(prim); var sogIdStr = RDBMap.GetDBValue(reader, "SceneGroupID"); if (Guid.TryParse(sogIdStr, out var sogId)) { prim.SceneGroupId = sogId; var linkNumber = RDBMap.GetDBValue <int>(reader, "LinkNumber"); if (linkNumber == 1) { rootPrims.Add(sogId, prim); } else if (linkNumber > 1) { childPrims.Add(prim); } } } } finally { reader.Close(); } foreach (var prim in childPrims) { if (rootPrims.TryGetValue(prim.SceneGroupId, out var rootPrim)) { prim.RootRotation = rootPrim.Rotation; } } return(prims); } } }
public bool Update() { using (var conn = DBHelpers.GetConnection(_rdbConnectionString)) { if (conn == null) { LOG.Warn($"Could not get connection to DB for region '{_regionId}'."); return(false); } using (var cmd = conn.CreateCommand()) { cmd.CommandText = @"SELECT terrain_texture_1, terrain_texture_2, terrain_texture_3, terrain_texture_4, elevation_1_nw, elevation_2_nw, elevation_1_ne, elevation_2_ne, elevation_1_sw, elevation_2_sw, elevation_1_se, elevation_2_se, water_height, Heightfield FROM regionsettings NATURAL JOIN terrain WHERE RegionUUID = @region_id " ; cmd.Parameters.AddWithValue("region_id", _regionId.ToString()); cmd.Prepare(); IDataReader reader = null; try { reader = DBHelpers.ExecuteReader(cmd); } catch (Exception e) { LOG.Warn($"Prims query DB reader threw an error when attempting to get prims for region '{_regionId}'.", e); } if (reader == null) { LOG.Warn($"Terrain DB reader query returned nothing for region '{_regionId}'."); return(false); } try { reader.Read(); TerrainTexture1 = Guid.Parse(RDBMap.GetDBValue(reader, "terrain_texture_1")); TerrainTexture2 = Guid.Parse(RDBMap.GetDBValue(reader, "terrain_texture_2")); TerrainTexture3 = Guid.Parse(RDBMap.GetDBValue(reader, "terrain_texture_3")); TerrainTexture4 = Guid.Parse(RDBMap.GetDBValue(reader, "terrain_texture_4")); ElevationNWLow = RDBMap.GetDBValue <double>(reader, "elevation_1_nw"); ElevationNWHigh = RDBMap.GetDBValue <double>(reader, "elevation_2_nw"); ElevationNELow = RDBMap.GetDBValue <double>(reader, "elevation_1_ne"); ElevationNEHigh = RDBMap.GetDBValue <double>(reader, "elevation_2_ne"); ElevationSWLow = RDBMap.GetDBValue <double>(reader, "elevation_1_sw"); ElevationSWHigh = RDBMap.GetDBValue <double>(reader, "elevation_2_sw"); ElevationSELow = RDBMap.GetDBValue <double>(reader, "elevation_1_se"); ElevationSEHigh = RDBMap.GetDBValue <double>(reader, "elevation_2_se"); WaterHeight = RDBMap.GetDBValue <double>(reader, "water_height"); _heightmap.Initialize(); var minHeightFound = 510.0; // Max terrain height var br = new BinaryReader(new MemoryStream((byte[])reader["Heightfield"])); for (int x = 0; x < _heightmap.GetLength(0); x++) { for (int y = 0; y < _heightmap.GetLength(1); y++) { var height = br.ReadDouble(); _heightmap[x, y] = height; if (height < minHeightFound) { minHeightFound = height; } } } TerrainHeightMin = minHeightFound; } finally { reader.Close(); } } } return(true); }