示例#1
0
        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);
                }
            }
        }
示例#2
0
        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);
        }