void Paint(Vector3 AtPosition, int id = 0) { int BrushPaintType = SelectedBrush; if (Smooth) { BrushPaintType = 2; // Smooth } int hmWidth = ScmapEditor.Current.Teren.terrainData.heightmapWidth; int hmHeight = ScmapEditor.Current.Teren.terrainData.heightmapHeight; Vector3 tempCoord = ScmapEditor.Current.Teren.gameObject.transform.InverseTransformPoint(AtPosition); Vector3 coord = Vector3.zero; coord.x = tempCoord.x / ScmapEditor.Current.Teren.terrainData.size.x; //coord.y = tempCoord.y / ScmapEditor.Current.Teren.terrainData.size.y; coord.z = tempCoord.z / ScmapEditor.Current.Teren.terrainData.size.z; if (coord.x > 1) { return; } if (coord.x < 0) { return; } if (coord.z > 1) { return; } if (coord.z < 0) { return; } // get the position of the terrain heightmap where this game object is int posXInTerrain = (int)(coord.x * hmWidth); int posYInTerrain = (int)(coord.z * hmHeight); // we set an offset so that all the raising terrain is under this game object int size = BrushSize.intValue; if (BrushPaintType == 2 && size < 8) { size = 8; } int offset = size / 2; // get the heights of the terrain under this game object // Horizontal Brush Offsets int OffsetLeft = 0; if (posXInTerrain - offset < 0) { OffsetLeft = Mathf.Abs(posXInTerrain - offset); } int OffsetRight = 0; if (posXInTerrain - offset + size > ScmapEditor.Current.Teren.terrainData.heightmapWidth) { OffsetRight = posXInTerrain - offset + size - ScmapEditor.Current.Teren.terrainData.heightmapWidth; } // Vertical Brush Offsets int OffsetDown = 0; if (posYInTerrain - offset < 0) { OffsetDown = Mathf.Abs(posYInTerrain - offset); } int OffsetTop = 0; if (posYInTerrain - offset + size > ScmapEditor.Current.Teren.terrainData.heightmapWidth) { OffsetTop = posYInTerrain - offset + size - ScmapEditor.Current.Teren.terrainData.heightmapWidth; } //float[,] heights = ScmapEditor.Current.Teren.terrainData.GetHeights(posXInTerrain - offset + OffsetLeft, posYInTerrain - offset + OffsetDown, (size - OffsetLeft) - OffsetRight, (size - OffsetDown) - OffsetTop); int GetX = posXInTerrain - offset + OffsetLeft; int GetY = posYInTerrain - offset + OffsetDown; int SizeDown = (size - OffsetDown) - OffsetTop; int SizeLeft = (size - OffsetLeft) - OffsetRight; ScmapEditor.GetValues(GetX, GetY, SizeDown, SizeLeft); float CenterHeight = 0; int i = 0; int j = 0; int x = 0; int y = 0; float SampleBrush = 0; float PixelPower = 0; if (SelectedBrush == 1) { float Count = 0; for (i = 0; i < ScmapEditor.LastGetWidth; i++) { for (j = 0; j < ScmapEditor.LastGetHeight; j++) { // Brush strength x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]); y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]); if (x < 0 || y < 0 || x >= BrushGenerator.Current.PaintImageWidths[id] || y >= BrushGenerator.Current.PaintImageHeights[id]) { continue; } SampleBrush = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageHeights[id] * x] - 0.0255f); CenterHeight += ScmapEditor.ReturnValues[i, j] * SampleBrush; Count += SampleBrush; } } CenterHeight /= Count; } else if (SelectedBrush == 3) { float Count = 0; for (i = 0; i < ScmapEditor.LastGetWidth; i++) { for (j = 0; j < ScmapEditor.LastGetHeight; j++) { // Brush strength x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]); y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]); if (x < 0 || y < 0 || x >= BrushGenerator.Current.PaintImageWidths[id] || y >= BrushGenerator.Current.PaintImageHeights[id]) { continue; } SampleBrush = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageHeights[id] * x] - 0.0255f); CenterHeight += ScmapEditor.ReturnValues[i, j] * SampleBrush; Count += SampleBrush; } } CenterHeight /= Count; } float TargetHeight = Mathf.Clamp(((Invert?(256):(BrushTarget.value)) / ScmapEditor.Current.Data.size.y) / 10f, Min, Max); float BrushStrenghtValue = BrushStrength.value; //float PaintStrength = BrushStrenghtValue * 0.00005f * (Invert ? (-1) : 1); float StrengthMultiplier = 1; switch (BrushPaintType) { case 1: // Flatten StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * 0.00008f; break; case 2: // Smooth StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * Mathf.Clamp(size / 10f, 0, 20) * 0.01f; break; case 3: // Sharp StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * 0.00008f; break; default: StrengthMultiplier = BrushGenerator.Current.HeightmapPaintStrength.Evaluate(BrushStrenghtValue) * 0.00008f * (Invert ? (-1) : 1); break; } //float SizeSmooth = Mathf.Clamp01(size / 10f) * 15; for (i = 0; i < ScmapEditor.LastGetWidth; i++) { for (j = 0; j < ScmapEditor.LastGetHeight; j++) { // Brush strength x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]); y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]); if (x < 0 || y < 0 || x >= BrushGenerator.Current.PaintImageWidths[id] || y >= BrushGenerator.Current.PaintImageHeights[id]) { continue; } SampleBrush = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageHeights[id] * x] - 0.0255f); if (SampleBrush > 0) { //if (i < 0 || j < 0 || i >= ScmapEditor.LastGetWidth || j >= ScmapEditor.LastGetHeight) // continue; switch (BrushPaintType) { case 1: // Flatten PixelPower = Mathf.Pow(Mathf.Abs(ScmapEditor.ReturnValues[i, j] - CenterHeight), 0.454545f) + 1; PixelPower /= 2f; //if (PixelPower < 0.001f) // heights[i, j] = CenterHeight; //else { //float FlattenStrenght = PixelPower * StrengthMultiplier * Mathf.Pow(SampleBrush, 2); //heights[i, j] += FlattenStrenght; ScmapEditor.ReturnValues[i, j] = MoveToValue(ScmapEditor.ReturnValues[i, j], CenterHeight, StrengthMultiplier * SampleBrush * PixelPower, 0, ScmapEditor.MaxElevation); //} break; case 2: // Smooth CenterHeight = GetNearValues(ref ScmapEditor.ReturnValues, i, j); PixelPower = Mathf.Pow(Mathf.Abs(ScmapEditor.ReturnValues[i, j] - CenterHeight), 0.454545f) + 1; PixelPower /= 2f; //PixelPower = 10; //heights[i, j] = Mathf.Lerp(heights[i, j], CenterHeight, BrushStrenghtValue * Mathf.Pow(SampleBrush, 2) * PixelPower); ScmapEditor.ReturnValues[i, j] = Mathf.Lerp(ScmapEditor.ReturnValues[i, j], CenterHeight, PixelPower * StrengthMultiplier * Mathf.Pow(SampleBrush, 2)); break; case 3: // Sharp PixelPower = Mathf.Pow(Mathf.Abs(ScmapEditor.ReturnValues[i, j] - CenterHeight), 0.454545f) + 1; PixelPower /= 2f; //heights[i, j] += Mathf.Lerp(PixelPower, 0, PixelPower * 10) * BrushStrenghtValue * 0.01f * Mathf.Pow(SampleBrush, 2); ScmapEditor.ReturnValues[i, j] = MoveToValue(ScmapEditor.ReturnValues[i, j], CenterHeight, -StrengthMultiplier * SampleBrush * PixelPower, Min, Max); break; default: //heights[i, j] += SampleBrush * StrengthMultiplier; ScmapEditor.ReturnValues[i, j] = MoveToValue(ScmapEditor.ReturnValues[i, j], TargetHeight, SampleBrush * StrengthMultiplier, Min, Max); break; } } } } // set the new height if (!TerainChanged) { ScmapEditor.GetAllHeights(ref beginHeights); TerainChanged = true; } //ScmapEditor.Current.Teren.terrainData.SetHeightsDelayLOD(posXInTerrain - offset + OffsetLeft, posYInTerrain - offset + OffsetDown, heights); ScmapEditor.ApplyChanges(GetX, GetY); //Markers.MarkersControler.UpdateMarkersHeights(); OnTerrainChanged(); }