refactor: ObjImporter, InputGeomProvider

This commit is contained in:
ikpil 2023-09-24 18:42:41 +09:00
parent c294275da4
commit 229ab3f9f5
20 changed files with 56 additions and 69 deletions

View File

@ -1,5 +1,6 @@
/*
recast4j Copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -17,24 +18,16 @@ freely, subject to the following restrictions:
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using DotRecast.Recast.Geom;
namespace DotRecast.Recast
namespace DotRecast.Core
{
public static class ObjImporter
public static class RcObjImporter
{
public static IInputGeomProvider Load(byte[] chunk)
public static RcObjImporterContext LoadContext(byte[] chunk)
{
var context = LoadContext(chunk);
return new SimpleInputGeomProvider(context.vertexPositions, context.meshFaces);
}
public static ObjImporterContext LoadContext(byte[] chunk)
{
ObjImporterContext context = new ObjImporterContext();
RcObjImporterContext context = new RcObjImporterContext();
try
{
using StreamReader reader = new StreamReader(new MemoryStream(chunk));
@ -54,7 +47,7 @@ namespace DotRecast.Recast
}
public static void ReadLine(string line, ObjImporterContext context)
public static void ReadLine(string line, RcObjImporterContext context)
{
if (line.StartsWith("v"))
{
@ -66,7 +59,7 @@ namespace DotRecast.Recast
}
}
private static void ReadVertex(string line, ObjImporterContext context)
private static void ReadVertex(string line, RcObjImporterContext context)
{
if (line.StartsWith("v "))
{
@ -95,7 +88,7 @@ namespace DotRecast.Recast
};
}
private static void ReadFace(string line, ObjImporterContext context)
private static void ReadFace(string line, RcObjImporterContext context)
{
string[] v = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (v.Length < 4)
@ -113,7 +106,7 @@ namespace DotRecast.Recast
}
}
private static int ReadFaceVertex(string face, ObjImporterContext context)
private static int ReadFaceVertex(string face, RcObjImporterContext context)
{
string[] v = face.Split("/");
return GetIndex(int.Parse(v[0]), context.vertexPositions.Count);

View File

@ -1,8 +1,8 @@
using System.Collections.Generic;
namespace DotRecast.Recast
namespace DotRecast.Core
{
public class ObjImporterContext
public class RcObjImporterContext
{
public List<float> vertexPositions = new List<float>();
public List<int> meshFaces = new List<int>();

View File

@ -43,7 +43,6 @@ using DotRecast.Recast.Toolset.Geom;
using DotRecast.Recast.Demo.Tools;
using DotRecast.Recast.Demo.UI;
using DotRecast.Recast.Toolset;
using MouseButton = Silk.NET.Input.MouseButton;
using Window = Silk.NET.Windowing.Window;
@ -298,9 +297,7 @@ public class RecastDemo : IRecastDemoChannel
private DemoInputGeomProvider LoadInputMesh(string filename)
{
var bytes = RcResources.Load(filename);
DemoInputGeomProvider geom = DemoObjImporter.Load(bytes);
DemoInputGeomProvider geom = DemoInputGeomProvider.LoadFile(filename);
_lastGeomFileName = filename;
return geom;
}

View File

@ -30,6 +30,7 @@ using DotRecast.Recast.Toolset.Gizmos;
using DotRecast.Recast.Toolset.Tools;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Demo.UI;
using DotRecast.Recast.Toolset.Geom;
using ImGuiNET;
using Serilog;
using static DotRecast.Recast.Demo.Draw.DebugDraw;
@ -88,9 +89,9 @@ public class DynamicUpdateSampleTool : ISampleTool
public DynamicUpdateSampleTool()
{
var bridgeGeom = DemoObjImporter.Load(RcResources.Load("bridge.obj"));
var houseGeom = DemoObjImporter.Load(RcResources.Load("house.obj"));
var convexGeom = DemoObjImporter.Load(RcResources.Load("convex.obj"));
var bridgeGeom = DemoInputGeomProvider.LoadFile("bridge.obj");
var houseGeom = DemoInputGeomProvider.LoadFile("house.obj");
var convexGeom = DemoInputGeomProvider.LoadFile("convex.obj");
_tool = new(Random.Shared, bridgeGeom, houseGeom, convexGeom);
executor = Task.Factory;
}

View File

@ -1,15 +0,0 @@
using System;
using System.IO;
using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset
{
public static class DemoObjImporter
{
public static DemoInputGeomProvider Load(byte[] chunk)
{
var context = ObjImporter.LoadContext(chunk);
return new DemoInputGeomProvider(context.vertexPositions, context.meshFaces);
}
}
}

View File

@ -37,6 +37,13 @@ namespace DotRecast.Recast.Toolset.Geom
private readonly List<RcOffMeshConnection> _offMeshConnections = new List<RcOffMeshConnection>();
private readonly RcTriMesh _mesh;
public static DemoInputGeomProvider LoadFile(string objFilePath)
{
byte[] chunk = RcResources.Load(objFilePath);
var context = RcObjImporter.LoadContext(chunk);
return new DemoInputGeomProvider(context.vertexPositions, context.meshFaces);
}
public DemoInputGeomProvider(List<float> vertexPositions, List<int> meshFaces) :
this(MapVertices(vertexPositions), MapFaces(meshFaces))
{

View File

@ -35,6 +35,13 @@ namespace DotRecast.Recast.Geom
private readonly List<RcConvexVolume> volumes = new List<RcConvexVolume>();
private readonly RcTriMesh _mesh;
public static SimpleInputGeomProvider LoadFile(string objFilePath)
{
byte[] chunk = RcResources.Load(objFilePath);
var context = RcObjImporter.LoadContext(chunk);
return new SimpleInputGeomProvider(context.vertexPositions, context.meshFaces);
}
public SimpleInputGeomProvider(List<float> vertexPositions, List<int> meshFaces)
: this(MapVertices(vertexPositions), MapFaces(meshFaces))
{

View File

@ -1,6 +1,6 @@
namespace DotRecast.Recast
{
public interface IRecastBuilderProgressListener
public interface IRcBuilderProgressListener
{
void OnProgress(int completed, int total);
}

View File

@ -32,16 +32,16 @@ namespace DotRecast.Recast
public class RcBuilder
{
private readonly IRecastBuilderProgressListener progressListener;
private readonly IRcBuilderProgressListener _progressListener;
public RcBuilder()
{
progressListener = null;
_progressListener = null;
}
public RcBuilder(IRecastBuilderProgressListener progressListener)
public RcBuilder(IRcBuilderProgressListener progressListener)
{
this.progressListener = progressListener;
_progressListener = progressListener;
}
public List<RcBuilderResult> BuildTiles(IInputGeomProvider geom, RcConfig cfg, TaskFactory taskFactory)
@ -150,9 +150,9 @@ namespace DotRecast.Recast
int ty, RcAtomicInteger counter, int total)
{
RcBuilderResult result = Build(geom, new RcBuilderConfig(cfg, bmin, bmax, tx, ty));
if (progressListener != null)
if (_progressListener != null)
{
progressListener.OnProgress(counter.IncrementAndGet(), total);
_progressListener.OnProgress(counter.IncrementAndGet(), total);
}
return result;
@ -237,8 +237,7 @@ namespace DotRecast.Recast
//
// Create contours.
RcContourSet cset = RcContours.BuildContours(ctx, chf, cfg.MaxSimplificationError, cfg.MaxEdgeLen,
RcConstants.RC_CONTOUR_TESS_WALL_EDGES);
RcContourSet cset = RcContours.BuildContours(ctx, chf, cfg.MaxSimplificationError, cfg.MaxEdgeLen, RcConstants.RC_CONTOUR_TESS_WALL_EDGES);
//
// Step 6. Build polygons mesh from contours.
@ -283,8 +282,7 @@ namespace DotRecast.Recast
/*
* Step 3. Partition walkable surface to simple regions.
*/
private RcCompactHeightfield BuildCompactHeightfield(IInputGeomProvider geom, RcConfig cfg, RcTelemetry ctx,
RcHeightfield solid)
private RcCompactHeightfield BuildCompactHeightfield(IInputGeomProvider geom, RcConfig cfg, RcTelemetry ctx, RcHeightfield solid)
{
// Compact the heightfield so that it is faster to handle from now on.
// This will result more cache coherent data as well as the neighbours

View File

@ -40,7 +40,7 @@ public class RecastTestMeshBuilder
public const float m_detailSampleMaxError = 1.0f;
public RecastTestMeshBuilder()
: this(ObjImporter.Load(RcResources.Load("dungeon.obj")),
: this(SimpleInputGeomProvider.LoadFile("dungeon.obj"),
RcPartition.WATERSHED,
m_cellSize, m_cellHeight,
m_agentMaxSlope, m_agentHeight, m_agentRadius, m_agentMaxClimb,

View File

@ -54,7 +54,7 @@ public class MeshSetReaderWriterTest
[Test]
public void Test()
{
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
NavMeshSetHeader header = new NavMeshSetHeader();
header.magic = NavMeshSetHeader.NAVMESHSET_MAGIC;

View File

@ -40,7 +40,7 @@ public class RecastTestMeshBuilder
private const float m_detailSampleMaxError = 1.0f;
public RecastTestMeshBuilder()
: this(ObjImporter.Load(RcResources.Load("dungeon.obj")),
: this(SimpleInputGeomProvider.LoadFile("dungeon.obj"),
RcPartition.WATERSHED,
m_cellSize, m_cellHeight,
m_agentMaxSlope, m_agentHeight, m_agentRadius, m_agentMaxClimb,

View File

@ -45,7 +45,7 @@ public class TestTiledNavMeshBuilder
private const int m_tileSize = 32;
public TestTiledNavMeshBuilder() :
this(ObjImporter.Load(RcResources.Load("dungeon.obj")),
this(SimpleInputGeomProvider.LoadFile("dungeon.obj"),
RcPartition.WATERSHED, 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, m_tileSize)

View File

@ -51,7 +51,7 @@ public class TileCacheReaderWriterTest : AbstractTileCacheTest
private void TestDungeon(bool cCompatibility)
{
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
TestTileLayerBuilder layerBuilder = new TestTileLayerBuilder(geom);
List<byte[]> layers = layerBuilder.Build(RcByteOrder.LITTLE_ENDIAN, cCompatibility, 1);
DtTileCache tc = GetTileCache(geom, RcByteOrder.LITTLE_ENDIAN, cCompatibility);

View File

@ -34,7 +34,7 @@ public class TempObstaclesTest : AbstractTileCacheTest
public void TestDungeon()
{
bool cCompatibility = true;
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
TestTileLayerBuilder layerBuilder = new TestTileLayerBuilder(geom);
List<byte[]> layers = layerBuilder.Build(RcByteOrder.LITTLE_ENDIAN, cCompatibility, 1);
DtTileCache tc = GetTileCache(geom, RcByteOrder.LITTLE_ENDIAN, cCompatibility);
@ -68,7 +68,7 @@ public class TempObstaclesTest : AbstractTileCacheTest
public void TestDungeonBox()
{
bool cCompatibility = true;
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
TestTileLayerBuilder layerBuilder = new TestTileLayerBuilder(geom);
List<byte[]> layers = layerBuilder.Build(RcByteOrder.LITTLE_ENDIAN, cCompatibility, 1);
DtTileCache tc = GetTileCache(geom, RcByteOrder.LITTLE_ENDIAN, cCompatibility);

View File

@ -55,7 +55,7 @@ public class TileCacheNavigationTest : AbstractTileCacheTest
public void SetUp()
{
bool cCompatibility = true;
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
TestTileLayerBuilder layerBuilder = new TestTileLayerBuilder(geom);
List<byte[]> layers = layerBuilder.Build(RcByteOrder.LITTLE_ENDIAN, cCompatibility, 1);
DtTileCache tc = GetTileCache(geom, RcByteOrder.LITTLE_ENDIAN, cCompatibility);

View File

@ -59,7 +59,7 @@ public class TileCacheTest : AbstractTileCacheTest
private void TestDungeon(RcByteOrder order, bool cCompatibility)
{
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
DtTileCache tc = GetTileCache(geom, order, cCompatibility);
TestTileLayerBuilder layerBuilder = new TestTileLayerBuilder(geom);
List<byte[]> layers = layerBuilder.Build(order, cCompatibility, 1);
@ -155,7 +155,7 @@ public class TileCacheTest : AbstractTileCacheTest
private void Test(RcByteOrder order, bool cCompatibility)
{
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("nav_test.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("nav_test.obj");
DtTileCache tc = GetTileCache(geom, order, cCompatibility);
TestTileLayerBuilder layerBuilder = new TestTileLayerBuilder(geom);
List<byte[]> layers = layerBuilder.Build(order, cCompatibility, 1);
@ -182,8 +182,7 @@ public class TileCacheTest : AbstractTileCacheTest
RcByteOrder order = RcByteOrder.LITTLE_ENDIAN;
bool cCompatibility = false;
var objBytes = RcResources.Load("dungeon.obj");
IInputGeomProvider geom = ObjImporter.Load(objBytes);
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
TestTileLayerBuilder layerBuilder = new TestTileLayerBuilder(geom);
for (int i = 0; i < 4; i++)
{

View File

@ -145,7 +145,7 @@ public class RecastLayersTest
private RcHeightfieldLayerSet Build(string filename, int x, int y)
{
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load(filename));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile(filename);
RcBuilder builder = new RcBuilder();
RcConfig cfg = new RcConfig(true, m_tileSize, m_tileSize,
RcConfig.CalcBorder(m_agentRadius, m_cellSize),

View File

@ -97,7 +97,7 @@ public class RecastSoloMeshTest
int expContours, int expVerts, int expPolys, int expDetMeshes, int expDetVerts, int expDetTris)
{
m_partitionType = partitionType;
IInputGeomProvider geomProvider = ObjImporter.Load(RcResources.Load(filename));
IInputGeomProvider geomProvider = SimpleInputGeomProvider.LoadFile(filename);
long time = RcFrequency.Ticks;
RcVec3f bmin = geomProvider.GetMeshBoundsMin();
RcVec3f bmax = geomProvider.GetMeshBoundsMax();

View File

@ -58,7 +58,7 @@ public class RecastTileMeshTest
public void TestBuild(string filename)
{
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load(filename));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile(filename);
RcBuilder builder = new RcBuilder();
RcConfig cfg = new RcConfig(
true, m_tileSize, m_tileSize, RcConfig.CalcBorder(m_agentRadius, m_cellSize),
@ -100,7 +100,7 @@ public class RecastTileMeshTest
[Test]
public void TestPerformance()
{
IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj"));
IInputGeomProvider geom = SimpleInputGeomProvider.LoadFile("dungeon.obj");
RcBuilder builder = new RcBuilder();
RcConfig cfg = new RcConfig(
true, m_tileSize, m_tileSize,