From e729b5d171cf1f1f2384a608b82fadfea122718a Mon Sep 17 00:00:00 2001 From: Kamzik123 Date: Sun, 1 Dec 2024 01:15:13 +0100 Subject: [PATCH 1/4] Initial translokator spatial grid rendering code --- Mafia2Libs/Forms/MapEditor.cs | 2 +- .../Rendering/Graphics/GraphicsClass.cs | 10 +- .../Graphics/RenderTypes/IRenderer.cs | 1 + .../Graphics/RenderTypes/RenderBoundingBox.cs | 120 ++++++++++++- .../Rendering/Graphics/ShaderManager.cs | 8 +- .../Rendering/Graphics/Shaders/DebugShader.cs | 31 ++++ .../Spatial/TranslokatorSpatialGrid.cs | 163 ++++++++++++++++++ Mafia2Libs/Shaders/DebugVS.hlsl | 21 +++ 8 files changed, 341 insertions(+), 15 deletions(-) create mode 100644 Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs diff --git a/Mafia2Libs/Forms/MapEditor.cs b/Mafia2Libs/Forms/MapEditor.cs index 7e5d9fcd..05d4ab33 100644 --- a/Mafia2Libs/Forms/MapEditor.cs +++ b/Mafia2Libs/Forms/MapEditor.cs @@ -1138,7 +1138,7 @@ private void BuildRenderObjects() translokatorRoot.Nodes.Add(gridNode); dSceneTree.AddToTree(translokatorRoot); - //Graphics.SetTranslokatorGrid(SceneData.Translokator); + Graphics.SetTranslokatorGrid(SceneData.Translokator); } } diff --git a/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs b/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs index 8a6ee4d9..f71b9e66 100644 --- a/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs +++ b/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs @@ -50,7 +50,7 @@ public class GraphicsClass private DirectX11Class D3D; - private SpatialGrid translokatorGrid; + private TranslokatorSpatialGrid translokatorGrid; private SpatialGrid[] navigationGrids; // Local batches for objects passed through @@ -68,7 +68,7 @@ public GraphicsClass() Profile = new Profiler(); Assets = new Dictionary(); selectionBox = new RenderBoundingBox(); - translokatorGrid = new SpatialGrid(); + translokatorGrid = new TranslokatorSpatialGrid(); navigationGrids = new SpatialGrid[0]; OurPrimitiveManager = new PrimitiveManager(); @@ -153,11 +153,11 @@ public bool InitScene(int width, int height) return true; } - public TreeNode SetTranslokatorGrid(TranslokatorLoader translokator) + public void SetTranslokatorGrid(TranslokatorLoader translokator) { - translokatorGrid = new SpatialGrid(this, translokator); + translokatorGrid = new TranslokatorSpatialGrid(translokator); translokatorGrid.Initialise(D3D.Device, D3D.DeviceContext); - return translokatorGrid.GetTreeNodes(); + //return translokatorGrid.GetTreeNodes(); } public TreeNode SetNavigationGrid(ResourceTypes.Navigation.OBJData[] data) diff --git a/Mafia2Libs/Rendering/Graphics/RenderTypes/IRenderer.cs b/Mafia2Libs/Rendering/Graphics/RenderTypes/IRenderer.cs index e83c21cd..efe56f8a 100644 --- a/Mafia2Libs/Rendering/Graphics/RenderTypes/IRenderer.cs +++ b/Mafia2Libs/Rendering/Graphics/RenderTypes/IRenderer.cs @@ -15,6 +15,7 @@ public abstract class IRenderer protected ID3D11ShaderResourceView instanceBufferView; public bool DoRender { get; set; } + public bool DoRenderInstancesOnly { get; set; } public Matrix4x4 Transform { get; protected set; } public BoundingBox BoundingBox { get; protected set; } diff --git a/Mafia2Libs/Rendering/Graphics/RenderTypes/RenderBoundingBox.cs b/Mafia2Libs/Rendering/Graphics/RenderTypes/RenderBoundingBox.cs index db0471ca..c9621e64 100644 --- a/Mafia2Libs/Rendering/Graphics/RenderTypes/RenderBoundingBox.cs +++ b/Mafia2Libs/Rendering/Graphics/RenderTypes/RenderBoundingBox.cs @@ -1,5 +1,9 @@ -using System.Numerics; +using Rendering.Core; +using System; +using System.Collections.Generic; +using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Vortice; using Vortice.Direct3D; using Vortice.Direct3D11; @@ -22,6 +26,7 @@ public class RenderBoundingBox : IRenderer private VertexLayouts.BasicLayout.Vertex[] vertices; private Color CurrentColour; private Color UnselectedColour; + private List InstanceTransforms = new(); public RenderBoundingBox() { @@ -73,6 +78,73 @@ public override void InitBuffers(ID3D11Device d3d, ID3D11DeviceContext deviceCon { vertexBuffer = d3d.CreateBuffer(BindFlags.VertexBuffer, vertices, 0, ResourceUsage.Dynamic, CpuAccessFlags.Write); indexBuffer = d3d.CreateBuffer(BindFlags.IndexBuffer, Indices, 0, ResourceUsage.Dynamic, CpuAccessFlags.Write); + + InitInstanceBuffer(d3d); + } + + public void InitInstanceBuffer(ID3D11Device d3d) + { + int newSize = InstanceTransforms.Count * Marshal.SizeOf(); + + if (InstanceTransforms.Count == 0) + { + return; + } + + // Create or update buffer only if necessary + if (instanceBuffer == null || instanceBuffer.Description.SizeInBytes < newSize) + { + // Buffer description for instance buffer + var bufferDescription = new BufferDescription + { + SizeInBytes = newSize, + Usage = ResourceUsage.Dynamic, + BindFlags = BindFlags.ShaderResource, + OptionFlags = ResourceOptionFlags.BufferStructured, + CpuAccessFlags = CpuAccessFlags.Write, + StructureByteStride = Marshal.SizeOf(), + }; + + var viewDescription = new ShaderResourceViewDescription() + { + Format = Vortice.DXGI.Format.Unknown, + ViewDimension = ShaderResourceViewDimension.Buffer, + }; + + viewDescription.Buffer.FirstElement = 0; + viewDescription.Buffer.NumElements = InstanceTransforms.Count; + + // Dispose old buffer if necessary + instanceBuffer?.Dispose(); + + // Convert list to array + Matrix4x4[] transformsArray = InstanceTransforms.ToArray(); + + // Pin the array in memory + GCHandle handle = GCHandle.Alloc(transformsArray, GCHandleType.Pinned); + try + { + IntPtr pointer = handle.AddrOfPinnedObject(); + // Update the instance buffer + instanceBuffer = d3d.CreateBuffer(bufferDescription, pointer); + + instanceBufferView = d3d.CreateShaderResourceView(instanceBuffer, viewDescription); + } + finally + { + handle.Free(); + } + } + } + + public void ReloadInstanceBuffer(ID3D11Device d3d) + { + instanceBuffer?.Dispose(); + instanceBuffer = null; + instanceBufferView?.Dispose(); + instanceBufferView = null; + + InitInstanceBuffer(d3d); } public void SetColour(Color newColour, bool update = false) @@ -95,18 +167,51 @@ public override void Render(ID3D11Device device, ID3D11DeviceContext deviceConte return; } + bool BuffersSet = false; + + if (InstanceTransforms.Count > 0) + { + VertexBufferView VertexBufferView = new VertexBufferView(vertexBuffer, Unsafe.SizeOf(), 0); + deviceContext.IASetVertexBuffers(0, VertexBufferView); + deviceContext.IASetIndexBuffer(indexBuffer, Vortice.DXGI.Format.R32_UInt, 0); + deviceContext.IASetPrimitiveTopology(PrimitiveTopology.LineList); + + BuffersSet = true; + + RenderInstances(deviceContext, camera, device); + } + + if (DoRenderInstancesOnly) + { + return; + } + if (!camera.CheckBBoxFrustum(Transform, BoundingBox)) return; - VertexBufferView VertexBufferView = new VertexBufferView(vertexBuffer, Unsafe.SizeOf(), 0); - deviceContext.IASetVertexBuffers(0, VertexBufferView); - deviceContext.IASetIndexBuffer(indexBuffer, Vortice.DXGI.Format.R32_UInt, 0); - deviceContext.IASetPrimitiveTopology(PrimitiveTopology.LineList); + if (!BuffersSet) + { + VertexBufferView VertexBufferView = new VertexBufferView(vertexBuffer, Unsafe.SizeOf(), 0); + deviceContext.IASetVertexBuffers(0, VertexBufferView); + deviceContext.IASetIndexBuffer(indexBuffer, Vortice.DXGI.Format.R32_UInt, 0); + deviceContext.IASetPrimitiveTopology(PrimitiveTopology.LineList); + BuffersSet = true; + } shader.SetSceneVariables(deviceContext, Transform, camera); shader.Render(deviceContext, PrimitiveTopology.LineList, ReadOnlyIndices.Length, 0); } + public void RenderInstances(ID3D11DeviceContext deviceContext, Camera camera, ID3D11Device device) + { + deviceContext.VSSetShaderResource(0, instanceBufferView); + + shader.SetSceneVariables(deviceContext, Transform, camera); + + shader.RenderInstanced(deviceContext, PrimitiveTopology.LineList, Indices.Length, 0, InstanceTransforms.Count); + Profiler.NumDrawCallsThisFrame++; + } + public override void Shutdown() { vertices = null; @@ -165,5 +270,10 @@ public VertexLayouts.BasicLayout.Vertex[] GetTransformVertices() return NewVertices; } + + public void SetInstanceTransforms(List Transforms) + { + InstanceTransforms = Transforms; + } } } \ No newline at end of file diff --git a/Mafia2Libs/Rendering/Graphics/ShaderManager.cs b/Mafia2Libs/Rendering/Graphics/ShaderManager.cs index 6dea6d1c..e06282a8 100644 --- a/Mafia2Libs/Rendering/Graphics/ShaderManager.cs +++ b/Mafia2Libs/Rendering/Graphics/ShaderManager.cs @@ -24,7 +24,7 @@ public bool Init(ID3D11Device device) DebugInitParams.Elements = VertexLayouts.BasicLayout.GetLayout(); DebugInitParams.PixelShaderFile = new ShaderInitParams.ShaderFileEntryPoint("DebugPS.hlsl", "DebugPixelShader", "ps_5_0"); DebugInitParams.VertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("DebugVS.hlsl", "DebugVertexShader", "vs_5_0"); - DefaultInitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightInstanceVertexShader", "vs_5_0"); + DebugInitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("DebugVS.hlsl", "DebugInstanceVertexShader", "vs_5_0"); DebugShader OurDebugShader = new DebugShader(device, DebugInitParams); @@ -33,7 +33,7 @@ public bool Init(ID3D11Device device) CollisionInitParams.Elements = VertexLayouts.CollisionLayout.GetLayout(); CollisionInitParams.PixelShaderFile = new ShaderInitParams.ShaderFileEntryPoint("CollisionPS.hlsl", "CollisionShader", "ps_5_0"); CollisionInitParams.VertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("CollisionVS.hlsl", "CollisionShader", "vs_5_0"); - DefaultInitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightInstanceVertexShader", "vs_5_0"); + CollisionInitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightInstanceVertexShader", "vs_5_0"); CollisionShader OurCollisionShader = new CollisionShader(device, CollisionInitParams); @@ -42,7 +42,7 @@ public bool Init(ID3D11Device device) Shader601151254_InitParams.Elements = VertexLayouts.NormalLayout.GetLayout(); Shader601151254_InitParams.PixelShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightPS.hlsl", "PS_601151254", "ps_5_0"); Shader601151254_InitParams.VertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightVertexShader", "vs_5_0"); - DefaultInitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightInstanceVertexShader", "vs_5_0"); + Shader601151254_InitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightInstanceVertexShader", "vs_5_0"); Shader_601151254 OurShader601151254 = new Shader_601151254(device, Shader601151254_InitParams); @@ -51,7 +51,7 @@ public bool Init(ID3D11Device device) Shader_50760736_InitParams.Elements = VertexLayouts.NormalLayout.GetLayout(); Shader_50760736_InitParams.PixelShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightPS.hlsl", "PS_50760736", "ps_5_0"); Shader_50760736_InitParams.VertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightVertexShader", "vs_5_0"); - DefaultInitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightInstanceVertexShader", "vs_5_0"); + Shader_50760736_InitParams.InstancedVertexShaderFile = new ShaderInitParams.ShaderFileEntryPoint("LightVS.hlsl", "LightInstanceVertexShader", "vs_5_0"); Shader_50760736 OurShader50760736 = new Shader_50760736(device, Shader_50760736_InitParams); diff --git a/Mafia2Libs/Rendering/Graphics/Shaders/DebugShader.cs b/Mafia2Libs/Rendering/Graphics/Shaders/DebugShader.cs index d9b02da2..196ef8fe 100644 --- a/Mafia2Libs/Rendering/Graphics/Shaders/DebugShader.cs +++ b/Mafia2Libs/Rendering/Graphics/Shaders/DebugShader.cs @@ -35,6 +35,37 @@ public override void Render(ID3D11DeviceContext deviceContext, PrimitiveTopology Profiler.NumDrawCallsThisFrame++; } + public override void RenderInstanced(ID3D11DeviceContext context, PrimitiveTopology type, int size, int offset, int count) + { + context.IASetInputLayout(Layout); + + // set shaders only if available + if (OurInstanceVertexShader != null) + { + context.VSSetShader(OurInstanceVertexShader); + } + + if (OurInstanceVertexShader != null) + { + context.PSSetShader(OurPixelShader); + } + + switch (type) + { + case PrimitiveTopology.LineList: + case PrimitiveTopology.TriangleList: + context.DrawIndexedInstanced(size, count, offset, 0, 0); + break; + case PrimitiveTopology.LineStrip: + //context.Draw(size, 0); + break; + default: + break; + } + + Profiler.NumDrawCallsThisFrame++; + } + public override void SetShaderParameters(ID3D11Device device, ID3D11DeviceContext context, MaterialParameters material) { //empty diff --git a/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs new file mode 100644 index 00000000..098284d3 --- /dev/null +++ b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs @@ -0,0 +1,163 @@ +using Rendering.Graphics; +using ResourceTypes.Translokator; +using System.Collections.Generic; +using System.Numerics; +using Vortice.Direct3D11; +using Vortice.Mathematics; + +namespace Rendering.Core +{ + public class TranslokatorSpatialGrid + { + // TODO: Make cells selectable and toggleable + // Right now all cells render at once and you can't see anything + + private BoundingBox gridBounds; + private BoundingBox[] cellBounds = new BoundingBox[0]; + private RenderBoundingBox boundingBox; + private RenderBoundingBox[] cellBoundingBox = new RenderBoundingBox[0]; + private bool bIsReady = false; + public TranslokatorSpatialGrid() + { + + } + + public TranslokatorSpatialGrid(TranslokatorLoader translokator) + { + bIsReady = true; + + gridBounds = translokator.Bounds; + Vector3 origin = gridBounds.Min; + + cellBounds = new BoundingBox[translokator.Grids.Length]; + cellBoundingBox = new RenderBoundingBox[translokator.Grids.Length]; + + for (int k = 0; k < translokator.Grids.Length; k++) + { + List CellTransforms = new(); + + int width = translokator.Grids[k].Width; + int height = translokator.Grids[k].Height; + var cellSize = translokator.Grids[k].CellSize; + + Vector3 Min = new Vector3(0.0f); + Vector3 Max = new Vector3(cellSize.X, cellSize.Y, gridBounds.Depth); + + cellBounds[k] = new(Min, Max); + cellBoundingBox[k] = new(); + + for (int i = 0; i < height; i++) + { + for (int x = 0; x < width; x++) + { + Vector3 Position = new Vector3(origin.X + cellSize.X * x, origin.Y + cellSize.Y * i, origin.Z); + Matrix4x4 transform = Matrix4x4.Identity; + transform.Translation = Position; + CellTransforms.Add(Matrix4x4.Transpose(transform)); + } + } + + cellBoundingBox[k].SetInstanceTransforms(CellTransforms); + } + + + /*for (int i = 0; i != translokator.ObjectGroups.Length; i++) + { + ObjectGroup objectGroup = translokator.ObjectGroups[i]; + + for (int x = 0; x != objectGroup.NumObjects; x++) + { + ResourceTypes.Translokator.Object obj = objectGroup.Objects[x]; + + for (int y = 0; y != obj.NumInstances; y++) + { + Instance instance = obj.Instances[y]; + var cell = GetCell(instance.Position); + RenderBoundingBox box = new RenderBoundingBox(); + box.SetTransform(Matrix4x4.CreateTranslation(instance.Position)); + box.Init(new BoundingBox(-Vector3.One, Vector3.One)); + cells[cell].AddAsset(box, RefManager.GetNewRefID()); + } + } + }*/ + } + + public void Initialise(ID3D11Device device, ID3D11DeviceContext deviceContext) + { + if (bIsReady) + { + boundingBox = new RenderBoundingBox(); + boundingBox.SetColour(System.Drawing.Color.Red, true); + boundingBox.Init(gridBounds); + boundingBox.InitBuffers(device, deviceContext); + + + for (int i = 0; i < cellBoundingBox.Length; i++) + { + cellBoundingBox[i].SetColour(System.Drawing.Color.Blue, true); + cellBoundingBox[i].Init(cellBounds[i]); + cellBoundingBox[i].InitBuffers(device, deviceContext); + cellBoundingBox[i].DoRenderInstancesOnly = true; + } + } + } + + public void Render(ID3D11Device device, ID3D11DeviceContext deviceContext, Camera camera) + { + foreach (var cell in cellBoundingBox) + { + cell.Render(device, deviceContext, camera); + //break; + } + + boundingBox.Render(device, deviceContext, camera); + } + + public void Shutdown() + { + boundingBox?.Shutdown(); + + foreach (var cell in cellBoundingBox) + { + cell?.Shutdown(); + } + } + + //private int GetCell(Vector3 position) + //{ + // var offsetX = position.X - origin.X; + // var offsetY = position.Y - origin.Y; + // var gridX = Math.Abs(Math.Floor(offsetX / cellSize.X)); + // var gridY = Math.Abs(Math.Floor(offsetY / cellSize.Y)); + // var intX = Convert.ToUInt32(Math.Min(gridX, width - 1)); + // var intY = Convert.ToUInt32(Math.Min(gridY, height - 1)); + // return (int)(intX + (int)(intY * width)); + //} + + //public void SetSelectedCell(int index) + //{ + // currentCell = index; + //} + + //public TreeNode GetTreeNodes() + //{ + // TreeNode[] ChildCells = new TreeNode[cells.Length]; + // + // for (int i = 0; i < cells.Length; i++) + // { + // TreeNode Child = new TreeNode(); + // Child.Text = string.Format("CELL {0}", i); + // Child.Name = cells[i].GetRefID().ToString(); + // Child.Tag = cells[i]; + // ChildCells[i] = Child; + // } + // + // TreeNode Parent = new TreeNode(); + // Parent.Text = string.Format("Parent"); + // Parent.Tag = this; + // Parent.Nodes.AddRange(ChildCells); + // + // return Parent; + //} + } +} diff --git a/Mafia2Libs/Shaders/DebugVS.hlsl b/Mafia2Libs/Shaders/DebugVS.hlsl index d8f1328e..84358f11 100644 --- a/Mafia2Libs/Shaders/DebugVS.hlsl +++ b/Mafia2Libs/Shaders/DebugVS.hlsl @@ -4,6 +4,9 @@ cbuffer MatrixBuffer matrix viewProjectionMatrix; }; +// Instance transformation matrix buffer +StructuredBuffer InstanceBuffer : register(t0); + struct VS_INPUT { float4 Position : POSITION; @@ -28,5 +31,23 @@ VS_OUTPUT DebugVertexShader(VS_INPUT input) output.Position = mul(output.Position, viewProjectionMatrix); output.Colour = input.Colour.bgra; + return output; +} + +VS_OUTPUT DebugInstanceVertexShader(VS_INPUT input, uint InstanceId : SV_InstanceID) +{ + VS_OUTPUT output; + + // Fetch the instance transformation matrix using InstanceID + matrix instanceMatrix = InstanceBuffer[InstanceId]; + + // Change the position vector to be 4 units for proper matrix calculations. + input.Position.w = 1.0f; + + // Calculate the position of the vertex against the instance, view, and projection matrices. + output.Position = mul(input.Position, instanceMatrix); + output.Position = mul(output.Position, viewProjectionMatrix); + output.Colour = input.Colour.bgra; + return output; } \ No newline at end of file From 8d4e455be3a60635f5306df8ef034c2c5783e213 Mon Sep 17 00:00:00 2001 From: Kamzik123 Date: Tue, 3 Dec 2024 19:03:04 +0100 Subject: [PATCH 2/4] Made grids render only when their node is checked --- Mafia2Libs/Forms/MapEditor.cs | 14 ++++++++-- .../Rendering/Graphics/GraphicsClass.cs | 5 ++++ .../Spatial/TranslokatorSpatialGrid.cs | 27 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Mafia2Libs/Forms/MapEditor.cs b/Mafia2Libs/Forms/MapEditor.cs index 05d4ab33..41eb7d07 100644 --- a/Mafia2Libs/Forms/MapEditor.cs +++ b/Mafia2Libs/Forms/MapEditor.cs @@ -362,9 +362,18 @@ private void UpdateAssetVisualisation(TreeNode node, TreeNode parent) // Update rendered counterpart int refID = (bIsFrame) ? (node.Tag as FrameEntry).RefID : result; - if (!bIsFrame && node.Tag is Instance && node.Parent.Tag is Object trObject) + + if (!bIsFrame) { - UpdateInstanceVisualisation(node,trObject,node.Checked && node.CheckIfParentsAreValid()); + if (node.Tag is Instance && node.Parent.Tag is Object trObject) + { + UpdateInstanceVisualisation(node, trObject, node.Checked && node.CheckIfParentsAreValid()); + } + else if (node.Tag is Grid trGrid) + { + int trGridIndex = Array.IndexOf(SceneData.Translokator.Grids, trGrid); + Graphics.SetTranslokatorGridEnabled(trGridIndex, node.Checked && node.CheckIfParentsAreValid()); + } } else { @@ -1132,6 +1141,7 @@ private void BuildRenderObjects() Grid grid = SceneData.Translokator.Grids[i]; TreeNode child = new TreeNode("Grid " + i); child.Tag = grid; + child.Checked = false; gridNode.Nodes.Add(child); } diff --git a/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs b/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs index f71b9e66..b5463ae7 100644 --- a/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs +++ b/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs @@ -741,5 +741,10 @@ public void DeleteInstance(int InstanceRefID) { InstanceGizmo.InstanceModel.RemoveInstance(InstanceRefID,D3D.Device); } + + public void SetTranslokatorGridEnabled(int index, bool enabled) + { + translokatorGrid.SetGridEnabled(index, enabled); + } } } \ No newline at end of file diff --git a/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs index 098284d3..efa211ad 100644 --- a/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs +++ b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs @@ -90,6 +90,7 @@ public void Initialise(ID3D11Device device, ID3D11DeviceContext deviceContext) boundingBox.SetColour(System.Drawing.Color.Red, true); boundingBox.Init(gridBounds); boundingBox.InitBuffers(device, deviceContext); + boundingBox.DoRender = false; for (int i = 0; i < cellBoundingBox.Length; i++) @@ -98,12 +99,18 @@ public void Initialise(ID3D11Device device, ID3D11DeviceContext deviceContext) cellBoundingBox[i].Init(cellBounds[i]); cellBoundingBox[i].InitBuffers(device, deviceContext); cellBoundingBox[i].DoRenderInstancesOnly = true; + cellBoundingBox[i].DoRender = false; } } } public void Render(ID3D11Device device, ID3D11DeviceContext deviceContext, Camera camera) { + if (!bIsReady) + { + return; + } + foreach (var cell in cellBoundingBox) { cell.Render(device, deviceContext, camera); @@ -159,5 +166,25 @@ public void Shutdown() // // return Parent; //} + + public void SetGridEnabled(int index, bool enabled) + { + if (index < cellBoundingBox.Length) + { + cellBoundingBox[index].DoRender = enabled; + } + + // We want to render the general bounding box only if one or more grids is enabled + boundingBox.DoRender = false; + + foreach (var cell in cellBoundingBox) + { + if (cell.DoRender) + { + boundingBox.DoRender = true; + break; + } + } + } } } From 688066d3559658458ee2c0af8ed21e57f15a8ad9 Mon Sep 17 00:00:00 2001 From: Kamzik123 Date: Tue, 3 Dec 2024 20:32:38 +0100 Subject: [PATCH 3/4] Added automatic translokator grids render update The grids now update accordingly when editing their properties, they also update when enabling a grid. --- Mafia2Libs/Forms/MapEditor.cs | 46 ++++++++++++++++-- .../Rendering/Graphics/GraphicsClass.cs | 5 +- .../Spatial/TranslokatorSpatialGrid.cs | 26 ++-------- .../FileTypes/Translokator/Translokator.cs | 47 ++++++++++++++++++- 4 files changed, 95 insertions(+), 29 deletions(-) diff --git a/Mafia2Libs/Forms/MapEditor.cs b/Mafia2Libs/Forms/MapEditor.cs index 41eb7d07..e6518ac7 100644 --- a/Mafia2Libs/Forms/MapEditor.cs +++ b/Mafia2Libs/Forms/MapEditor.cs @@ -371,8 +371,17 @@ private void UpdateAssetVisualisation(TreeNode node, TreeNode parent) } else if (node.Tag is Grid trGrid) { - int trGridIndex = Array.IndexOf(SceneData.Translokator.Grids, trGrid); - Graphics.SetTranslokatorGridEnabled(trGridIndex, node.Checked && node.CheckIfParentsAreValid()); + bool enabled = node.Checked && node.CheckIfParentsAreValid(); + + if (enabled) + { + RebuildTranslokatorGrids(); + } + else + { + int trGridIndex = Array.IndexOf(SceneData.Translokator.Grids, trGrid); + Graphics.SetTranslokatorGridEnabled(trGridIndex, enabled); + } } } else @@ -1148,7 +1157,7 @@ private void BuildRenderObjects() translokatorRoot.Nodes.Add(gridNode); dSceneTree.AddToTree(translokatorRoot); - Graphics.SetTranslokatorGrid(SceneData.Translokator); + Graphics.BuildTranslokatorGrid(SceneData.Translokator); } } @@ -1861,6 +1870,10 @@ private void OnPropertyValueChanged(object s, PropertyValueChangedEventArgs e) Graphics.InstanceGizmo.UpdateInstanceBuffer(instance, Graphics.GetId3D11Device()); } } + if (pGrid.SelectedObject is Grid trGrid) + { + RebuildTranslokatorGrids(); + } pGrid.Refresh(); } @@ -2810,6 +2823,33 @@ private void DeleteTRObject(TreeNode objectNode) } dSceneTree.RemoveNode(objectNode); } + + private void RebuildTranslokatorGrids() + { + SceneData.Translokator.RebuildGridData(); + Graphics.BuildTranslokatorGrid(SceneData.Translokator); + + TreeNode gridsNode = null; + + foreach (TreeNode node in translokatorRoot.Nodes) + { + if (node.Text.Equals("Grids", StringComparison.InvariantCultureIgnoreCase)) + { + gridsNode = node; + break; + } + } + + for (int i = 0; i < gridsNode.Nodes.Count; i++) + { + TreeNode child = gridsNode.Nodes[i]; + + if (child.Tag is Grid) + { + Graphics.SetTranslokatorGridEnabled(i, child.Checked && child.CheckIfParentsAreValid()); + } + } + } } } diff --git a/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs b/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs index b5463ae7..1a59641e 100644 --- a/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs +++ b/Mafia2Libs/Rendering/Graphics/GraphicsClass.cs @@ -153,11 +153,10 @@ public bool InitScene(int width, int height) return true; } - public void SetTranslokatorGrid(TranslokatorLoader translokator) + public void BuildTranslokatorGrid(TranslokatorLoader translokator) { - translokatorGrid = new TranslokatorSpatialGrid(translokator); + translokatorGrid.Build(translokator); translokatorGrid.Initialise(D3D.Device, D3D.DeviceContext); - //return translokatorGrid.GetTreeNodes(); } public TreeNode SetNavigationGrid(ResourceTypes.Navigation.OBJData[] data) diff --git a/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs index efa211ad..171ba29e 100644 --- a/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs +++ b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs @@ -23,6 +23,11 @@ public TranslokatorSpatialGrid() } public TranslokatorSpatialGrid(TranslokatorLoader translokator) + { + Build(translokator); + } + + public void Build(TranslokatorLoader translokator) { bIsReady = true; @@ -59,27 +64,6 @@ public TranslokatorSpatialGrid(TranslokatorLoader translokator) cellBoundingBox[k].SetInstanceTransforms(CellTransforms); } - - - /*for (int i = 0; i != translokator.ObjectGroups.Length; i++) - { - ObjectGroup objectGroup = translokator.ObjectGroups[i]; - - for (int x = 0; x != objectGroup.NumObjects; x++) - { - ResourceTypes.Translokator.Object obj = objectGroup.Objects[x]; - - for (int y = 0; y != obj.NumInstances; y++) - { - Instance instance = obj.Instances[y]; - var cell = GetCell(instance.Position); - RenderBoundingBox box = new RenderBoundingBox(); - box.SetTransform(Matrix4x4.CreateTranslation(instance.Position)); - box.Init(new BoundingBox(-Vector3.One, Vector3.One)); - cells[cell].AddAsset(box, RefManager.GetNewRefID()); - } - } - }*/ } public void Initialise(ID3D11Device device, ID3D11DeviceContext deviceContext) diff --git a/Mafia2Libs/ResourceTypes/FileTypes/Translokator/Translokator.cs b/Mafia2Libs/ResourceTypes/FileTypes/Translokator/Translokator.cs index 4aa55cc1..56ed210c 100644 --- a/Mafia2Libs/ResourceTypes/FileTypes/Translokator/Translokator.cs +++ b/Mafia2Libs/ResourceTypes/FileTypes/Translokator/Translokator.cs @@ -30,12 +30,12 @@ public short Key { get { return key; } set { key = value; } } - [TypeConverter(typeof(Vector3Converter))] + [TypeConverter(typeof(Vector3Converter)), ReadOnly(true)] public Vector3 Origin { get { return origin; } set { origin = value; } } - [TypeConverter(typeof(Vector2Converter))] + [TypeConverter(typeof(Vector2Converter)), ReadOnly(true)] public Vector2 CellSize { get { return cellSize; } set { cellSize = value; } @@ -573,6 +573,49 @@ private void CompileData() #endregion encode instance data / build grid } + public void RebuildGridData() + { + for (int i = 0; i < Grids.Length; i++) + { + var grid = Grids[i]; + grid.CellSize = new Vector2(bounds.GetWidth() / grid.Width, bounds.GetHeight() / grid.Height); + grid.Data = new ushort[grid.Width * grid.Height]; + grid.Origin = bounds.Min; + } + + for (int i = 0; i < ObjectGroups.Length; i++) + { + ObjectGroup objectGroup = ObjectGroups[i]; + + for (int x = 0; x < objectGroup.Objects.Length; x++) + { + Object obj = objectGroup.Objects[x]; + + for (int y = 0; y < obj.Instances.Length; y++) + { + Instance instance = obj.Instances[y]; + + for (int a = 0; a < Grids.Length; a++) + { + var grid = Grids[a]; + + if (obj.GridMax == grid.Key) + { + var offsetX = instance.Position.X - grid.Origin.X; + var offsetY = instance.Position.Y - grid.Origin.Y; + + var gridX = (ushort)Math.Abs(Math.Floor(offsetX / grid.CellSize.X)); + var gridY = (ushort)Math.Abs(Math.Floor(offsetY / grid.CellSize.Y)); + gridX = (ushort)Math.Min(gridX, grid.Width - 1); + gridY = (ushort)Math.Min(gridY, grid.Height - 1); + grid.Data[gridX + (gridY * grid.Width)]++; + } + } + } + } + } + } + public void ReadFromFile(BinaryReader reader) { From 5f7574e7a2f8377e953b1413e28430b7a8923a43 Mon Sep 17 00:00:00 2001 From: Kamzik123 Date: Wed, 4 Dec 2024 17:29:21 +0100 Subject: [PATCH 4/4] Cleanup --- .../Spatial/TranslokatorSpatialGrid.cs | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs index 171ba29e..541c6203 100644 --- a/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs +++ b/Mafia2Libs/Rendering/Spatial/TranslokatorSpatialGrid.cs @@ -9,9 +9,6 @@ namespace Rendering.Core { public class TranslokatorSpatialGrid { - // TODO: Make cells selectable and toggleable - // Right now all cells render at once and you can't see anything - private BoundingBox gridBounds; private BoundingBox[] cellBounds = new BoundingBox[0]; private RenderBoundingBox boundingBox; @@ -98,7 +95,6 @@ public void Render(ID3D11Device device, ID3D11DeviceContext deviceContext, Camer foreach (var cell in cellBoundingBox) { cell.Render(device, deviceContext, camera); - //break; } boundingBox.Render(device, deviceContext, camera); @@ -114,43 +110,6 @@ public void Shutdown() } } - //private int GetCell(Vector3 position) - //{ - // var offsetX = position.X - origin.X; - // var offsetY = position.Y - origin.Y; - // var gridX = Math.Abs(Math.Floor(offsetX / cellSize.X)); - // var gridY = Math.Abs(Math.Floor(offsetY / cellSize.Y)); - // var intX = Convert.ToUInt32(Math.Min(gridX, width - 1)); - // var intY = Convert.ToUInt32(Math.Min(gridY, height - 1)); - // return (int)(intX + (int)(intY * width)); - //} - - //public void SetSelectedCell(int index) - //{ - // currentCell = index; - //} - - //public TreeNode GetTreeNodes() - //{ - // TreeNode[] ChildCells = new TreeNode[cells.Length]; - // - // for (int i = 0; i < cells.Length; i++) - // { - // TreeNode Child = new TreeNode(); - // Child.Text = string.Format("CELL {0}", i); - // Child.Name = cells[i].GetRefID().ToString(); - // Child.Tag = cells[i]; - // ChildCells[i] = Child; - // } - // - // TreeNode Parent = new TreeNode(); - // Parent.Text = string.Format("Parent"); - // Parent.Tag = this; - // Parent.Nodes.AddRange(ChildCells); - // - // return Parent; - //} - public void SetGridEnabled(int index, bool enabled) { if (index < cellBoundingBox.Length)