Update Terrain scripting API
This commit is contained in:
@@ -61,6 +61,7 @@ public class Editor : EditorModule
|
||||
options.PrivateDependencies.Add("Renderer");
|
||||
options.PrivateDependencies.Add("TextureTool");
|
||||
options.PrivateDependencies.Add("Particles");
|
||||
options.PrivateDependencies.Add("Terrain");
|
||||
|
||||
var platformToolsRoot = Path.Combine(FolderPath, "Cooker", "Platform");
|
||||
var platformToolsRootExternal = Path.Combine(Globals.EngineRoot, "Source", "Platforms");
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace FlaxEditor.Tools.Terrain
|
||||
if (!terrain.HasPatch(ref patchCoord) && _planeModel)
|
||||
{
|
||||
var planeSize = 100.0f;
|
||||
var patchSize = terrain.ChunkSize * FlaxEngine.Terrain.UnitsPerVertex * FlaxEngine.Terrain.PatchEdgeChunksCount;
|
||||
var patchSize = terrain.PatchSize;
|
||||
Matrix world = Matrix.RotationX(-Mathf.PiOverTwo) *
|
||||
Matrix.Scaling(patchSize / planeSize) *
|
||||
Matrix.Translation(patchSize * (0.5f + patchCoord.X), 0, patchSize * (0.5f + patchCoord.Y)) *
|
||||
|
||||
@@ -69,9 +69,9 @@ namespace FlaxEditor.Tools.Terrain.Paint
|
||||
var splatmapIndex = ActiveSplatmapIndex;
|
||||
var splatmapIndexOther = (splatmapIndex + 1) % 2;
|
||||
var chunkSize = terrain.ChunkSize;
|
||||
var heightmapSize = chunkSize * FlaxEngine.Terrain.PatchEdgeChunksCount + 1;
|
||||
var heightmapSize = terrain.HeightmapSize;
|
||||
var heightmapLength = heightmapSize * heightmapSize;
|
||||
var patchSize = chunkSize * FlaxEngine.Terrain.UnitsPerVertex * FlaxEngine.Terrain.PatchEdgeChunksCount;
|
||||
var patchSize = terrain.PatchSize;
|
||||
var tempBuffer = (Color32*)gizmo.GetSplatmapTempBuffer(heightmapLength * Color32.SizeInBytes, splatmapIndex).ToPointer();
|
||||
var tempBufferOther = (Color32*)gizmo.GetSplatmapTempBuffer(heightmapLength * Color32.SizeInBytes, (splatmapIndex + 1) % 2).ToPointer();
|
||||
var unitsPerVertexInv = 1.0f / FlaxEngine.Terrain.UnitsPerVertex;
|
||||
|
||||
@@ -70,9 +70,9 @@ namespace FlaxEditor.Tools.Terrain.Sculpt
|
||||
|
||||
// Prepare
|
||||
var chunkSize = terrain.ChunkSize;
|
||||
var heightmapSize = chunkSize * FlaxEngine.Terrain.PatchEdgeChunksCount + 1;
|
||||
var heightmapSize = terrain.HeightmapSize;
|
||||
var heightmapLength = heightmapSize * heightmapSize;
|
||||
var patchSize = chunkSize * FlaxEngine.Terrain.UnitsPerVertex * FlaxEngine.Terrain.PatchEdgeChunksCount;
|
||||
var patchSize = terrain.PatchSize;
|
||||
var tempBuffer = (float*)gizmo.GetHeightmapTempBuffer(heightmapLength * sizeof(float)).ToPointer();
|
||||
var unitsPerVertexInv = 1.0f / FlaxEngine.Terrain.UnitsPerVertex;
|
||||
|
||||
|
||||
@@ -85,8 +85,7 @@ namespace FlaxEditor.Tools.Terrain.Undo
|
||||
{
|
||||
_terrain = terrain.ID;
|
||||
_patches = new List<PatchData>(4);
|
||||
var chunkSize = terrain.ChunkSize;
|
||||
var heightmapSize = chunkSize * FlaxEngine.Terrain.PatchEdgeChunksCount + 1;
|
||||
var heightmapSize = terrain.HeightmapSize;
|
||||
_heightmapLength = heightmapSize * heightmapSize;
|
||||
_heightmapDataSize = _heightmapLength * stride;
|
||||
|
||||
|
||||
@@ -303,8 +303,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
{
|
||||
_terrain = new Terrain();
|
||||
_terrain.Setup(1, 63);
|
||||
var chunkSize = _terrain.ChunkSize;
|
||||
var heightMapSize = chunkSize * Terrain.PatchEdgeChunksCount + 1;
|
||||
var heightMapSize = _terrain.HeightmapSize;
|
||||
var heightMapLength = heightMapSize * heightMapSize;
|
||||
var heightmap = new float[heightMapLength];
|
||||
var patchCoord = new Int2(0, 0);
|
||||
|
||||
@@ -88,9 +88,8 @@ void TerrainMaterialShader::Bind(BindParameters& params)
|
||||
}
|
||||
|
||||
// Bind terrain textures
|
||||
const auto heightmap = drawCall.Terrain.Patch->Heightmap->GetTexture();
|
||||
const auto splatmap0 = drawCall.Terrain.Patch->Splatmap[0] ? drawCall.Terrain.Patch->Splatmap[0]->GetTexture() : nullptr;
|
||||
const auto splatmap1 = drawCall.Terrain.Patch->Splatmap[1] ? drawCall.Terrain.Patch->Splatmap[1]->GetTexture() : nullptr;
|
||||
GPUTexture* heightmap, *splatmap0, *splatmap1;
|
||||
drawCall.Terrain.Patch->GetTextures(heightmap, splatmap0, splatmap1);
|
||||
context->BindSR(0, heightmap);
|
||||
context->BindSR(1, splatmap0);
|
||||
context->BindSR(2, splatmap1);
|
||||
|
||||
@@ -8,13 +8,22 @@ using Flax.Build.NativeCpp;
|
||||
/// </summary>
|
||||
public class Terrain : EngineModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables terrain editing and changing at runtime. If your game doesn't use procedural terrain in game then disable this option to reduce build size.
|
||||
/// </summary>
|
||||
public static bool WithEditing = true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Setup(BuildOptions options)
|
||||
{
|
||||
base.Setup(options);
|
||||
|
||||
options.PrivateDependencies.Add("Physics");
|
||||
if (!WithEditing)
|
||||
{
|
||||
options.PublicDefinitions.Add("TERRAIN_EDITING=0");
|
||||
}
|
||||
|
||||
options.PrivateDependencies.Add("Physics");
|
||||
if (options.Target.IsEditor)
|
||||
{
|
||||
options.PrivateDependencies.Add("ContentImporters");
|
||||
|
||||
@@ -306,6 +306,16 @@ void Terrain::SetPhysicalMaterials(const Array<JsonAssetReference<PhysicalMateri
|
||||
}
|
||||
}
|
||||
|
||||
int32 Terrain::GetHeightmapSize() const
|
||||
{
|
||||
return GetChunkSize() * ChunksCountEdge + 1;
|
||||
}
|
||||
|
||||
float Terrain::GetPatchSize() const
|
||||
{
|
||||
return TERRAIN_UNITS_PER_VERTEX * ChunksCountEdge * GetChunkSize();
|
||||
}
|
||||
|
||||
TerrainPatch* Terrain::GetPatch(const Int2& patchCoord) const
|
||||
{
|
||||
return GetPatch(patchCoord.X, patchCoord.Y);
|
||||
|
||||
@@ -21,11 +21,14 @@ struct RenderView;
|
||||
// Amount of units per terrain geometry vertex (can be adjusted per terrain instance using non-uniform scale factor)
|
||||
#define TERRAIN_UNITS_PER_VERTEX 100.0f
|
||||
|
||||
// Enable/disable terrain editing and changing at runtime. If your game doesn't use procedural terrain in game then disable this option to reduce build size.
|
||||
#ifndef TERRAIN_EDITING
|
||||
// Enables terrain editing and changing at runtime. If your game doesn't use procedural terrain in game then disable this option to reduce build size.
|
||||
#define TERRAIN_EDITING 1
|
||||
#endif
|
||||
|
||||
// Enable/disable terrain heightmap samples modification and gather. Used by the editor to modify the terrain with the brushes.
|
||||
#define TERRAIN_UPDATING 1
|
||||
// [Deprecated in 1.12, use TERRAIN_EDITING instead]
|
||||
#define TERRAIN_UPDATING (TERRAIN_EDITING)
|
||||
|
||||
// Enable/disable terrain physics collision drawing
|
||||
#define TERRAIN_USE_PHYSICS_DEBUG (USE_EDITOR && 1)
|
||||
@@ -240,6 +243,18 @@ public:
|
||||
return static_cast<int32>(_chunkSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the heightmap texture size (square) used by a single patch (shared by all chunks within that patch).
|
||||
/// </summary>
|
||||
/// <remarks>ChunkSize * ChunksCountEdge + 1</remarks>
|
||||
API_PROPERTY() int32 GetHeightmapSize() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the patch in world-units (square) without actor scale.
|
||||
/// </summary>
|
||||
/// <remarks>UnitsPerVertex * ChunksCountEdge * ChunkSize</remarks>
|
||||
API_PROPERTY() float GetPatchSize() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the terrain patches count. Each patch contains 16 chunks arranged into a 4x4 square.
|
||||
/// </summary>
|
||||
@@ -329,7 +344,6 @@ public:
|
||||
API_FUNCTION() void SetChunkOverrideMaterial(API_PARAM(Ref) const Int2& patchCoord, API_PARAM(Ref) const Int2& chunkCoord, MaterialBase* value);
|
||||
|
||||
#if TERRAIN_EDITING
|
||||
|
||||
/// <summary>
|
||||
/// Setups the terrain patch using the specified heightmap data.
|
||||
/// </summary>
|
||||
@@ -352,10 +366,6 @@ public:
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
API_FUNCTION() bool SetupPatchSplatMap(API_PARAM(Ref) const Int2& patchCoord, int32 index, int32 splatMapLength, const Color32* splatMap, bool forceUseVirtualStorage = false);
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
#if TERRAIN_EDITING
|
||||
/// <summary>
|
||||
/// Setups the terrain. Clears the existing data.
|
||||
/// </summary>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#if TERRAIN_EDITING
|
||||
#include "Engine/Core/Math/Packed.h"
|
||||
#include "Engine/Core/Collections/ArrayExtensions.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
@@ -27,11 +28,6 @@
|
||||
#include "Editor/Editor.h"
|
||||
#include "Engine/ContentImporters/AssetsImportingManager.h"
|
||||
#endif
|
||||
#endif
|
||||
#if TERRAIN_EDITING || TERRAIN_UPDATING
|
||||
#include "Engine/Core/Collections/ArrayExtensions.h"
|
||||
#endif
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Debug/DebugDraw.h"
|
||||
#endif
|
||||
#if TERRAIN_USE_PHYSICS_DEBUG
|
||||
@@ -90,7 +86,7 @@ void TerrainPatch::Init(Terrain* terrain, int16 x, int16 z)
|
||||
Splatmap[i] = nullptr;
|
||||
}
|
||||
_heightfield = nullptr;
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
_cachedHeightMap.Resize(0);
|
||||
_cachedHolesMask.Resize(0);
|
||||
_wasHeightModified = false;
|
||||
@@ -114,7 +110,7 @@ void TerrainPatch::Init(Terrain* terrain, int16 x, int16 z)
|
||||
|
||||
TerrainPatch::~TerrainPatch()
|
||||
{
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
SAFE_DELETE(_dataHeightmap);
|
||||
for (int32 i = 0; i < TERRAIN_MAX_SPLATMAPS_COUNT; i++)
|
||||
{
|
||||
@@ -134,6 +130,13 @@ RawDataAsset* TerrainPatch::GetHeightfield() const
|
||||
return _heightfield.Get();
|
||||
}
|
||||
|
||||
void TerrainPatch::GetTextures(GPUTexture*& heightmap, GPUTexture*& splatmap0, GPUTexture*& splatmap1) const
|
||||
{
|
||||
heightmap = Heightmap->GetTexture();
|
||||
splatmap0 = Splatmap[0] ? Splatmap[0]->GetTexture() : nullptr;
|
||||
splatmap1 = Splatmap[1] ? Splatmap[1]->GetTexture() : nullptr;
|
||||
}
|
||||
|
||||
void TerrainPatch::RemoveLightmap()
|
||||
{
|
||||
for (auto& chunk : Chunks)
|
||||
@@ -178,7 +181,7 @@ void TerrainPatch::UpdateTransform()
|
||||
_collisionVertices.Resize(0);
|
||||
}
|
||||
|
||||
#if TERRAIN_EDITING || TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
|
||||
bool IsValidMaterial(const JsonAssetReference<PhysicalMaterial>& e)
|
||||
{
|
||||
@@ -217,7 +220,7 @@ struct TerrainDataUpdateInfo
|
||||
// When using physical materials, then get splatmaps data required for per-triangle material indices
|
||||
void GetSplatMaps()
|
||||
{
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
if (SplatMaps[0])
|
||||
return;
|
||||
if (UsePhysicalMaterials())
|
||||
@@ -1021,7 +1024,7 @@ bool TerrainPatch::SetupHeightMap(int32 heightMapLength, const float* heightMap,
|
||||
_terrain->UpdateBounds();
|
||||
_terrain->UpdateLayerBits();
|
||||
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
// Invalidate cache
|
||||
_cachedHeightMap.Resize(0);
|
||||
_cachedHolesMask.Resize(0);
|
||||
@@ -1169,7 +1172,7 @@ bool TerrainPatch::SetupSplatMap(int32 index, int32 splatMapLength, const Color3
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
// Invalidate cache
|
||||
_cachedSplatMap[index].Resize(0);
|
||||
_wasSplatmapModified[index] = false;
|
||||
@@ -1191,7 +1194,7 @@ bool TerrainPatch::InitializeHeightMap()
|
||||
return SetupHeightMap(heightmap.Count(), heightmap.Get());
|
||||
}
|
||||
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
|
||||
float* TerrainPatch::GetHeightmapData()
|
||||
{
|
||||
@@ -2631,7 +2634,7 @@ void TerrainPatch::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
}
|
||||
stream.EndArray();
|
||||
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
SaveHeightData();
|
||||
SaveSplatData();
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
struct RayCastHit;
|
||||
class TerrainMaterialShader;
|
||||
|
||||
#ifndef TERRAIN_EDITING
|
||||
#define TERRAIN_EDITING 1
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Represents single terrain patch made of 16 terrain chunks.
|
||||
/// </summary>
|
||||
@@ -34,7 +38,7 @@ private:
|
||||
void* _physicsHeightField;
|
||||
CriticalSection _collisionLocker;
|
||||
float _collisionScaleXZ;
|
||||
#if TERRAIN_UPDATING
|
||||
#if TERRAIN_EDITING
|
||||
Array<float> _cachedHeightMap;
|
||||
Array<byte> _cachedHolesMask;
|
||||
Array<Color32> _cachedSplatMap[TERRAIN_MAX_SPLATMAPS_COUNT];
|
||||
@@ -189,6 +193,8 @@ public:
|
||||
return _bounds;
|
||||
}
|
||||
|
||||
void GetTextures(GPUTexture*& heightmap, GPUTexture*& splatmap0, GPUTexture*& splatmap1) const;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Removes the lightmap data from the terrain patch.
|
||||
@@ -220,7 +226,7 @@ public:
|
||||
/// <param name="holesMask">The holes mask (optional). Normalized to 0-1 range values with holes mask per-vertex. Must match the heightmap dimensions.</param>
|
||||
/// <param name="forceUseVirtualStorage">If set to <c>true</c> patch will use virtual storage by force. Otherwise it can use normal texture asset storage on drive (valid only during Editor). Runtime-created terrain can only use virtual storage (in RAM).</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
API_FUNCTION() bool SetupHeightMap(int32 heightMapLength, API_PARAM(Ref) const float* heightMap, API_PARAM(Ref) const byte* holesMask = nullptr, bool forceUseVirtualStorage = false);
|
||||
API_FUNCTION() bool SetupHeightMap(int32 heightMapLength, const float* heightMap, const byte* holesMask = nullptr, bool forceUseVirtualStorage = false);
|
||||
|
||||
/// <summary>
|
||||
/// Setups the terrain patch layer weights using the specified splatmaps data.
|
||||
@@ -230,14 +236,12 @@ public:
|
||||
/// <param name="splatMap">The splat map. Each array item contains 4 layer weights.</param>
|
||||
/// <param name="forceUseVirtualStorage">If set to <c>true</c> patch will use virtual storage by force. Otherwise it can use normal texture asset storage on drive (valid only during Editor). Runtime-created terrain can only use virtual storage (in RAM).</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
API_FUNCTION() bool SetupSplatMap(int32 index, int32 splatMapLength, API_PARAM(Ref) const Color32* splatMap, bool forceUseVirtualStorage = false);
|
||||
#endif
|
||||
API_FUNCTION() bool SetupSplatMap(int32 index, int32 splatMapLength, const Color32* splatMap, bool forceUseVirtualStorage = false);
|
||||
|
||||
#if TERRAIN_UPDATING
|
||||
/// <summary>
|
||||
/// Gets the raw pointer to the heightmap data.
|
||||
/// Gets the raw pointer to the heightmap data. Array size is square of Terrain.HeightmapSize.
|
||||
/// </summary>
|
||||
/// <returns>The heightmap data.</returns>
|
||||
/// <returns>The heightmap data. Null if empty or failed to access it.</returns>
|
||||
API_FUNCTION() float* GetHeightmapData();
|
||||
|
||||
/// <summary>
|
||||
@@ -246,9 +250,9 @@ public:
|
||||
API_FUNCTION() void ClearHeightmapCache();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw pointer to the holes mask data.
|
||||
/// Gets the raw pointer to the holes mask data. Array size is square of Terrain.HeightmapSize.
|
||||
/// </summary>
|
||||
/// <returns>The holes mask data.</returns>
|
||||
/// <returns>The holes mask data. Null if empty/unused or failed to access it.</returns>
|
||||
API_FUNCTION() byte* GetHolesMaskData();
|
||||
|
||||
/// <summary>
|
||||
@@ -257,10 +261,10 @@ public:
|
||||
API_FUNCTION() void ClearHolesMaskCache();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw pointer to the splat map data.
|
||||
/// Gets the raw pointer to the splat map data. Array size is square of Terrain.HeightmapSize.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index of the splatmap texture.</param>
|
||||
/// <returns>The splat map data.</returns>
|
||||
/// <returns>The splat map data. Null if empty/unused or failed to access it.</returns>
|
||||
API_FUNCTION() Color32* GetSplatMapData(int32 index);
|
||||
|
||||
/// <summary>
|
||||
@@ -280,7 +284,7 @@ public:
|
||||
/// <param name="modifiedOffset">The offset from the first row and column of the heightmap data (offset destination x and z start position).</param>
|
||||
/// <param name="modifiedSize">The size of the heightmap to modify (x and z). Amount of samples in each direction.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
API_FUNCTION() bool ModifyHeightMap(API_PARAM(Ref) const float* samples, API_PARAM(Ref) const Int2& modifiedOffset, API_PARAM(Ref) const Int2& modifiedSize);
|
||||
API_FUNCTION() bool ModifyHeightMap(const float* samples, const Int2& modifiedOffset, const Int2& modifiedSize);
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the terrain patch holes mask with the given samples.
|
||||
@@ -289,7 +293,7 @@ public:
|
||||
/// <param name="modifiedOffset">The offset from the first row and column of the holes map data (offset destination x and z start position).</param>
|
||||
/// <param name="modifiedSize">The size of the holes map to modify (x and z). Amount of samples in each direction.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
API_FUNCTION() bool ModifyHolesMask(API_PARAM(Ref) const byte* samples, API_PARAM(Ref) const Int2& modifiedOffset, API_PARAM(Ref) const Int2& modifiedSize);
|
||||
API_FUNCTION() bool ModifyHolesMask(const byte* samples, const Int2& modifiedOffset, const Int2& modifiedSize);
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the terrain patch splat map (layers mask) with the given samples.
|
||||
@@ -299,7 +303,7 @@ public:
|
||||
/// <param name="modifiedOffset">The offset from the first row and column of the splat map data (offset destination x and z start position).</param>
|
||||
/// <param name="modifiedSize">The size of the splat map to modify (x and z). Amount of samples in each direction.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
API_FUNCTION() bool ModifySplatMap(int32 index, API_PARAM(Ref) const Color32* samples, API_PARAM(Ref) const Int2& modifiedOffset, API_PARAM(Ref) const Int2& modifiedSize);
|
||||
API_FUNCTION() bool ModifySplatMap(int32 index, const Color32* samples, const Int2& modifiedOffset, const Int2& modifiedSize);
|
||||
|
||||
private:
|
||||
bool UpdateHeightData(struct TerrainDataUpdateInfo& info, const Int2& modifiedOffset, const Int2& modifiedSize, bool wasHeightRangeChanged, bool wasHeightChanged);
|
||||
|
||||
Reference in New Issue
Block a user