From 9d1b287cd7792a09e202a2bae6584cf5369bf48e Mon Sep 17 00:00:00 2001 From: Wiktor Kocielski Date: Wed, 18 Oct 2023 13:12:10 +0300 Subject: [PATCH] Terrain-related classes exposure to scripting API --- .../Engine/ShadowsOfMordor/Builder.Jobs.cpp | 2 +- Source/Engine/Terrain/Terrain.h | 18 +-- Source/Engine/Terrain/TerrainChunk.cpp | 6 + Source/Engine/Terrain/TerrainChunk.h | 38 +++--- Source/Engine/Terrain/TerrainPatch.cpp | 5 + Source/Engine/Terrain/TerrainPatch.h | 109 ++++++++++++------ 6 files changed, 111 insertions(+), 67 deletions(-) diff --git a/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp b/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp index 11d136d62..8aed89eb3 100644 --- a/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp +++ b/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp @@ -165,7 +165,7 @@ void ShadowsOfMordor::Builder::onJobRender(GPUContext* context) Matrix::Transpose(world, shaderData.WorldMatrix); shaderData.LightmapArea = chunk->Lightmap.UVsArea; shaderData.TerrainChunkSizeLOD0 = TERRAIN_UNITS_PER_VERTEX * chunkSize; - chunk->GetHeightmapUVScaleBias(&shaderData.HeightmapUVScaleBias); + shaderData.HeightmapUVScaleBias = chunk->GetHeightmapUVScaleBias(); // Extract per axis scales from LocalToWorld transform const float scaleX = Float3(world.M11, world.M12, world.M13).Length(); diff --git a/Source/Engine/Terrain/Terrain.h b/Source/Engine/Terrain/Terrain.h index 636f30206..5b8465cd0 100644 --- a/Source/Engine/Terrain/Terrain.h +++ b/Source/Engine/Terrain/Terrain.h @@ -219,7 +219,7 @@ public: /// /// The patch location (x and z). /// The patch. - TerrainPatch* GetPatch(const Int2& patchCoord) const; + API_FUNCTION() TerrainPatch* GetPatch(API_PARAM(Ref) const Int2& patchCoord) const; /// /// Gets the patch at the given location. @@ -227,7 +227,7 @@ public: /// The patch location x. /// The patch location z. /// The patch. - TerrainPatch* GetPatch(int32 x, int32 z) const; + API_FUNCTION() TerrainPatch* GetPatch(int32 x, int32 z) const; /// /// Gets the zero-based index of the terrain patch in the terrain patches collection. @@ -241,7 +241,7 @@ public: /// /// The index. /// The patch. - FORCE_INLINE TerrainPatch* GetPatch(int32 index) const + API_FUNCTION() FORCE_INLINE TerrainPatch* GetPatch(int32 index) const { return _patches[index]; } @@ -344,22 +344,22 @@ public: /// /// Updates the cached bounds of the actor. Updates the cached world bounds for every patch and chunk. /// - void UpdateBounds(); + API_FUNCTION() void UpdateBounds(); /// /// Caches the neighbor chunks of this terrain. /// - void CacheNeighbors(); + API_FUNCTION() void CacheNeighbors(); /// /// Updates the collider shapes collisions/queries layer mask bits. /// - void UpdateLayerBits(); + API_FUNCTION() void UpdateLayerBits(); /// /// Removes the lightmap data from the terrain. /// - void RemoveLightmap(); + API_FUNCTION() void RemoveLightmap(); public: @@ -371,7 +371,7 @@ public: /// The raycast result hit position distance from the ray origin. Valid only if raycast hits anything. /// The maximum distance the ray should check for collisions. /// True if ray hits an object, otherwise false. - API_FUNCTION() bool RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance = MAX_float) const; + API_FUNCTION() bool RayCast(const Vector3& origin, const Vector3& direction, API_PARAM(Out) float& resultHitDistance, float maxDistance = MAX_float) const; /// /// Performs a raycast against this terrain collision shape. Returns the hit chunk. @@ -382,7 +382,7 @@ public: /// The raycast result hit chunk. Valid only if raycast hits anything. /// The maximum distance the ray should check for collisions. /// True if ray hits an object, otherwise false. - bool RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, TerrainChunk*& resultChunk, float maxDistance = MAX_float) const; + API_FUNCTION() bool RayCast(const Vector3& origin, const Vector3& direction, API_PARAM(Out) float& resultHitDistance, API_PARAM(Out) TerrainChunk*& resultChunk, float maxDistance = MAX_float) const; /// /// Performs a raycast against this terrain collision shape. Returns the hit chunk. diff --git a/Source/Engine/Terrain/TerrainChunk.cpp b/Source/Engine/Terrain/TerrainChunk.cpp index 737ce08f8..5088357fe 100644 --- a/Source/Engine/Terrain/TerrainChunk.cpp +++ b/Source/Engine/Terrain/TerrainChunk.cpp @@ -13,6 +13,12 @@ #include "Engine/Level/Scene/Scene.h" #include "Engine/Level/Prefabs/PrefabManager.h" + +TerrainChunk::TerrainChunk(const SpawnParams& params) + : ScriptingObject(params) +{ +} + void TerrainChunk::Init(TerrainPatch* patch, uint16 x, uint16 z) { // Initialize chunk properties diff --git a/Source/Engine/Terrain/TerrainChunk.h b/Source/Engine/Terrain/TerrainChunk.h index 884160b45..15de44a9c 100644 --- a/Source/Engine/Terrain/TerrainChunk.h +++ b/Source/Engine/Terrain/TerrainChunk.h @@ -17,8 +17,9 @@ struct RenderContext; /// /// Represents a single terrain chunk. /// -class FLAXENGINE_API TerrainChunk : public ISerializable +API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API TerrainChunk : public ScriptingObject, public ISerializable { + DECLARE_SCRIPTING_TYPE(TerrainChunk); friend Terrain; friend TerrainPatch; friend TerrainChunk; @@ -45,7 +46,7 @@ public: /// /// The material to override the terrain default one for this chunk. /// - AssetReference OverrideMaterial; + API_FIELD() AssetReference OverrideMaterial; /// /// The baked lightmap entry info for this chunk. @@ -57,7 +58,7 @@ public: /// /// Gets the x coordinate. /// - FORCE_INLINE int32 GetX() const + API_FUNCTION() FORCE_INLINE int32 GetX() const { return _x; } @@ -65,7 +66,7 @@ public: /// /// Gets the z coordinate. /// - FORCE_INLINE int32 GetZ() const + API_FUNCTION() FORCE_INLINE int32 GetZ() const { return _z; } @@ -73,7 +74,7 @@ public: /// /// Gets the patch. /// - FORCE_INLINE TerrainPatch* GetPatch() const + API_FUNCTION() FORCE_INLINE TerrainPatch* GetPatch() const { return _patch; } @@ -81,7 +82,7 @@ public: /// /// Gets the chunk world bounds. /// - FORCE_INLINE const BoundingBox& GetBounds() const + API_FUNCTION() FORCE_INLINE const BoundingBox& GetBounds() const { return _bounds; } @@ -89,7 +90,7 @@ public: /// /// Gets the chunk transformation (world to local). /// - FORCE_INLINE const Transform& GetTransform() const + API_FUNCTION() FORCE_INLINE const Transform& GetTransform() const { return _transform; } @@ -97,16 +98,15 @@ public: /// /// Gets the scale (in XY) and bias (in ZW) applied to the vertex UVs to get the chunk coordinates. /// - /// The result. - FORCE_INLINE void GetHeightmapUVScaleBias(Float4* result) const + API_FUNCTION() FORCE_INLINE const Float4& GetHeightmapUVScaleBias() const { - *result = _heightmapUVScaleBias; + return _heightmapUVScaleBias; } /// /// Determines whether this chunk has valid lightmap data. /// - FORCE_INLINE bool HasLightmap() const + API_FUNCTION() FORCE_INLINE bool HasLightmap() const { return Lightmap.TextureIndex != INVALID_INDEX; } @@ -114,7 +114,7 @@ public: /// /// Removes the lightmap data from the chunk. /// - FORCE_INLINE void RemoveLightmap() + API_FUNCTION() FORCE_INLINE void RemoveLightmap() { Lightmap.TextureIndex = INVALID_INDEX; } @@ -126,13 +126,13 @@ public: /// /// The rendering context. /// True if draw chunk, otherwise false. - bool PrepareDraw(const RenderContext& renderContext); + API_FUNCTION() bool PrepareDraw(API_PARAM(Ref) const RenderContext& renderContext); /// /// Draws the chunk (adds the draw call). Must be called after PrepareDraw. /// /// The rendering context. - void Draw(const RenderContext& renderContext) const; + API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext) const; /// /// Draws the terrain chunk. @@ -140,7 +140,7 @@ public: /// The rendering context. /// The material to use for rendering. /// The LOD index. - void Draw(const RenderContext& renderContext, MaterialBase* material, int32 lodIndex = 0) const; + API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, int32 lodIndex = 0) const; /// /// Determines if there is an intersection between the terrain chunk and a point @@ -148,22 +148,22 @@ public: /// The ray. /// The output distance. /// True if chunk intersects with the ray, otherwise false. - bool Intersects(const Ray& ray, Real& distance); + API_FUNCTION() bool Intersects(const Ray& ray, API_PARAM(Out) Real& distance); /// /// Updates the cached bounds of the chunk. /// - void UpdateBounds(); + API_FUNCTION() void UpdateBounds(); /// /// Updates the cached transform of the chunk. /// - void UpdateTransform(); + API_FUNCTION() void UpdateTransform(); /// /// Caches the neighbor chunks of this chunk. /// - void CacheNeighbors(); + API_FUNCTION() void CacheNeighbors(); public: diff --git a/Source/Engine/Terrain/TerrainPatch.cpp b/Source/Engine/Terrain/TerrainPatch.cpp index 8e05062c8..f6421ff97 100644 --- a/Source/Engine/Terrain/TerrainPatch.cpp +++ b/Source/Engine/Terrain/TerrainPatch.cpp @@ -41,6 +41,11 @@ struct TerrainCollisionDataHeader float ScaleXZ; }; +TerrainPatch::TerrainPatch(const SpawnParams& params) + : ScriptingObject(params) +{ +} + void TerrainPatch::Init(Terrain* terrain, int16 x, int16 z) { ScopeLock lock(_collisionLocker); diff --git a/Source/Engine/Terrain/TerrainPatch.h b/Source/Engine/Terrain/TerrainPatch.h index 689c629c5..103ee028b 100644 --- a/Source/Engine/Terrain/TerrainPatch.h +++ b/Source/Engine/Terrain/TerrainPatch.h @@ -15,17 +15,27 @@ class TerrainMaterialShader; /// /// Represents single terrain patch made of 16 terrain chunks. /// -class FLAXENGINE_API TerrainPatch : public ISerializable +API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API TerrainPatch : public ScriptingObject, public ISerializable { + DECLARE_SCRIPTING_TYPE(TerrainPatch); friend Terrain; friend TerrainPatch; friend TerrainChunk; public: - enum + /// + /// Various defines regarding maximum chunk counts + /// + API_ENUM() enum ChunksCount { + /// + /// The maximum allowed amount of chunks per patch + /// CHUNKS_COUNT = 16, + /// + /// The maximum allowed amount of chunks per chunk + /// CHUNKS_COUNT_EDGE = 4, }; @@ -73,12 +83,12 @@ public: /// /// The chunks contained within the patch. Organized in 4x4 square. /// - TerrainChunk Chunks[CHUNKS_COUNT]; + TerrainChunk Chunks[ChunksCount::CHUNKS_COUNT]; /// /// The heightmap texture. /// - AssetReference Heightmap; + API_FIELD() AssetReference Heightmap; /// /// The splatmap textures. @@ -91,7 +101,7 @@ public: /// Gets the Y axis heightmap offset from terrain origin. /// /// The offset. - FORCE_INLINE float GetOffsetY() const + API_FUNCTION() FORCE_INLINE float GetOffsetY() const { return _yOffset; } @@ -100,7 +110,7 @@ public: /// Gets the Y axis heightmap height. /// /// The height. - FORCE_INLINE float GetHeightY() const + API_FUNCTION() FORCE_INLINE float GetHeightY() const { return _yHeight; } @@ -109,7 +119,7 @@ public: /// Gets the x coordinate. /// /// The x position. - FORCE_INLINE int32 GetX() const + API_FUNCTION() FORCE_INLINE int32 GetX() const { return _x; } @@ -118,7 +128,7 @@ public: /// Gets the z coordinate. /// /// The z position. - FORCE_INLINE int32 GetZ() const + API_FUNCTION() FORCE_INLINE int32 GetZ() const { return _z; } @@ -127,7 +137,7 @@ public: /// Gets the terrain. /// /// The terrain, - FORCE_INLINE Terrain* GetTerrain() const + API_FUNCTION() FORCE_INLINE Terrain* GetTerrain() const { return _terrain; } @@ -137,7 +147,7 @@ public: /// /// The chunk zero-based index. /// The chunk. - TerrainChunk* GetChunk(int32 index) + API_FUNCTION() TerrainChunk* GetChunk(int32 index) { if (index < 0 || index >= CHUNKS_COUNT) return nullptr; @@ -149,7 +159,7 @@ public: /// /// The chunk location (x and z). /// The chunk. - TerrainChunk* GetChunk(const Int2& chunkCoord) + API_FUNCTION() TerrainChunk* GetChunk(API_PARAM(Ref) const Int2& chunkCoord) { return GetChunk(chunkCoord.Y * CHUNKS_COUNT_EDGE + chunkCoord.X); } @@ -160,16 +170,28 @@ public: /// The chunk location x. /// The chunk location z. /// The chunk. - TerrainChunk* GetChunk(int32 x, int32 z) + API_FUNCTION() TerrainChunk* GetChunk(int32 x, int32 z) { return GetChunk(z * CHUNKS_COUNT_EDGE + x); } + /// + /// Gets the splatmap assigned to this patch. + /// + /// Splatmap index. + /// Splatmap texture. + API_FUNCTION() AssetReference GetSplatmap(int32 index) + { + if (index < 0 || index >= TERRAIN_MAX_SPLATMAPS_COUNT) + return nullptr; + return Splatmap[index]; + } + /// /// Gets the patch world bounds. /// /// The bounding box. - FORCE_INLINE const BoundingBox& GetBounds() const + API_FUNCTION() FORCE_INLINE const BoundingBox& GetBounds() const { return _bounds; } @@ -179,17 +201,28 @@ public: /// /// Removes the lightmap data from the terrain patch. /// - void RemoveLightmap(); + API_FUNCTION() void RemoveLightmap(); /// /// Updates the cached bounds of the patch and child chunks. /// - void UpdateBounds(); + API_FUNCTION() void UpdateBounds(); /// /// Updates the cached transform of the patch and child chunks. /// - void UpdateTransform(); + API_FUNCTION() void UpdateTransform(); + + /// + /// Assigns a splatmap to this patch. + /// + /// Splatmap index. + /// Splatmap texture. + API_FUNCTION() void SetSplatmap(int32 index, const AssetReference& splatMap) + { + if (index >= 0 && index < TERRAIN_MAX_SPLATMAPS_COUNT) + Splatmap[index] = splatMap; + } #if TERRAIN_EDITING @@ -197,7 +230,7 @@ public: /// Initializes the patch heightmap and collision to the default flat level. /// /// True if failed, otherwise false. - bool InitializeHeightMap(); + API_FUNCTION() bool InitializeHeightMap(); /// /// Setups the terrain patch using the specified heightmap data. @@ -207,7 +240,7 @@ public: /// The holes mask (optional). Normalized to 0-1 range values with holes mask per-vertex. Must match the heightmap dimensions. /// If set to true 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). /// True if failed, otherwise false. - bool SetupHeightMap(int32 heightMapLength, const float* heightMap, const byte* holesMask = nullptr, bool forceUseVirtualStorage = false); + API_FUNCTION() bool SetupHeightMap(int32 heightMapLength, API_PARAM(Ref) const float* heightMap, API_PARAM(Ref) const byte* holesMask = nullptr, bool forceUseVirtualStorage = false); /// /// Setups the terrain patch layer weights using the specified splatmaps data. @@ -217,7 +250,7 @@ public: /// The splat map. Each array item contains 4 layer weights. /// If set to true 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). /// True if failed, otherwise false. - bool SetupSplatMap(int32 index, int32 splatMapLength, const Color32* splatMap, bool forceUseVirtualStorage = false); + API_FUNCTION() bool SetupSplatMap(int32 index, int32 splatMapLength, API_PARAM(Ref) const Color32* splatMap, bool forceUseVirtualStorage = false); #endif @@ -227,40 +260,40 @@ public: /// Gets the raw pointer to the heightmap data. /// /// The heightmap data. - float* GetHeightmapData(); + API_FUNCTION() float* GetHeightmapData(); /// /// Clears cache of the heightmap data. /// - void ClearHeightmapCache(); + API_FUNCTION() void ClearHeightmapCache(); /// /// Gets the raw pointer to the holes mask data. /// /// The holes mask data. - byte* GetHolesMaskData(); + API_FUNCTION() byte* GetHolesMaskData(); /// /// Clears cache of the holes mask data. /// - void ClearHolesMaskCache(); + API_FUNCTION() void ClearHolesMaskCache(); /// /// Gets the raw pointer to the splat map data. /// /// The zero-based index of the splatmap texture. /// The splat map data. - Color32* GetSplatMapData(int32 index); + API_FUNCTION() Color32* GetSplatMapData(int32 index); /// /// Clears cache of the splat map data. /// - void ClearSplatMapCache(); + API_FUNCTION() void ClearSplatMapCache(); /// /// Clears all caches. /// - void ClearCache(); + API_FUNCTION() void ClearCache(); /// /// Modifies the terrain patch heightmap with the given samples. @@ -269,7 +302,7 @@ public: /// The offset from the first row and column of the heightmap data (offset destination x and z start position). /// The size of the heightmap to modify (x and z). Amount of samples in each direction. /// True if failed, otherwise false. - bool ModifyHeightMap(const float* samples, const Int2& modifiedOffset, const Int2& modifiedSize); + API_FUNCTION() bool ModifyHeightMap(API_PARAM(Ref) const float* samples, API_PARAM(Ref) const Int2& modifiedOffset, API_PARAM(Ref) const Int2& modifiedSize); /// /// Modifies the terrain patch holes mask with the given samples. @@ -278,7 +311,7 @@ public: /// The offset from the first row and column of the holes map data (offset destination x and z start position). /// The size of the holes map to modify (x and z). Amount of samples in each direction. /// True if failed, otherwise false. - bool ModifyHolesMask(const byte* samples, const Int2& modifiedOffset, const Int2& modifiedSize); + API_FUNCTION() bool ModifyHolesMask(API_PARAM(Ref) const byte* samples, API_PARAM(Ref) const Int2& modifiedOffset, API_PARAM(Ref) const Int2& modifiedSize); /// /// Modifies the terrain patch splat map (layers mask) with the given samples. @@ -288,7 +321,7 @@ public: /// The offset from the first row and column of the splat map data (offset destination x and z start position). /// The size of the splat map to modify (x and z). Amount of samples in each direction. /// True if failed, otherwise false. - bool ModifySplatMap(int32 index, const Color32* samples, const Int2& modifiedOffset, const Int2& modifiedSize); + API_FUNCTION() bool ModifySplatMap(int32 index, API_PARAM(Ref) const Color32* samples, API_PARAM(Ref) const Int2& modifiedOffset, API_PARAM(Ref) const Int2& modifiedSize); private: @@ -311,7 +344,7 @@ public: /// The raycast result hit position distance from the ray origin. Valid only if raycast hits anything. /// The maximum distance the ray should check for collisions. /// True if ray hits an object, otherwise false. - bool RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance = MAX_float) const; + API_FUNCTION() bool RayCast(const Vector3& origin, const Vector3& direction, API_PARAM(Out) float& resultHitDistance, float maxDistance = MAX_float) const; /// /// Performs a raycast against this terrain collision shape. @@ -322,7 +355,7 @@ public: /// The raycast result hit position normal vector. Valid only if raycast hits anything. /// The maximum distance the ray should check for collisions. /// True if ray hits an object, otherwise false. - bool RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, Vector3& resultHitNormal, float maxDistance = MAX_float) const; + API_FUNCTION() bool RayCast(const Vector3& origin, const Vector3& direction, API_PARAM(Out) float& resultHitDistance, API_PARAM(Out) Vector3& resultHitNormal, float maxDistance = MAX_float) const; /// /// Performs a raycast against this terrain collision shape. Returns the hit chunk. @@ -333,7 +366,7 @@ public: /// The raycast result hit chunk. Valid only if raycast hits anything. /// The maximum distance the ray should check for collisions. /// True if ray hits an object, otherwise false. - bool RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, TerrainChunk*& resultChunk, float maxDistance = MAX_float) const; + API_FUNCTION() bool RayCast(const Vector3& origin, const Vector3& direction, API_PARAM(Out) float& resultHitDistance, API_PARAM(Out) TerrainChunk*& resultChunk, float maxDistance = MAX_float) const; /// /// Performs a raycast against terrain collision, returns results in a RaycastHit structure. @@ -343,21 +376,21 @@ public: /// The result hit information. Valid only when method returns true. /// The maximum distance the ray should check for collisions. /// True if ray hits an object, otherwise false. - bool RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, float maxDistance = MAX_float) const; + API_FUNCTION() bool RayCast(const Vector3& origin, const Vector3& direction, API_PARAM(Out) RayCastHit& hitInfo, float maxDistance = MAX_float) const; /// /// Gets a point on the terrain collider that is closest to a given location. Can be used to find a hit location or position to apply explosion force or any other special effects. /// /// The position to find the closest point to it. /// The result point on the collider that is closest to the specified location. - void ClosestPoint(const Vector3& position, Vector3& result) const; + API_FUNCTION() void ClosestPoint(API_PARAM(Ref) const Vector3& position, API_PARAM(Out) Vector3& result) const; #if USE_EDITOR /// /// Updates the patch data after manual deserialization called at runtime (eg. by editor undo). /// - void UpdatePostManualDeserialization(); + API_FUNCTION() void UpdatePostManualDeserialization(); #endif @@ -369,14 +402,14 @@ public: /// Gets the collision mesh triangles array (3 vertices per triangle in linear list). Cached internally to reuse data. /// /// The collision triangles vertices list (in world-space). - const Array& GetCollisionTriangles(); + API_FUNCTION() const Array& GetCollisionTriangles(); /// /// Gets the collision mesh triangles array (3 vertices per triangle in linear list) that intersect with the given bounds. /// /// The world-space bounds to find terrain triangles that intersect with it. /// The result triangles that intersect with the given bounds (in world-space). - void GetCollisionTriangles(const BoundingSphere& bounds, Array& result); + API_FUNCTION() void GetCollisionTriangles(API_PARAM(Ref) const BoundingSphere& bounds, API_PARAM(Out) Array& result); #endif @@ -385,7 +418,7 @@ public: /// /// The output vertex buffer. /// The output index buffer. - void ExtractCollisionGeometry(Array& vertexBuffer, Array& indexBuffer); + API_FUNCTION() void ExtractCollisionGeometry(API_PARAM(Out) Array& vertexBuffer, API_PARAM(Out) Array& indexBuffer); private: