public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x; for (x = 0; x < map.Width; x++) { int y; for (y = 0; y < map.Height; y++) { if (!mask[x, y]) { continue; } // Calculate a sphere and add it to the heighmap double z = strength; z *= z; z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); double noise = TerrainUtil.PerlinNoise2D(x / (double)map.Width, y / (double)map.Height, 8, 1.0); if (z > 0.0) { map[x, y] += noise * z * duration; } } } }
public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength, float duration, float BrushSize, List <IScene> scene) { if (m_module == null) { return; } strength = TerrainUtil.MetersToSphericalStrength(BrushSize); duration = 0.03f; //MCP Should be read from ini file if (duration > 1.0) { duration = 1; } if (duration < 0) { return; } int n = (int)(BrushSize + 0.5f); int zx = (int)(rx + 0.5); int zy = (int)(ry + 0.5); int dx; for (dx = -n; dx <= n; dx++) { int dy; for (dy = -n; dy <= n; dy++) { int x = zx + dx; int y = zy + dy; if (x >= 0 && y >= 0 && x < map.Width && y < map.Height) { if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0))) { continue; } // Calculate a sphere and add it to the heighmap float z = 0; if (duration < 4.0) { z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration * 0.25f; } if (z > 0.0) { float s = strength * 0.025f; map[x, y] = (map[x, y] * (1 - s)) + (m_module.TerrainRevertMap[x, y] * s); } } } } }
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration, int startX, int endX, int startY, int endY) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x, y; // blend in map for (x = startX; x <= endX; x++) { for (y = startY; y <= endY; y++) { if (!mask[x, y]) { continue; } double z; if (duration < 4.0) { z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration * 0.25; } else { z = 1.0; } double delta = rz - map[x, y]; if (Math.Abs(delta) > 0.1) { if (z > 1.0) { z = 1.0; } else if (z < 0.0) { z = 0.0; } delta *= z; } if (delta != 0) // add in non-zero amount { map[x, y] += delta; } } } }
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) { strength = TerrainUtil.MetersToSphericalStrength(strength); duration = 0.03; //MCP Should be read from ini file if (duration > 1.0) { duration = 1.0; } if (duration < 0) { return; } int x; for (x = 0; x < map.Width; x++) { int y; for (y = 0; y < map.Height; y++) { if (!mask[x, y]) { continue; } // Calculate a sphere and add it to the heighmap double z = strength; z *= z; z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); if (z > 0.0) { z *= duration; map[x, y] = (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z); } } } }
public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength, float duration, float BrushSize, Scene scene) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x; for (x = 0; x < map.Width; x++) { int y; for (y = 0; y < map.Height; y++) { if (!scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0))) { continue; } double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); if (z > 0) // add in non-zero amount { const int NEIGHBOUR_ME = 4; const int NEIGHBOUR_MAX = 9; for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } double heightF = map[x, y]; double target = map[coords[0], coords[1]]; if (target > heightF + talus) { double calc = duration * ((target - heightF) - talus) * z; heightF += calc; target -= calc; } map[x, y] = heightF; map[coords[0], coords[1]] = target; } } } } } }
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x; for (x = 0; x < map.Width; x++) { int y; for (y = 0; y < map.Height; y++) { if (!mask[x, y]) { continue; } double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); if (z > 0) // add in non-zero amount { const int NEIGHBOUR_ME = 4; const int NEIGHBOUR_MAX = 9; double max = Double.MinValue; int loc = 0; for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } double cellmax = map[x, y] - map[coords[0], coords[1]]; if (cellmax > max) { max = cellmax; loc = j; } } } double T = nConst / ((map.Width + map.Height) / 2.0); // Apply results if (0 < max && max <= T) { int[] maxCoords = Neighbours(type, loc); double heightDelta = 0.5 * max * z * duration; map[x, y] -= heightDelta; map[x + maxCoords[0], y + maxCoords[1]] += heightDelta; } } } } }
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x, y; // Using one 'rain' round for this, so skipping a useless loop // Will need to adapt back in for the Flood brush ITerrainChannel water = new TerrainChannel(map.Width, map.Height); ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height); // Fill with rain for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration); } } for (int i = 0; i < rounds; i++) { // Erode underlying terrain for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { if (mask[x, y]) { const double solConst = (1.0 / rounds); double sedDelta = water[x, y] * solConst; map[x, y] -= sedDelta; sediment[x, y] += sedDelta; } } } // Move water for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { if (water[x, y] <= 0) { continue; } // Step 1. Calculate average of neighbours int neighbours = 0; double altitudeTotal = 0.0; double altitudeMe = map[x, y] + water[x, y]; const int NEIGHBOUR_ME = 4; const int NEIGHBOUR_MAX = 9; for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } // Calculate total height of this neighbour double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]]; // If it's greater than me... if (altitudeNeighbour - altitudeMe < 0) { // Add it to our calculations neighbours++; altitudeTotal += altitudeNeighbour; } } } if (neighbours == 0) { continue; } double altitudeAvg = altitudeTotal / neighbours; // Step 2. Allocate water to neighbours. for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } // Skip if we dont have water to begin with. if (water[x, y] < 0) { continue; } // Calculate our delta average double altitudeDelta = altitudeMe - altitudeAvg; if (altitudeDelta < 0) { continue; } // Calculate how much water we can move double waterMin = Math.Min(water[x, y], altitudeDelta); double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]]) / altitudeTotal); double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]); if (sedimentDelta > 0) { sediment[x, y] -= sedimentDelta; sediment[coords[0], coords[1]] += sedimentDelta; } } } } } // Evaporate for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { water[x, y] *= 1.0 - (rainHeight / rounds); double waterCapacity = waterSaturation * water[x, y]; double sedimentDeposit = sediment[x, y] - waterCapacity; if (sedimentDeposit > 0) { if (mask[x, y]) { sediment[x, y] -= sedimentDeposit; map[x, y] += sedimentDeposit; } } } } } // Deposit any remainder (should be minimal) for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { if (mask[x, y] && sediment[x, y] > 0) { map[x, y] += sediment[x, y]; } } } }
public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength, float duration, float BrushSize) { strength = TerrainUtil.MetersToSphericalStrength(BrushSize); int x, y; int xFrom = (int)(rx - BrushSize + 0.5); int xTo = (int)(rx + BrushSize + 0.5) + 1; int yFrom = (int)(ry - BrushSize + 0.5); int yTo = (int)(ry + BrushSize + 0.5) + 1; if (xFrom < 0) { xFrom = 0; } if (yFrom < 0) { yFrom = 0; } if (xTo > map.Width) { xTo = map.Width; } if (yTo > map.Height) { yTo = map.Height; } // blend in map for (x = xFrom; x < xTo; x++) { for (y = yFrom; y < yTo; y++) { if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0))) { continue; } float z; if (duration < 4.0) { z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration * 0.25f; } else { z = 1; } float delta = rz - map[x, y]; if (Math.Abs(delta) > 0.1) { if (z > 1) { z = 1; } else if (z < 0) { z = 0; } delta *= z; } if (delta != 0) // add in non-zero amount { map[x, y] += delta; } } } }
public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength, float duration, float BrushSize) { int n = (int)(BrushSize + 0.5f); if (BrushSize > 6) //If it gets too high, it will start roughening at an ever increasing rate when held down { BrushSize = 6; } strength = TerrainUtil.MetersToSphericalStrength(BrushSize); float area = BrushSize; float step = BrushSize / 4; duration *= 0.01f; //MCP Should be read from ini file int zx = (int)(rx + 0.5); int zy = (int)(ry + 0.5); float average = 0; int avgsteps = 0; float nn; for (nn = 0 - area; nn < area; nn += step) { float l; for (l = 0 - area; l < area; l += step) { avgsteps++; average += TerrainUtil.GetBilinearInterpolate(rx + nn, ry + l, map); } } int dx; for (dx = -n; dx <= n; dx++) { int dy; for (dy = -n; dy <= n; dy++) { int x = zx + dx; int y = zy + dy; if (x >= 0 && y >= 0 && x < map.Width && y < map.Height) { if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0))) { continue; } float z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) / (strength); if (z > 0) // add in non-zero amount { float avg; if (avgsteps > 0) { avg = average / avgsteps; } else { avg = 0f; } float a = (map [x, y] - avg); float newz = map [x, y] + (a * duration); if (newz > 0.0) { map [x, y] = newz; } } } } } }
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x; for (x = 0; x < map.Width; x++) { int y; for (y = 0; y < map.Height; y++) { if (!mask[x, y]) { continue; } double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); if (z > 0) // add in non-zero amount { const int NEIGHBOUR_ME = 4; const int NEIGHBOUR_MAX = 9; for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } double heightF = map[x, y]; double target = map[coords[0], coords[1]]; if (target > heightF + talus) { double calc = duration * ((target - heightF) - talus) * z; heightF += calc; target -= calc; } map[x, y] = heightF; map[coords[0], coords[1]] = target; } } } } } }
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration, int startX, int endX, int startY, int endY) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x, y; double[,] tweak = new double[map.Width, map.Height]; double area = strength; double step = strength / 4.0; duration = 0.03; //MCP Should be read from ini file // compute delta map for (x = startX; x <= endX; x++) { for (y = startY; y <= endY; y++) { if (!mask[x, y]) { continue; } double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); if (z > 0) // add in non-zero amount { double average = 0.0; int avgsteps = 0; double n; for (n = 0.0 - area; n < area; n += step) { double l; for (l = 0.0 - area; l < area; l += step) { avgsteps++; average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map); } } tweak[x, y] = average / avgsteps; } } } // blend in map for (x = startX; x <= endX; x++) { for (y = startY; y <= endY; y++) { if (!mask[x, y]) { continue; } double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); if (z > 0) // add in non-zero amount { double da = z; double a = (map[x, y] - tweak[x, y]) * da; double newz = map[x, y] - (a * duration); if (newz > 0.0) { map[x, y] = newz; } } } } }
public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength, float duration, float BrushSize, List <Scene> scene) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x, y; // Using one 'rain' round for this, so skipping a useless loop // Will need to adapt back in for the Flood brush ITerrainChannel water = new TerrainChannel(map.Width, map.Height, null); ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height, null); // Fill with rain for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { water[x, y] = (float)Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration); } } for (int i = 0; i < rounds; i++) { // Erode underlying terrain for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { const float solConst = (1.0f / rounds); float sedDelta = water[x, y] * solConst; map[x, y] -= sedDelta; sediment[x, y] += sedDelta; } } // Move water for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { if (water[x, y] <= 0) { continue; } // Step 1. Calculate average of neighbours int neighbours = 0; float altitudeTotal = 0.0f; float altitudeMe = map[x, y] + water[x, y]; const int NEIGHBOUR_ME = 4; const int NEIGHBOUR_MAX = 9; for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } // Calculate total height of this neighbour float altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]]; // If it's greater than me... if (altitudeNeighbour - altitudeMe < 0) { // Add it to our calculations neighbours++; altitudeTotal += altitudeNeighbour; } } } if (neighbours == 0) { continue; } float altitudeAvg = altitudeTotal / neighbours; // Step 2. Allocate water to neighbours. for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } // Skip if we dont have water to begin with. if (water[x, y] < 0) { continue; } // Calculate our delta average float altitudeDelta = altitudeMe - altitudeAvg; if (altitudeDelta < 0) { continue; } // Calculate how much water we can move float waterMin = Math.Min(water[x, y], altitudeDelta); float waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]]) / altitudeTotal); float sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]); if (sedimentDelta > 0) { sediment[x, y] -= sedimentDelta; sediment[coords[0], coords[1]] += sedimentDelta; } } } } } // Evaporate for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { water[x, y] *= 1.0f - (rainHeight / rounds); float waterCapacity = waterSaturation * water[x, y]; float sedimentDeposit = sediment[x, y] - waterCapacity; if (sedimentDeposit > 0) { sediment[x, y] -= sedimentDeposit; map[x, y] += sedimentDeposit; } } } } // Deposit any remainder (should be minimal) for (x = 0; x < water.Width; x++) { for (y = 0; y < water.Height; y++) { if (!((Scene)map.Scene).Permissions.CanTerraformLand(userID, new Vector3(rx + x, ry + y, 0))) { continue; } if (sediment[x, y] > 0) { map[(int)rx + x, (int)ry + y] += sediment[x, y]; } } } }
public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength, float duration, float BrushSize) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x; int xFrom = (int)(rx - BrushSize + 0.5); int xTo = (int)(rx + BrushSize + 0.5) + 1; int yFrom = (int)(ry - BrushSize + 0.5); int yTo = (int)(ry + BrushSize + 0.5) + 1; if (xFrom < 0) { xFrom = 0; } if (yFrom < 0) { yFrom = 0; } if (xTo > map.Width) { xTo = map.Width; } if (yTo > map.Height) { yTo = map.Height; } for (x = xFrom; x < xTo; x++) { int y; for (y = yFrom; y < yTo; y++) { if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0))) { continue; } float z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); if (z > 0) // add in non-zero amount { const int NEIGHBOUR_ME = 4; const int NEIGHBOUR_MAX = 9; float max = float.MinValue; int loc = 0; for (int j = 0; j < NEIGHBOUR_MAX; j++) { if (j != NEIGHBOUR_ME) { int[] coords = Neighbours(type, j); coords[0] += x; coords[1] += y; if (coords[0] > map.Width - 1) { continue; } if (coords[1] > map.Height - 1) { continue; } if (coords[0] < 0) { continue; } if (coords[1] < 0) { continue; } float cellmax = map[x, y] - map[coords[0], coords[1]]; if (cellmax > max) { max = cellmax; loc = j; } } } float T = nConst / ((map.Width + map.Height) / 2); // Apply results if (0 < max && max <= T) { int[] maxCoords = Neighbours(type, loc); float heightDelta = 0.5f * max * z * duration; map[x, y] -= heightDelta; map[x + maxCoords[0], y + maxCoords[1]] += heightDelta; } } } } }
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) { strength = TerrainUtil.MetersToSphericalStrength(strength); int x, y; if (rz < 0) { double sum = 0.0; double step2 = 0.0; duration = 0.009; //MCP Should be read from ini file // compute delta map for (x = 0; x < map.Width; x++) { for (y = 0; y < map.Height; y++) { double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); if (z > 0) // add in non-zero amount { sum += map[x, y] * z; step2 += z; } } } rz = sum / step2; } // blend in map for (x = 0; x < map.Width; x++) { for (y = 0; y < map.Height; y++) { if (!mask[x, y]) { continue; } double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration; if (z > 0) // add in non-zero amount { if (z > 1.0) { z = 1.0; } map[x, y] = (map[x, y] * (1.0 - z)) + (rz * z); } double delta = rz - map[x, y]; if (Math.Abs(delta) > 0.1) { delta *= 0.25; } if (delta != 0) // add in non-zero amount { map[x, y] += delta; } } } }
public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength, float duration, float BrushSize, List <IScene> scene) { if (locked) { return; } locked = true; strength = TerrainUtil.MetersToSphericalStrength(BrushSize); int x, y; int xFrom = (int)(rx - BrushSize + 0.5); int xTo = (int)(rx + BrushSize + 0.5) + 1; int yFrom = (int)(ry - BrushSize + 0.5); int yTo = (int)(ry + BrushSize + 0.5) + 1; if (xFrom < 0) { xFrom = 0; } if (yFrom < 0) { yFrom = 0; } if (xTo > map.Width) { xTo = map.Width; } if (yTo > map.Height) { yTo = map.Height; } //ONLY get cached assets, since this is a local asset ONLY AssetBase paintAsset = map.Scene.AssetService.Get(map.Scene.RegionInfo.RegionSettings.PaintableTerrainTexture.ToString()); if (paintAsset == null) { paintAsset = new AssetBase(map.Scene.RegionInfo.RegionSettings.PaintableTerrainTexture, "PaintableTerrainTexture-" + map.Scene.RegionInfo.RegionID, AssetType.Texture, UUID.Zero) { Flags = AssetFlags.Deletable }; AssetBase defaultTexture = map.Scene.AssetService.Get(RegionSettings.DEFAULT_TERRAIN_TEXTURE_2.ToString()); //Nice grass if (defaultTexture == null) { //Erm... what to do! return; } paintAsset.Data = defaultTexture.Data; //Eventually we need to replace this with an interpolation of the existing textures! } AssetBase textureToApply = map.Scene.AssetService.Get(m_textureToPaint.ToString()); //The texture the client wants to paint if (textureToApply == null) { return; } Image paintiTexture = map.Scene.RequestModuleInterface <IJ2KDecoder>().DecodeToImage(paintAsset.Data); if (paintiTexture == null) { return; } Image textureToAddiTexture = map.Scene.RequestModuleInterface <IJ2KDecoder>().DecodeToImage(textureToApply.Data); if (textureToAddiTexture == null) { paintiTexture.Dispose(); return; } FastBitmap paintTexture = new FastBitmap((Bitmap)paintiTexture); FastBitmap textureToAddTexture = new FastBitmap((Bitmap)textureToAddiTexture); paintTexture.LockBitmap(); textureToAddTexture.LockBitmap(); // blend in map for (x = xFrom; x < xTo; x++) { for (y = yFrom; y < yTo; y++) { if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0))) { continue; } Color c = textureToAddTexture.GetPixel( (int)((x / (float)map.Scene.RegionInfo.RegionSizeX * textureToAddiTexture.Width)), (int)((y / (float)map.Scene.RegionInfo.RegionSizeX) * textureToAddiTexture.Height)); paintTexture.SetPixel((int)((x / (float)map.Scene.RegionInfo.RegionSizeX) * paintiTexture.Width), (int)((y / (float)map.Scene.RegionInfo.RegionSizeX) * paintiTexture.Height), c); } } map.Scene.AssetService.Delete(paintAsset.ID); paintTexture.UnlockBitmap(); textureToAddTexture.UnlockBitmap(); paintAsset.Data = OpenJPEG.EncodeFromImage(paintTexture.Bitmap(), false); paintAsset.Flags = AssetFlags.Deletable; map.Scene.RegionInfo.RegionSettings.PaintableTerrainTexture = UUID.Random(); paintAsset.ID = map.Scene.RegionInfo.RegionSettings.PaintableTerrainTexture; paintAsset.ID = map.Scene.AssetService.Store(paintAsset); map.Scene.RequestModuleInterface <IEstateModule>().sendRegionHandshakeToAll(); locked = false; }