diff --git a/src/DotRecast.Core/ByteBuffer.cs b/src/DotRecast.Core/ByteBuffer.cs index b487b98..a3caa9c 100644 --- a/src/DotRecast.Core/ByteBuffer.cs +++ b/src/DotRecast.Core/ByteBuffer.cs @@ -122,6 +122,15 @@ namespace DotRecast.Core public void putFloat(float v) { + // if (_order == ByteOrder.BIG_ENDIAN) + // { + // BinaryPrimitives.WriteInt32BigEndian(_bytes[_position]); + // } + // else + // { + // BinaryPrimitives.ReadInt64LittleEndian(span); + // } + // ? } diff --git a/src/DotRecast.Core/Loader.cs b/src/DotRecast.Core/Loader.cs index b9589ea..d97ac45 100644 --- a/src/DotRecast.Core/Loader.cs +++ b/src/DotRecast.Core/Loader.cs @@ -27,7 +27,7 @@ namespace DotRecast.Core filePath = Path.Combine("..", filePath); } - return filename; + return Path.GetFullPath(filename); } } } \ No newline at end of file diff --git a/src/DotRecast.Recast.Demo/Draw/GLU.cs b/src/DotRecast.Recast.Demo/Draw/GLU.cs index 9766a8a..50b79af 100644 --- a/src/DotRecast.Recast.Demo/Draw/GLU.cs +++ b/src/DotRecast.Recast.Demo/Draw/GLU.cs @@ -18,6 +18,7 @@ freely, subject to the following restrictions: using System; using DotRecast.Core; +using Silk.NET.OpenGL; namespace DotRecast.Recast.Demo.Draw; diff --git a/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs b/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs index bf92fc0..cb0f372 100644 --- a/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs +++ b/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs @@ -1,9 +1,15 @@ using System; +using System.Buffers; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Runtime.InteropServices; +using DotRecast.Core; +using ImGuiNET; using Microsoft.DotNet.PlatformAbstractions; using Silk.NET.OpenGL; using Silk.NET.Windowing; +using Buffer = Silk.NET.OpenGL.Buffer; namespace DotRecast.Recast.Demo.Draw; @@ -30,7 +36,7 @@ public class ModernOpenGLDraw : OpenGLDraw private int uniformFogStart; private int uniformFogEnd; - public void init(GL gl) + public unsafe void init(GL gl) { _gl = gl; string NK_SHADER_VERSION = PlatformID.MacOSX == Environment.OSVersion.Platform ? "#version 150\n" : "#version 300 es\n"; @@ -116,13 +122,19 @@ public class ModernOpenGLDraw : OpenGLDraw _gl.EnableVertexAttribArray(attrib_uv); _gl.EnableVertexAttribArray(attrib_col); - // _gl.VertexAttribPointer(attrib_pos, 3, GLEnum.Float, false, 24, 0); - // _gl.VertexAttribPointer(attrib_uv, 2, GLEnum.Float, false, 24, 12); - // _gl.VertexAttribPointer(attrib_col, 4, GLEnum.UnsignedByte, true, 24, 20); + // _gl.VertexAttribP3(attrib_pos, GLEnum.Float, false, 24); + // _gl.VertexAttribP2(attrib_pos, GLEnum.Float, false, 24); + // _gl.VertexAttribP4(attrib_pos, GLEnum.UnsignedByte, true, 24); + IntPtr pointer1 = 0; + IntPtr pointer2 = 12; + IntPtr pointer3 = 20; + _gl.VertexAttribPointer(attrib_pos, 3, GLEnum.Float, false, 24, pointer1.ToPointer()); + _gl.VertexAttribPointer(attrib_uv, 2, GLEnum.Float, false, 24, pointer2.ToPointer()); + _gl.VertexAttribPointer(attrib_col, 4, GLEnum.UnsignedByte, true, 24, pointer3.ToPointer()); - _gl.VertexAttribP3(attrib_pos, GLEnum.Float, false, 0); - _gl.VertexAttribP2(attrib_uv, GLEnum.Float, false, 12); - _gl.VertexAttribP4(attrib_col, GLEnum.UnsignedByte, true, 20); + // _gl.VertexAttribP3(attrib_pos, GLEnum.Float, false, 0); + // _gl.VertexAttribP2(attrib_uv, GLEnum.Float, false, 12); + // _gl.VertexAttribP4(attrib_col, GLEnum.UnsignedByte, true, 20); _gl.BindTexture(GLEnum.Texture2D, 0); _gl.BindBuffer(GLEnum.ArrayBuffer, 0); @@ -149,57 +161,74 @@ public class ModernOpenGLDraw : OpenGLDraw _gl.PointSize(size); } - public void end() + public unsafe void end() { - // if (vertices.isEmpty()) { - // return; - // } - // glUseProgram(program); - // glUniform1i(uniformTexture, 0); - // glUniformMatrix4fv(uniformViewMatrix, false, viewMatrix); - // glUniformMatrix4fv(uniformProjectionMatrix, false, projectionMatrix); - // glUniform1f(uniformFogStart, fogStart); - // glUniform1f(uniformFogEnd, fogEnd); - // glUniform1f(uniformFog, fogEnabled ? 1.0f : 0.0f); - // glBindVertexArray(vao); - // glBindBuffer(GL_ARRAY_BUFFER, vbo); - // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - // // glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_BUFFER, GL_STREAM_DRAW); - // // glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_BUFFER, GL_STREAM_DRAW); - // - // int vboSize = vertices.size() * 24; - // int eboSize = currentPrim == DebugDrawPrimitives.QUADS ? vertices.size() * 6 : vertices.size() * 4; - // - // glBufferData(GL_ARRAY_BUFFER, vboSize, GL_STREAM_DRAW); - // glBufferData(GL_ELEMENT_ARRAY_BUFFER, eboSize, GL_STREAM_DRAW); - // // load draw vertices & elements directly into vertex + element buffer - // ByteBuffer verts = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY, vboSize, null); - // ByteBuffer elems = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY, eboSize, null); - // vertices.forEach(v => v.store(verts)); - // if (currentPrim == DebugDrawPrimitives.QUADS) { - // for (int i = 0; i < vertices.size(); i += 4) { - // elems.putInt(i); - // elems.putInt(i + 1); - // elems.putInt(i + 2); - // elems.putInt(i); - // elems.putInt(i + 2); - // elems.putInt(i + 3); - // } - // - // } else { - // for (int i = 0; i < vertices.size(); i++) { - // elems.putInt(i); - // } - // } - // - // glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - // glUnmapBuffer(GL_ARRAY_BUFFER); - // if (texture != null) { - // texture.bind(); - // glUniform1f(uniformUseTexture, 1.0f); - // } else { - // glUniform1f(uniformUseTexture, 0.0f); - // } + if (0 >= vertices.Count) + { + return; + } + + _gl.UseProgram(program); + _gl.Uniform1(uniformTexture, 0); + _gl.UniformMatrix4(uniformViewMatrix, false, _viewMatrix); + _gl.UniformMatrix4(uniformProjectionMatrix, false, _projectionMatrix); + _gl.Uniform1(uniformFogStart, fogStart); + _gl.Uniform1(uniformFogEnd, fogEnd); + _gl.Uniform1(uniformFog, fogEnabled ? 1.0f : 0.0f); + _gl.BindVertexArray(vao); + _gl.BindBuffer(GLEnum.ArrayBuffer, vbo); + _gl.BindBuffer(GLEnum.ElementArrayBuffer, ebo); + // glBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_BUFFER, GL_STREAM_DRAW); + // glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_BUFFER, GL_STREAM_DRAW); + + int vboSize = vertices.Count * 24; + int eboSize = currentPrim == DebugDrawPrimitives.QUADS ? vertices.Count * 6 : vertices.Count * 4; + // var ssss = new byte[vboSize]; + // var ssss2 = new byte[eboSize]; + + _gl.BufferData(GLEnum.ArrayBuffer, (nuint)vboSize, IntPtr.Zero, GLEnum.StreamDraw); + _gl.BufferData(GLEnum.ElementArrayBuffer, (nuint)eboSize, IntPtr.Zero, GLEnum.StreamDraw); + // load draw vertices & elements directly into vertex + element buffer + byte* pVerts = (byte*)_gl.MapBuffer(GLEnum.ArrayBuffer, GLEnum.WriteOnly); + byte* pElems = (byte*)_gl.MapBuffer(GLEnum.ElementArrayBuffer, GLEnum.WriteOnly); + + { + using var verts = new UnmanagedMemoryStream(pVerts, vboSize, vboSize, FileAccess.Write); + using var elems = new UnmanagedMemoryStream(pElems, eboSize, eboSize, FileAccess.Write); + + vertices.forEach(v => v.store(verts)); + if (currentPrim == DebugDrawPrimitives.QUADS) + { + for (int i = 0; i < vertices.Count; i += 4) + { + elems.Write(BitConverter.GetBytes(i)); + elems.Write(BitConverter.GetBytes(i + 1)); + elems.Write(BitConverter.GetBytes(i + 2)); + elems.Write(BitConverter.GetBytes(i)); + elems.Write(BitConverter.GetBytes(i + 2)); + elems.Write(BitConverter.GetBytes(i + 3)); + } + } + else + { + for (int i = 0; i < vertices.Count; i++) + { + elems.Write(BitConverter.GetBytes(i)); + } + } + + _gl.UnmapBuffer(GLEnum.ElementArrayBuffer); + _gl.UnmapBuffer(GLEnum.ArrayBuffer); + } + if (_texture != null) + { + _texture.bind(); + _gl.Uniform1(uniformUseTexture, 1.0f); + } + else + { + _gl.Uniform1(uniformUseTexture, 0.0f); + } // // switch (currentPrim) { // case POINTS: @@ -217,14 +246,14 @@ public class ModernOpenGLDraw : OpenGLDraw // default: // break; // } - // - // glUseProgram(0); - // glBindBuffer(GL_ARRAY_BUFFER, 0); - // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - // glBindVertexArray(0); - // vertices.clear(); - // glLineWidth(1.0f); - // glPointSize(1.0f); + + _gl.UseProgram(0); + _gl.BindBuffer(GLEnum.ArrayBuffer, 0); + _gl.BindBuffer(GLEnum.ElementArrayBuffer, 0); + _gl.BindVertexArray(0); + vertices.Clear(); + _gl.LineWidth(1.0f); + _gl.PointSize(1.0f); } public void vertex(float x, float y, float z, int color) diff --git a/src/DotRecast.Recast.Demo/Draw/OpenGLVertex.cs b/src/DotRecast.Recast.Demo/Draw/OpenGLVertex.cs index 294ab1a..215f477 100644 --- a/src/DotRecast.Recast.Demo/Draw/OpenGLVertex.cs +++ b/src/DotRecast.Recast.Demo/Draw/OpenGLVertex.cs @@ -1,3 +1,5 @@ +using System; +using System.IO; using DotRecast.Core; namespace DotRecast.Recast.Demo.Draw; @@ -36,13 +38,13 @@ public class OpenGLVertex this.color = color; } - public void store(ByteBuffer buffer) + public void store(Stream writer) { - buffer.putFloat(x); - buffer.putFloat(y); - buffer.putFloat(z); - buffer.putFloat(u); - buffer.putFloat(v); - buffer.putInt(color); + writer.Write(BitConverter.GetBytes(x)); + writer.Write(BitConverter.GetBytes(y)); + writer.Write(BitConverter.GetBytes(z)); + writer.Write(BitConverter.GetBytes(u)); + writer.Write(BitConverter.GetBytes(v)); + writer.Write(BitConverter.GetBytes(color)); } } \ No newline at end of file diff --git a/src/DotRecast.Recast.Demo/Program.cs b/src/DotRecast.Recast.Demo/Program.cs index c0a24a0..8dd48f5 100644 --- a/src/DotRecast.Recast.Demo/Program.cs +++ b/src/DotRecast.Recast.Demo/Program.cs @@ -1,9 +1,21 @@ -namespace DotRecast.Recast.Demo; +using System.IO; +using DotRecast.Core; + +namespace DotRecast.Recast.Demo; public static class Program { public static void Main(string[] args) { + var path = Loader.ToRPath("dungeon.obj"); + path = Path.GetDirectoryName(path); + if (!string.IsNullOrEmpty(path)) + { + var workingDirectory = Path.Combine(path, ".."); + workingDirectory = Path.GetFullPath(workingDirectory); + Directory.SetCurrentDirectory(workingDirectory); + } + var demo = new RecastDemo(); demo.start(); } diff --git a/src/DotRecast.Recast.Demo/RecastDemo.cs b/src/DotRecast.Recast.Demo/RecastDemo.cs index c9b3864..f1977e4 100644 --- a/src/DotRecast.Recast.Demo/RecastDemo.cs +++ b/src/DotRecast.Recast.Demo/RecastDemo.cs @@ -19,10 +19,13 @@ freely, subject to the following restrictions: */ using System; +using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using System.IO; using System.Linq; using System.Numerics; +using System.Runtime.InteropServices; using Serilog; using Silk.NET.Input; using Silk.NET.Maths; @@ -40,6 +43,7 @@ using DotRecast.Recast.Demo.Geom; using DotRecast.Recast.Demo.Settings; using DotRecast.Recast.Demo.Tools; using DotRecast.Recast.Demo.UI; +using Silk.NET.SDL; using Silk.NET.Windowing.Sdl; using static DotRecast.Detour.DetourCommon; using Color = System.Drawing.Color; @@ -55,6 +59,7 @@ public class RecastDemo : MouseListener private IInputContext _input; private ImGuiController _imgui; private GL _gl; + private Sdl _sdl; private int width = 1000; private int height = 900; @@ -69,7 +74,7 @@ public class RecastDemo : MouseListener private readonly SoloNavMeshBuilder soloNavMeshBuilder = new SoloNavMeshBuilder(); private readonly TileNavMeshBuilder tileNavMeshBuilder = new TileNavMeshBuilder(); - //private Sample sample; + private Sample sample; private bool processHitTest = false; private bool processHitTestShift; @@ -95,15 +100,15 @@ public class RecastDemo : MouseListener private bool markerPositionSet; private readonly float[] markerPosition = new float[3]; - private ToolsView _toolsView; - private RcSettingsView _rcSettingsView; + private ToolsView toolsUI; + private RcSettingsView settingsUI; private long prevFrameTime; private RecastDebugDraw dd; public RecastDemo() { - //dd = new RecastDebugDraw(); - // renderer = new NavMeshRenderer(dd); + dd = new RecastDebugDraw(); + renderer = new NavMeshRenderer(dd); } public void start() @@ -326,8 +331,8 @@ public class RecastDemo : MouseListener private DemoInputGeomProvider loadInputMesh(byte[] stream) { DemoInputGeomProvider geom = DemoObjImporter.load(stream); - //sample = new Sample(geom, ImmutableArray.Empty, null, settingsUI, dd); - _toolsView.setEnabled(true); + sample = new Sample(geom, ImmutableArray.Empty, null, settingsUI, dd); + toolsUI.setEnabled(true); return geom; } @@ -351,7 +356,7 @@ public class RecastDemo : MouseListener if (mesh != null) { //sample = new Sample(null, ImmutableArray.Empty, mesh, settingsUI, dd); - _toolsView.setEnabled(true); + toolsUI.setEnabled(true); } } @@ -376,11 +381,11 @@ public class RecastDemo : MouseListener private void OnWindowOnLoad() { - var s = SdlWindowing.GetExistingApi(window); + _sdl = SdlWindowing.GetExistingApi(window); _input = window.CreateInput(); _gl = window.CreateOpenGL(); - //dd.init(_gl, camr); + dd.init(_gl, camr); _imgui = new ImGuiController(_gl, window, _input); @@ -408,8 +413,8 @@ public class RecastDemo : MouseListener window.CreateInput(); - _rcSettingsView = new RcSettingsView(); - _toolsView = new ToolsView( + settingsUI = new RcSettingsView(); + toolsUI = new ToolsView( new TestNavmeshTool(), new OffMeshConnectionTool(), new ConvexVolumeTool(), @@ -418,28 +423,28 @@ public class RecastDemo : MouseListener new DynamicUpdateTool() ); - _viewSys = new RcViewSystem(window, _input, _rcSettingsView, _toolsView); + _viewSys = new RcViewSystem(window, _input, settingsUI, toolsUI); DemoInputGeomProvider geom = loadInputMesh(Loader.ToBytes("nav_test.obj")); - //sample = new Sample(geom, ImmutableArray.Empty, null, settingsUI, dd); + sample = new Sample(geom, ImmutableArray.Empty, null, settingsUI, dd); } private void OnWindowOnUpdate(double dt) { /* - * try (MemoryStack stack = stackPush()) { int[] w = stack.mallocInt(1); int[] h = - * stack.mallocInt(1); glfwGetWindowSize(win, w, h); width = w[0]; height = h[0]; } - */ - // if (sample.getInputGeom() != null) - // { - // float[] bmin = sample.getInputGeom().getMeshBoundsMin(); - // float[] bmax = sample.getInputGeom().getMeshBoundsMax(); - // int[] voxels = Recast.calcGridSize(bmin, bmax, settingsUI.getCellSize()); - // settingsUI.setVoxels(voxels); - // settingsUI.setTiles(tileNavMeshBuilder.getTiles(sample.getInputGeom(), settingsUI.getCellSize(), settingsUI.getTileSize())); - // settingsUI.setMaxTiles(tileNavMeshBuilder.getMaxTiles(sample.getInputGeom(), settingsUI.getCellSize(), settingsUI.getTileSize())); - // settingsUI.setMaxPolys(tileNavMeshBuilder.getMaxPolysPerTile(sample.getInputGeom(), settingsUI.getCellSize(), settingsUI.getTileSize())); - // } + * try (MemoryStack stack = stackPush()) { int[] w = stack.mallocInt(1); int[] h = + * stack.mallocInt(1); glfwGetWindowSize(win, w, h); width = w[0]; height = h[0]; } + */ + if (sample.getInputGeom() != null) + { + float[] bmin = sample.getInputGeom().getMeshBoundsMin(); + float[] bmax = sample.getInputGeom().getMeshBoundsMax(); + int[] voxels = Recast.calcGridSize(bmin, bmax, settingsUI.getCellSize()); + settingsUI.setVoxels(voxels); + settingsUI.setTiles(tileNavMeshBuilder.getTiles(sample.getInputGeom(), settingsUI.getCellSize(), settingsUI.getTileSize())); + settingsUI.setMaxTiles(tileNavMeshBuilder.getMaxTiles(sample.getInputGeom(), settingsUI.getCellSize(), settingsUI.getTileSize())); + settingsUI.setMaxPolys(tileNavMeshBuilder.getMaxPolysPerTile(sample.getInputGeom(), settingsUI.getCellSize(), settingsUI.getTileSize())); + } _viewSys.inputBegin(); window.DoEvents(); @@ -454,30 +459,18 @@ public class RecastDemo : MouseListener float DELTA_TIME = 1.0f / SIM_RATE; timeAcc = clamp((float)(timeAcc + dt), -1.0f, 1.0f); int simIter = 0; - // while (timeAcc > DELTA_TIME) - // { - // timeAcc -= DELTA_TIME; - // if (simIter < 5 && sample != null) - // { - // toolsUI.handleUpdate(DELTA_TIME); - // } - // - // simIter++; - // } + while (timeAcc > DELTA_TIME) + { + timeAcc -= DELTA_TIME; + if (simIter < 5 && sample != null) + { + toolsUI.handleUpdate((float)dt); + } + + simIter++; + } - // Set the viewport. - // glViewport(0, 0, width, height); - int[] viewport = new int[] { 0, 0, width, height }; - // glGetIntegerv(GL_VIEWPORT, viewport); - - // Clear the screen - // dd.clear(); - // float[] projectionMatrix = dd.projectionMatrix(50f, (float)width / (float)height, 1.0f, camr); - // float[] modelviewMatrix = dd.viewMatrix(cameraPos, cameraEulers); - - //mouseOverMenu = nuklearUI.layout(window, 0, 0, width, height, (int)mousePos[0], (int)mousePos[1]); - - if (_rcSettingsView.isMeshInputTrigerred()) + if (settingsUI.isMeshInputTrigerred()) { // aFilterPatterns.put(stack.UTF8("*.obj")); // aFilterPatterns.flip(); @@ -491,7 +484,7 @@ public class RecastDemo : MouseListener // } // } } - else if (_rcSettingsView.isNavMeshInputTrigerred()) + else if (settingsUI.isNavMeshInputTrigerred()) { // try (MemoryStack stack = stackPush()) { // PointerBuffer aFilterPatterns = stack.mallocPointer(4); @@ -515,50 +508,50 @@ public class RecastDemo : MouseListener // } // } } - // else if (settingsUI.isBuildTriggered() && sample.getInputGeom() != null) - // { - // if (!building) - // { - // float m_cellSize = settingsUI.getCellSize(); - // float m_cellHeight = settingsUI.getCellHeight(); - // float m_agentHeight = settingsUI.getAgentHeight(); - // float m_agentRadius = settingsUI.getAgentRadius(); - // float m_agentMaxClimb = settingsUI.getAgentMaxClimb(); - // float m_agentMaxSlope = settingsUI.getAgentMaxSlope(); - // int m_regionMinSize = settingsUI.getMinRegionSize(); - // int m_regionMergeSize = settingsUI.getMergedRegionSize(); - // float m_edgeMaxLen = settingsUI.getEdgeMaxLen(); - // float m_edgeMaxError = settingsUI.getEdgeMaxError(); - // int m_vertsPerPoly = settingsUI.getVertsPerPoly(); - // float m_detailSampleDist = settingsUI.getDetailSampleDist(); - // float m_detailSampleMaxError = settingsUI.getDetailSampleMaxError(); - // int m_tileSize = settingsUI.getTileSize(); - // long t = Stopwatch.GetTimestamp(); - // - // Tuple, NavMesh> buildResult; - // if (settingsUI.isTiled()) - // { - // buildResult = tileNavMeshBuilder.build(sample.getInputGeom(), settingsUI.getPartitioning(), m_cellSize, - // m_cellHeight, m_agentHeight, m_agentRadius, m_agentMaxClimb, m_agentMaxSlope, m_regionMinSize, - // m_regionMergeSize, m_edgeMaxLen, m_edgeMaxError, m_vertsPerPoly, m_detailSampleDist, - // m_detailSampleMaxError, settingsUI.isFilterLowHangingObstacles(), settingsUI.isFilterLedgeSpans(), - // settingsUI.isFilterWalkableLowHeightSpans(), m_tileSize); - // } - // else - // { - // buildResult = soloNavMeshBuilder.build(sample.getInputGeom(), settingsUI.getPartitioning(), m_cellSize, - // m_cellHeight, m_agentHeight, m_agentRadius, m_agentMaxClimb, m_agentMaxSlope, m_regionMinSize, - // m_regionMergeSize, m_edgeMaxLen, m_edgeMaxError, m_vertsPerPoly, m_detailSampleDist, - // m_detailSampleMaxError, settingsUI.isFilterLowHangingObstacles(), settingsUI.isFilterLedgeSpans(), - // settingsUI.isFilterWalkableLowHeightSpans()); - // } - // - // sample.update(sample.getInputGeom(), buildResult.Item1, buildResult.Item2); - // sample.setChanged(false); - // settingsUI.setBuildTime((Stopwatch.GetTimestamp() - t) / 1_000_000); - // toolsUI.setSample(sample); - // } - // } + else if (settingsUI.isBuildTriggered() && sample.getInputGeom() != null) + { + if (!building) + { + float m_cellSize = settingsUI.getCellSize(); + float m_cellHeight = settingsUI.getCellHeight(); + float m_agentHeight = settingsUI.getAgentHeight(); + float m_agentRadius = settingsUI.getAgentRadius(); + float m_agentMaxClimb = settingsUI.getAgentMaxClimb(); + float m_agentMaxSlope = settingsUI.getAgentMaxSlope(); + int m_regionMinSize = settingsUI.getMinRegionSize(); + int m_regionMergeSize = settingsUI.getMergedRegionSize(); + float m_edgeMaxLen = settingsUI.getEdgeMaxLen(); + float m_edgeMaxError = settingsUI.getEdgeMaxError(); + int m_vertsPerPoly = settingsUI.getVertsPerPoly(); + float m_detailSampleDist = settingsUI.getDetailSampleDist(); + float m_detailSampleMaxError = settingsUI.getDetailSampleMaxError(); + int m_tileSize = settingsUI.getTileSize(); + long t = Stopwatch.GetTimestamp(); + + Tuple, NavMesh> buildResult; + if (settingsUI.isTiled()) + { + buildResult = tileNavMeshBuilder.build(sample.getInputGeom(), settingsUI.getPartitioning(), m_cellSize, + m_cellHeight, m_agentHeight, m_agentRadius, m_agentMaxClimb, m_agentMaxSlope, m_regionMinSize, + m_regionMergeSize, m_edgeMaxLen, m_edgeMaxError, m_vertsPerPoly, m_detailSampleDist, + m_detailSampleMaxError, settingsUI.isFilterLowHangingObstacles(), settingsUI.isFilterLedgeSpans(), + settingsUI.isFilterWalkableLowHeightSpans(), m_tileSize); + } + else + { + buildResult = soloNavMeshBuilder.build(sample.getInputGeom(), settingsUI.getPartitioning(), m_cellSize, + m_cellHeight, m_agentHeight, m_agentRadius, m_agentMaxClimb, m_agentMaxSlope, m_regionMinSize, + m_regionMergeSize, m_edgeMaxLen, m_edgeMaxError, m_vertsPerPoly, m_detailSampleDist, + m_detailSampleMaxError, settingsUI.isFilterLowHangingObstacles(), settingsUI.isFilterLedgeSpans(), + settingsUI.isFilterWalkableLowHeightSpans()); + } + + sample.update(sample.getInputGeom(), buildResult.Item1, buildResult.Item2); + sample.setChanged(false); + settingsUI.setBuildTime((Stopwatch.GetTimestamp() - t) / 1_000_000); + toolsUI.setSample(sample); + } + } else { building = false; @@ -627,68 +620,60 @@ public class RecastDemo : MouseListener processHitTest = false; } - // if (sample.isChanged()) - // { - // float[] bmin = null; - // float[] bmax = null; - // if (sample.getInputGeom() != null) - // { - // bmin = sample.getInputGeom().getMeshBoundsMin(); - // bmax = sample.getInputGeom().getMeshBoundsMax(); - // } - // else if (sample.getNavMesh() != null) - // { - // float[][] bounds = NavMeshUtils.getNavMeshBounds(sample.getNavMesh()); - // bmin = bounds[0]; - // bmax = bounds[1]; - // } - // else if (0 < sample.getRecastResults().Count) - // { - // foreach (RecastBuilderResult result in sample.getRecastResults()) - // { - // if (result.getSolidHeightfield() != null) - // { - // if (bmin == null) - // { - // bmin = new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity }; - // bmax = new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity }; - // } - // - // for (int i = 0; i < 3; i++) - // { - // bmin[i] = Math.Min(bmin[i], result.getSolidHeightfield().bmin[i]); - // bmax[i] = Math.Max(bmax[i], result.getSolidHeightfield().bmax[i]); - // } - // } - // } - // } - // - // if (bmin != null && bmax != null) - // { - // camr = (float)(Math.Sqrt( - // DemoMath.sqr(bmax[0] - bmin[0]) + DemoMath.sqr(bmax[1] - bmin[1]) + DemoMath.sqr(bmax[2] - bmin[2])) - // / 2); - // cameraPos[0] = (bmax[0] + bmin[0]) / 2 + camr; - // cameraPos[1] = (bmax[1] + bmin[1]) / 2 + camr; - // cameraPos[2] = (bmax[2] + bmin[2]) / 2 + camr; - // camr *= 3; - // cameraEulers[0] = 45; - // cameraEulers[1] = -45; - // } - // - // sample.setChanged(false); - // toolsUI.setSample(sample); - // } + if (sample.isChanged()) + { + float[] bmin = null; + float[] bmax = null; + if (sample.getInputGeom() != null) + { + bmin = sample.getInputGeom().getMeshBoundsMin(); + bmax = sample.getInputGeom().getMeshBoundsMax(); + } + else if (sample.getNavMesh() != null) + { + float[][] bounds = NavMeshUtils.getNavMeshBounds(sample.getNavMesh()); + bmin = bounds[0]; + bmax = bounds[1]; + } + else if (0 < sample.getRecastResults().Count) + { + foreach (RecastBuilderResult result in sample.getRecastResults()) + { + if (result.getSolidHeightfield() != null) + { + if (bmin == null) + { + bmin = new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity }; + bmax = new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity }; + } + + for (int i = 0; i < 3; i++) + { + bmin[i] = Math.Min(bmin[i], result.getSolidHeightfield().bmin[i]); + bmax[i] = Math.Max(bmax[i], result.getSolidHeightfield().bmax[i]); + } + } + } + } + + if (bmin != null && bmax != null) + { + camr = (float)(Math.Sqrt( + DemoMath.sqr(bmax[0] - bmin[0]) + DemoMath.sqr(bmax[1] - bmin[1]) + DemoMath.sqr(bmax[2] - bmin[2])) + / 2); + cameraPos[0] = (bmax[0] + bmin[0]) / 2 + camr; + cameraPos[1] = (bmax[1] + bmin[1]) / 2 + camr; + cameraPos[2] = (bmax[2] + bmin[2]) / 2 + camr; + camr *= 3; + cameraEulers[0] = 45; + cameraEulers[1] = -45; + } + + sample.setChanged(false); + toolsUI.setSample(sample); + } + - // dd.fog(camr * 0.1f, camr * 1.25f); - // renderer.render(sample); - // Tool tool = toolsUI.getTool(); - // if (tool != null) - // { - // tool.handleRender(renderer); - // } - // - // dd.fog(false); var io = ImGui.GetIO(); @@ -702,9 +687,30 @@ public class RecastDemo : MouseListener private unsafe void OnWindowOnRender(double dt) { - _gl.ClearColor(Color.CadetBlue); - _gl.Clear(ClearBufferMask.ColorBufferBit); + // _gl.ClearColor(Color.CadetBlue); + // _gl.Clear(ClearBufferMask.ColorBufferBit); + // Set the viewport. + // glViewport(0, 0, width, height); + //_gl.Viewport(0, 0, (uint)width, (uint)height); + //int[] viewport = new int[] { 0, 0, width, height }; + // glGetIntegerv(GL_VIEWPORT, viewport); + + // Clear the screen + dd.clear(); + float[] projectionMatrix = dd.projectionMatrix(50f, (float)width / (float)height, 1.0f, camr); + float[] modelviewMatrix = dd.viewMatrix(cameraPos, cameraEulers); + + dd.fog(camr * 0.1f, camr * 1.25f); + renderer.render(sample); + Tool tool = toolsUI.getTool(); + if (tool != null) + { + tool.handleRender(renderer); + } + + dd.fog(false); + mouseOverMenu = _viewSys.render(window, 0, 0, width, height, (int)mousePos[0], (int)mousePos[1]); _imgui.Render(); diff --git a/src/DotRecast.Recast.Demo/Sample.cs b/src/DotRecast.Recast.Demo/Sample.cs index c893c72..bdc6060 100644 --- a/src/DotRecast.Recast.Demo/Sample.cs +++ b/src/DotRecast.Recast.Demo/Sample.cs @@ -31,17 +31,17 @@ public class Sample private DemoInputGeomProvider inputGeom; private NavMesh navMesh; private NavMeshQuery navMeshQuery; - private readonly RcSettingsView _rcSettingsView; + private readonly RcSettingsView _settingsView; private IList recastResults; private bool changed; public Sample(DemoInputGeomProvider inputGeom, IList recastResults, NavMesh navMesh, - RcSettingsView rcSettingsView, RecastDebugDraw debugDraw) + RcSettingsView settingsView, RecastDebugDraw debugDraw) { this.inputGeom = inputGeom; this.recastResults = recastResults; this.navMesh = navMesh; - this._rcSettingsView = rcSettingsView; + _settingsView = settingsView; setQuery(navMesh); changed = true; } @@ -68,7 +68,7 @@ public class Sample public RcSettingsView getSettingsUI() { - return _rcSettingsView; + return _settingsView; } public NavMeshQuery getNavMeshQuery()