// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Math/BoundingBox.h" #include "Engine/Core/Math/BoundingSphere.h" #include "Engine/Core/Math/Matrix.h" #include "Engine/Core/Math/Transform.h" #include "Engine/Core/ISerializable.h" #include "Engine/Content/Assets/MaterialBase.h" #include "Engine/Level/Scene/Lightmap.h" class Terrain; class TerrainPatch; struct RenderContext; /// /// Represents a single terrain chunk. /// API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API TerrainChunk : public ScriptingObject, public ISerializable { DECLARE_SCRIPTING_TYPE(TerrainChunk); friend Terrain; friend TerrainPatch; friend TerrainChunk; private: TerrainPatch* _patch; uint16 _x, _z; Float4 _heightmapUVScaleBias; Transform _transform; BoundingBox _bounds; BoundingSphere _sphere; float _perInstanceRandom; float _yOffset, _yHeight; TerrainChunk* _neighbors[4]; byte _cachedDrawLOD; IMaterial* _cachedDrawMaterial; void Init(TerrainPatch* patch, uint16 x, uint16 z); public: /// /// The material to override the terrain default one for this chunk. /// API_FIELD() AssetReference OverrideMaterial; /// /// The baked lightmap entry info for this chunk. /// LightmapEntry Lightmap; public: /// /// Gets the x coordinate. /// API_FUNCTION() FORCE_INLINE int32 GetX() const { return _x; } /// /// Gets the z coordinate. /// API_FUNCTION() FORCE_INLINE int32 GetZ() const { return _z; } /// /// Gets the patch. /// API_FUNCTION() FORCE_INLINE TerrainPatch* GetPatch() const { return _patch; } /// /// Gets the chunk world bounds. /// API_FUNCTION() FORCE_INLINE const BoundingBox& GetBounds() const { return _bounds; } /// /// Gets the chunk transformation (world to local). /// API_FUNCTION() FORCE_INLINE const Transform& GetTransform() const { return _transform; } /// /// Gets the scale (in XY) and bias (in ZW) applied to the vertex UVs to get the chunk coordinates. /// API_FUNCTION() FORCE_INLINE const Float4& GetHeightmapUVScaleBias() const { return _heightmapUVScaleBias; } /// /// Determines whether this chunk has valid lightmap data. /// FORCE_INLINE bool HasLightmap() const { return Lightmap.TextureIndex != INVALID_INDEX; } /// /// Removes the lightmap data from the chunk. /// FORCE_INLINE void RemoveLightmap() { Lightmap.TextureIndex = INVALID_INDEX; } public: /// /// Prepares for drawing chunk. Cached LOD and material. /// /// The rendering context. /// True if draw chunk, otherwise false. bool PrepareDraw(const RenderContext& renderContext); /// /// Draws the chunk (adds the draw call). Must be called after PrepareDraw. /// /// The rendering context. void Draw(const RenderContext& renderContext) const; /// /// Draws the terrain chunk. /// /// The rendering context. /// The material to use for rendering. /// The LOD index. 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 /// /// The ray. /// The output distance. /// True if chunk intersects with the ray, otherwise false. API_FUNCTION() bool Intersects(const Ray& ray, API_PARAM(Out) Real& distance); /// /// Updates the cached bounds of the chunk. /// void UpdateBounds(); /// /// Updates the cached transform of the chunk. /// void UpdateTransform(); /// /// Caches the neighbor chunks of this chunk. /// void CacheNeighbors(); public: // [ISerializable] void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; };