Further improve terrain painting logic #1739r
This commit is contained in:
@@ -209,8 +209,7 @@ namespace FlaxEditor.Tools.Terrain.Paint
|
||||
public int SplatmapIndex;
|
||||
|
||||
/// <summary>
|
||||
/// The splatmap texture index. If <see cref="SplatmapIndex"/> is 0, this will be 1.
|
||||
/// If <see cref="SplatmapIndex"/> is 1, this will be 0.
|
||||
/// The splatmap texture index. If <see cref="SplatmapIndex"/> is 0, this will be 1. If <see cref="SplatmapIndex"/> is 1, this will be 0.
|
||||
/// </summary>
|
||||
public int SplatmapIndexOther;
|
||||
|
||||
@@ -220,8 +219,7 @@ namespace FlaxEditor.Tools.Terrain.Paint
|
||||
public Color32* TempBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// The 'other" temporary data buffer (for modified data). If <see cref="TempBuffer"/> refers
|
||||
/// to the splatmap with index 0, this one will refer to the one with index 1.
|
||||
/// The 'other' temporary data buffer (for modified data). If <see cref="TempBuffer"/> refersto the splatmap with index 0, this one will refer to the one with index 1.
|
||||
/// </summary>
|
||||
public Color32* TempBufferOther;
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace FlaxEditor.Tools.Terrain.Paint
|
||||
|
||||
// Apply brush modification
|
||||
Profiler.BeginEvent("Apply Brush");
|
||||
bool otherModified = false;
|
||||
for (int z = 0; z < p.ModifiedSize.Y; z++)
|
||||
{
|
||||
var zz = z + p.ModifiedOffset.Y;
|
||||
@@ -86,34 +87,38 @@ namespace FlaxEditor.Tools.Terrain.Paint
|
||||
|
||||
var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, 0, zz * FlaxEngine.Terrain.UnitsPerVertex);
|
||||
Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld);
|
||||
var sample = Mathf.Saturate(p.Brush.Sample(ref brushPosition, ref samplePositionWorld));
|
||||
|
||||
var paintAmount = sample * strength;
|
||||
if (paintAmount < 0.0f)
|
||||
continue; // Skip when pixel won't be affected
|
||||
|
||||
var sample = Mathf.Clamp(p.Brush.Sample(ref brushPosition, ref samplePositionWorld), 0f, 1f);
|
||||
var paintAmount = sample * strength * (1f - src[c]);
|
||||
|
||||
// Paint on the active splatmap texture
|
||||
src[c] = Mathf.Clamp(src[c] + paintAmount, 0, 1f);
|
||||
src[(c + 1) % 4] = Mathf.Clamp(src[(c + 1) % 4] - paintAmount, 0, 1f);
|
||||
src[(c + 2) % 4] = Mathf.Clamp(src[(c + 2) % 4] - paintAmount, 0, 1f);
|
||||
src[(c + 3) % 4] = Mathf.Clamp(src[(c + 3) % 4] - paintAmount, 0, 1f);
|
||||
|
||||
src[c] = Mathf.Saturate(src[c] + paintAmount);
|
||||
src[(c + 1) % 4] = Mathf.Saturate(src[(c + 1) % 4] - paintAmount);
|
||||
src[(c + 2) % 4] = Mathf.Saturate(src[(c + 2) % 4] - paintAmount);
|
||||
src[(c + 3) % 4] = Mathf.Saturate(src[(c + 3) % 4] - paintAmount);
|
||||
p.TempBuffer[z * p.ModifiedSize.X + x] = src;
|
||||
|
||||
// Remove 'paint' from the other splatmap texture
|
||||
var other = (Color)p.SourceDataOther[zz * p.HeightmapSize + xx];
|
||||
|
||||
other[c] = Mathf.Clamp(other[c] - paintAmount, 0, 1f);
|
||||
other[(c + 1) % 4] = Mathf.Clamp(other[(c + 1) % 4] - paintAmount, 0, 1f);
|
||||
other[(c + 2) % 4] = Mathf.Clamp(other[(c + 2) % 4] - paintAmount, 0, 1f);
|
||||
other[(c + 3) % 4] = Mathf.Clamp(other[(c + 3) % 4] - paintAmount, 0, 1f);
|
||||
|
||||
p.TempBufferOther[z * p.ModifiedSize.X + x] = other;
|
||||
//if (other.ValuesSum > 0.0f) // Skip editing the other splatmap if it's empty
|
||||
{
|
||||
// Remove 'paint' from the other splatmap texture
|
||||
other[c] = Mathf.Saturate(other[c] - paintAmount);
|
||||
other[(c + 1) % 4] = Mathf.Saturate(other[(c + 1) % 4] - paintAmount);
|
||||
other[(c + 2) % 4] = Mathf.Saturate(other[(c + 2) % 4] - paintAmount);
|
||||
other[(c + 3) % 4] = Mathf.Saturate(other[(c + 3) % 4] - paintAmount);
|
||||
p.TempBufferOther[z * p.ModifiedSize.X + x] = other;
|
||||
otherModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Profiler.EndEvent();
|
||||
|
||||
// Update terrain patch
|
||||
TerrainTools.ModifySplatMap(p.Terrain, ref p.PatchCoord, p.SplatmapIndex, p.TempBuffer, ref p.ModifiedOffset, ref p.ModifiedSize);
|
||||
TerrainTools.ModifySplatMap(p.Terrain, ref p.PatchCoord, p.SplatmapIndexOther, p.TempBufferOther, ref p.ModifiedOffset, ref p.ModifiedSize);
|
||||
if (otherModified)
|
||||
TerrainTools.ModifySplatMap(p.Terrain, ref p.PatchCoord, p.SplatmapIndexOther, p.TempBufferOther, ref p.ModifiedOffset, ref p.ModifiedSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,21 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
public float MaxColorComponent => Mathf.Max(Mathf.Max(R, G), B);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a minimum component value (max of r,g,b,a).
|
||||
/// </summary>
|
||||
public float MinValue => Math.Min(R, Math.Min(G, Math.Min(B, A)));
|
||||
|
||||
/// <summary>
|
||||
/// Gets a maximum component value (min of r,g,b,a).
|
||||
/// </summary>
|
||||
public float MaxValue => Math.Max(R, Math.Max(G, Math.Max(B, A)));
|
||||
|
||||
/// <summary>
|
||||
/// Gets a sum of the component values.
|
||||
/// </summary>
|
||||
public float ValuesSum => R + G + B + A;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Color with given r,g,b,a component.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user