From 62ff305fadeaa5c80ff34aa40a85517e9b74e580 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 3 Jul 2022 15:38:39 +0200 Subject: [PATCH] Fixes for Terrain with Large Worlds usage --- Source/Editor/Gizmo/EditorPrimitives.cs | 1 + Source/Editor/Tools/Terrain/Brushes/Brush.cs | 3 ++- Source/Editor/Tools/Terrain/Brushes/CircleBrush.cs | 4 ++-- Source/Editor/Tools/Terrain/EditTerrainGizmo.cs | 6 +++--- Source/Editor/Tools/Terrain/PaintTerrainGizmo.cs | 2 +- Source/Editor/Tools/Terrain/SculptTerrainGizmo.cs | 2 +- Source/Engine/Terrain/Terrain.cpp | 7 +++++-- Source/Engine/Terrain/TerrainChunk.cpp | 2 +- Source/Engine/Terrain/TerrainPatch.cpp | 5 +++-- 9 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Source/Editor/Gizmo/EditorPrimitives.cs b/Source/Editor/Gizmo/EditorPrimitives.cs index f370bc3f3..c427418aa 100644 --- a/Source/Editor/Gizmo/EditorPrimitives.cs +++ b/Source/Editor/Gizmo/EditorPrimitives.cs @@ -67,6 +67,7 @@ namespace FlaxEditor.Gizmo var renderList = RenderList.GetFromPool(); var prevList = renderContext.List; renderContext.List = renderList; + renderContext.View.Pass = DrawPass.GBuffer | DrawPass.Forward; try { Viewport.DrawEditorPrimitives(context, ref renderContext, target, targetDepth); diff --git a/Source/Editor/Tools/Terrain/Brushes/Brush.cs b/Source/Editor/Tools/Terrain/Brushes/Brush.cs index 969d5d3f2..a177e9809 100644 --- a/Source/Editor/Tools/Terrain/Brushes/Brush.cs +++ b/Source/Editor/Tools/Terrain/Brushes/Brush.cs @@ -24,10 +24,11 @@ namespace FlaxEditor.Tools.Terrain.Brushes /// /// Gets the brush material for the terrain chunk rendering. It must have domain set to Terrain. Setup material parameters within this call. /// + /// The rendering context. /// The world-space brush position. /// The brush position. /// The ready to render material for terrain chunks overlay on top of the terrain. - public abstract MaterialInstance GetBrushMaterial(ref Vector3 position, ref Color color); + public abstract MaterialInstance GetBrushMaterial(ref RenderContext renderContext, ref Vector3 position, ref Color color); /// /// Loads the brush material from the internal location. It's later cached by the object and reused. diff --git a/Source/Editor/Tools/Terrain/Brushes/CircleBrush.cs b/Source/Editor/Tools/Terrain/Brushes/CircleBrush.cs index 497ea7b98..56327c50a 100644 --- a/Source/Editor/Tools/Terrain/Brushes/CircleBrush.cs +++ b/Source/Editor/Tools/Terrain/Brushes/CircleBrush.cs @@ -97,7 +97,7 @@ namespace FlaxEditor.Tools.Terrain.Brushes } /// - public override MaterialInstance GetBrushMaterial(ref Vector3 position, ref Color color) + public override MaterialInstance GetBrushMaterial(ref RenderContext renderContext, ref Vector3 position, ref Color color) { var material = CacheMaterial(EditorAssets.TerrainCircleBrushMaterial); if (material) @@ -108,7 +108,7 @@ namespace FlaxEditor.Tools.Terrain.Brushes float falloff = halfSize * Falloff; float radius = halfSize - falloff; material.SetParameterValue("Color", color); - material.SetParameterValue("BrushData0", new Float4(position, radius)); + material.SetParameterValue("BrushData0", new Float4(position - renderContext.View.Origin, radius)); material.SetParameterValue("BrushData1", new Float4(falloff, (float)FalloffType, 0, 0)); } return material; diff --git a/Source/Editor/Tools/Terrain/EditTerrainGizmo.cs b/Source/Editor/Tools/Terrain/EditTerrainGizmo.cs index e864350b9..def77df19 100644 --- a/Source/Editor/Tools/Terrain/EditTerrainGizmo.cs +++ b/Source/Editor/Tools/Terrain/EditTerrainGizmo.cs @@ -88,14 +88,14 @@ namespace FlaxEditor.Tools.Terrain var patchCoord = Mode.SelectedPatchCoord; if (!terrain.HasPatch(ref patchCoord) && _planeModel) { - var planeSize = 256.0f; + var planeSize = 100.0f; var patchSize = terrain.ChunkSize * FlaxEngine.Terrain.UnitsPerVertex * FlaxEngine.Terrain.PatchEdgeChunksCount; - Matrix world = Matrix.RotationZ(-Mathf.PiOverTwo) * + Matrix world = Matrix.RotationX(-Mathf.PiOverTwo) * Matrix.Scaling(patchSize / planeSize) * Matrix.Translation(patchSize * (0.5f + patchCoord.X), 0, patchSize * (0.5f + patchCoord.Y)) * Matrix.Scaling(terrain.Scale) * Matrix.RotationQuaternion(terrain.Orientation) * - Matrix.Translation(terrain.Position); + Matrix.Translation(terrain.Position - renderContext.View.Origin); _planeModel.Draw(ref renderContext, _highlightMaterial, ref world); } diff --git a/Source/Editor/Tools/Terrain/PaintTerrainGizmo.cs b/Source/Editor/Tools/Terrain/PaintTerrainGizmo.cs index ff02cb1c9..9a022c50f 100644 --- a/Source/Editor/Tools/Terrain/PaintTerrainGizmo.cs +++ b/Source/Editor/Tools/Terrain/PaintTerrainGizmo.cs @@ -74,7 +74,7 @@ namespace FlaxEditor.Tools.Terrain { var brushPosition = Mode.CursorPosition; var brushColor = new Color(1.0f, 0.85f, 0.0f); // TODO: expose to editor options - var brushMaterial = Mode.CurrentBrush.GetBrushMaterial(ref brushPosition, ref brushColor); + var brushMaterial = Mode.CurrentBrush.GetBrushMaterial(ref renderContext, ref brushPosition, ref brushColor); if (!brushMaterial) return; diff --git a/Source/Editor/Tools/Terrain/SculptTerrainGizmo.cs b/Source/Editor/Tools/Terrain/SculptTerrainGizmo.cs index 206b9bbf7..acfd70526 100644 --- a/Source/Editor/Tools/Terrain/SculptTerrainGizmo.cs +++ b/Source/Editor/Tools/Terrain/SculptTerrainGizmo.cs @@ -74,7 +74,7 @@ namespace FlaxEditor.Tools.Terrain { var brushPosition = Mode.CursorPosition; var brushColor = new Color(1.0f, 0.85f, 0.0f); // TODO: expose to editor options - var brushMaterial = Mode.CurrentBrush.GetBrushMaterial(ref brushPosition, ref brushColor); + var brushMaterial = Mode.CurrentBrush.GetBrushMaterial(ref renderContext, ref brushPosition, ref brushColor); if (!brushMaterial) return; diff --git a/Source/Engine/Terrain/Terrain.cpp b/Source/Engine/Terrain/Terrain.cpp index 713a26fb4..8c701e9d5 100644 --- a/Source/Engine/Terrain/Terrain.cpp +++ b/Source/Engine/Terrain/Terrain.cpp @@ -556,10 +556,12 @@ void Terrain::Draw(RenderContext& renderContext) // Frustum vs Box culling for patches const BoundingFrustum frustum = renderContext.View.CullingFrustum; + const Vector3 origin = renderContext.View.Origin; for (int32 patchIndex = 0; patchIndex < _patches.Count(); patchIndex++) { const auto patch = _patches[patchIndex]; - if (renderContext.View.IsCullingDisabled || frustum.Intersects(patch->_bounds)) + BoundingBox bounds(patch->_bounds.Minimum - origin, patch->_bounds.Maximum - origin); + if (renderContext.View.IsCullingDisabled || frustum.Intersects(bounds)) { // Skip if has no heightmap or it's not loaded if (patch->Heightmap == nullptr || patch->Heightmap->GetTexture()->ResidentMipLevels() == 0) @@ -570,7 +572,8 @@ void Terrain::Draw(RenderContext& renderContext) { auto chunk = &patch->Chunks[chunkIndex]; chunk->_cachedDrawLOD = 0; - if (renderContext.View.IsCullingDisabled || frustum.Intersects(chunk->_bounds)) + bounds = BoundingBox(chunk->_bounds.Minimum - origin, chunk->_bounds.Maximum - origin); + if (renderContext.View.IsCullingDisabled || frustum.Intersects(bounds)) { if (chunk->PrepareDraw(renderContext)) { diff --git a/Source/Engine/Terrain/TerrainChunk.cpp b/Source/Engine/Terrain/TerrainChunk.cpp index bd534fd54..b1e1fb2c6 100644 --- a/Source/Engine/Terrain/TerrainChunk.cpp +++ b/Source/Engine/Terrain/TerrainChunk.cpp @@ -45,7 +45,7 @@ bool TerrainChunk::PrepareDraw(const RenderContext& renderContext) // Calculate chunk distance to view const auto lodView = (renderContext.LodProxyView ? renderContext.LodProxyView : &renderContext.View); - const float distance = Float3::Distance(_boundsCenter, lodView->Position); // TODO: large-worlds + const float distance = Float3::Distance(_boundsCenter - lodView->Origin, lodView->Position); lod = (int32)Math::Pow(distance / chunkEdgeSize, lodDistribution); lod += lodBias; diff --git a/Source/Engine/Terrain/TerrainPatch.cpp b/Source/Engine/Terrain/TerrainPatch.cpp index 2aaa8dec7..07140f059 100644 --- a/Source/Engine/Terrain/TerrainPatch.cpp +++ b/Source/Engine/Terrain/TerrainPatch.cpp @@ -2244,7 +2244,8 @@ void TerrainPatch::CacheDebugLines() void TerrainPatch::DrawPhysicsDebug(RenderView& view) { - if (!_physicsShape || !view.CullingFrustum.Intersects(_bounds)) + const BoundingBox bounds(_bounds.Minimum - view.Origin, _bounds.Maximum - view.Origin); + if (!_physicsShape || !view.CullingFrustum.Intersects(bounds)) return; const Transform terrainTransform = _terrain->_transform; @@ -2258,7 +2259,7 @@ void TerrainPatch::DrawPhysicsDebug(RenderView& view) else { BoundingSphere sphere; - BoundingSphere::FromBox(_bounds, sphere); + BoundingSphere::FromBox(bounds, sphere); if (Vector3::Distance(sphere.Center, view.Position) - sphere.Radius < 4000.0f) { if (_debugLines.IsEmpty())