From 846e1a9b650bc036ca5c1c31ec3fcbf91b81f3c2 Mon Sep 17 00:00:00 2001 From: ikpil Date: Thu, 6 Jul 2023 00:01:53 +0900 Subject: [PATCH] change convexVolume tool impl for unity3d --- src/DotRecast.Core/ConvexUtils.cs | 16 ++-- .../Tools/ConvexVolumeTool.cs | 90 +++++-------------- .../Tools/ConvexVolumeToolImpl.cs | 72 ++++++++++++++- src/DotRecast.Recast/PolyUtils.cs | 2 +- 4 files changed, 98 insertions(+), 82 deletions(-) diff --git a/src/DotRecast.Core/ConvexUtils.cs b/src/DotRecast.Core/ConvexUtils.cs index a67269f..1e53d58 100644 --- a/src/DotRecast.Core/ConvexUtils.cs +++ b/src/DotRecast.Core/ConvexUtils.cs @@ -25,17 +25,15 @@ namespace DotRecast.Core // Calculates convex hull on xz-plane of points on 'pts', // stores the indices of the resulting hull in 'out' and // returns number of points on hull. - public static List Convexhull(List pts) + public static List Convexhull(List pts) { - int npts = pts.Count / 3; + int npts = pts.Count; List @out = new List(); // Find lower-leftmost point. int hull = 0; for (int i = 1; i < npts; ++i) { - RcVec3f a = RcVec3f.Of(pts[i * 3], pts[i * 3 + 1], pts[i * 3 + 2]); - RcVec3f b = RcVec3f.Of(pts[hull * 3], pts[hull * 3 + 1], pts[hull * 3 + 2]); - if (Cmppt(a, b)) + if (Cmppt(pts[i], pts[hull])) { hull = i; } @@ -49,9 +47,9 @@ namespace DotRecast.Core endpt = 0; for (int j = 1; j < npts; ++j) { - RcVec3f a = RcVec3f.Of(pts[hull * 3], pts[hull * 3 + 1], pts[hull * 3 + 2]); - RcVec3f b = RcVec3f.Of(pts[endpt * 3], pts[endpt * 3 + 1], pts[endpt * 3 + 2]); - RcVec3f c = RcVec3f.Of(pts[j * 3], pts[j * 3 + 1], pts[j * 3 + 2]); + RcVec3f a = pts[hull]; + RcVec3f b = pts[endpt]; + RcVec3f c = pts[j]; if (hull == endpt || Left(a, b, c)) { endpt = j; @@ -100,4 +98,4 @@ namespace DotRecast.Core return u1 * v2 - v1 * u2 < 0; } } -} +} \ No newline at end of file diff --git a/src/DotRecast.Recast.Demo/Tools/ConvexVolumeTool.cs b/src/DotRecast.Recast.Demo/Tools/ConvexVolumeTool.cs index a70f17d..f2dc9b5 100644 --- a/src/DotRecast.Recast.Demo/Tools/ConvexVolumeTool.cs +++ b/src/DotRecast.Recast.Demo/Tools/ConvexVolumeTool.cs @@ -35,13 +35,13 @@ namespace DotRecast.Recast.Demo.Tools; public class ConvexVolumeTool : IRcTool { private readonly ConvexVolumeToolImpl _impl; - + private int areaTypeValue = SampleAreaModifications.SAMPLE_AREAMOD_GRASS.Value; private AreaModification areaType = SampleAreaModifications.SAMPLE_AREAMOD_GRASS; private float boxHeight = 6f; private float boxDescent = 1f; private float polyOffset = 0f; - private readonly List pts = new(); + private readonly List pts = new(); private readonly List hull = new(); public ConvexVolumeTool() @@ -69,65 +69,16 @@ public class ConvexVolumeTool : IRcTool if (shift) { - // Delete - int nearestIndex = -1; - IList vols = geom.ConvexVolumes(); - for (int i = 0; i < vols.Count; ++i) - { - if (PolyUtils.PointInPoly(vols[i].verts, p) && p.y >= vols[i].hmin - && p.y <= vols[i].hmax) - { - nearestIndex = i; - } - } - - // If end point close enough, delete it. - if (nearestIndex != -1) - { - geom.ConvexVolumes().RemoveAt(nearestIndex); - } + _impl.RemoveByPos(p); } else { // Create // If clicked on that last pt, create the shape. - if (pts.Count > 0 && RcVec3f.DistSqr(p, RcVec3f.Of(pts[pts.Count - 3], pts[pts.Count - 2], pts[pts.Count - 1])) < 0.2f * 0.2f) + if (pts.Count > 0 && RcVec3f.DistSqr(p, pts[pts.Count - 1]) < 0.2f * 0.2f) { - if (hull.Count > 2) - { - // Create shape. - float[] verts = new float[hull.Count * 3]; - for (int i = 0; i < hull.Count; ++i) - { - verts[i * 3] = pts[hull[i] * 3]; - verts[i * 3 + 1] = pts[hull[i] * 3 + 1]; - verts[i * 3 + 2] = pts[hull[i] * 3 + 2]; - } - - float minh = float.MaxValue, maxh = 0; - for (int i = 0; i < hull.Count; ++i) - { - minh = Math.Min(minh, verts[i * 3 + 1]); - } - - minh -= boxDescent; - maxh = minh + boxHeight; - - if (polyOffset > 0.01f) - { - float[] offset = new float[verts.Length * 2]; - int noffset = PolyUtils.OffsetPoly(verts, hull.Count, polyOffset, offset, offset.Length); - if (noffset > 0) - { - geom.AddConvexVolume(RcArrayUtils.CopyOf(offset, 0, noffset * 3), minh, maxh, areaType); - } - } - else - { - geom.AddConvexVolume(verts, minh, maxh, areaType); - } - } + _impl.Add(pts, hull, areaType, boxDescent, boxHeight, polyOffset); pts.Clear(); hull.Clear(); @@ -135,9 +86,8 @@ public class ConvexVolumeTool : IRcTool else { // Add new point - pts.Add(p.x); - pts.Add(p.y); - pts.Add(p.z); + pts.Add(p); + // Update hull. if (pts.Count > 3) { @@ -157,24 +107,24 @@ public class ConvexVolumeTool : IRcTool RecastDebugDraw dd = renderer.GetDebugDraw(); // Find height extent of the shape. float minh = float.MaxValue, maxh = 0; - for (int i = 0; i < pts.Count; i += 3) + for (int i = 0; i < pts.Count; ++i) { - minh = Math.Min(minh, pts[i + 1]); + minh = Math.Min(minh, pts[i].y); } minh -= boxDescent; maxh = minh + boxHeight; dd.Begin(POINTS, 4.0f); - for (int i = 0; i < pts.Count; i += 3) + for (int i = 0; i < pts.Count; ++i) { int col = DuRGBA(255, 255, 255, 255); - if (i == pts.Count - 3) + if (i == pts.Count - 1) { col = DuRGBA(240, 32, 16, 255); } - dd.Vertex(pts[i + 0], pts[i + 1] + 0.1f, pts[i + 2], col); + dd.Vertex(pts[i].x, pts[i].y + 0.1f, pts[i].z, col); } dd.End(); @@ -182,14 +132,14 @@ public class ConvexVolumeTool : IRcTool dd.Begin(LINES, 2.0f); for (int i = 0, j = hull.Count - 1; i < hull.Count; j = i++) { - int vi = hull[j] * 3; - int vj = hull[i] * 3; - dd.Vertex(pts[vj + 0], minh, pts[vj + 2], DuRGBA(255, 255, 255, 64)); - dd.Vertex(pts[vi + 0], minh, pts[vi + 2], DuRGBA(255, 255, 255, 64)); - dd.Vertex(pts[vj + 0], maxh, pts[vj + 2], DuRGBA(255, 255, 255, 64)); - dd.Vertex(pts[vi + 0], maxh, pts[vi + 2], DuRGBA(255, 255, 255, 64)); - dd.Vertex(pts[vj + 0], minh, pts[vj + 2], DuRGBA(255, 255, 255, 64)); - dd.Vertex(pts[vj + 0], maxh, pts[vj + 2], DuRGBA(255, 255, 255, 64)); + int vi = hull[j]; + int vj = hull[i]; + dd.Vertex(pts[vj].x, minh, pts[vj].z, DuRGBA(255, 255, 255, 64)); + dd.Vertex(pts[vi].x, minh, pts[vi].z, DuRGBA(255, 255, 255, 64)); + dd.Vertex(pts[vj].x, maxh, pts[vj].z, DuRGBA(255, 255, 255, 64)); + dd.Vertex(pts[vi].x, maxh, pts[vi].z, DuRGBA(255, 255, 255, 64)); + dd.Vertex(pts[vj].x, minh, pts[vj].z, DuRGBA(255, 255, 255, 64)); + dd.Vertex(pts[vj].x, maxh, pts[vj].z, DuRGBA(255, 255, 255, 64)); } dd.End(); diff --git a/src/DotRecast.Recast.DemoTool/Tools/ConvexVolumeToolImpl.cs b/src/DotRecast.Recast.DemoTool/Tools/ConvexVolumeToolImpl.cs index be1f296..90978ac 100644 --- a/src/DotRecast.Recast.DemoTool/Tools/ConvexVolumeToolImpl.cs +++ b/src/DotRecast.Recast.DemoTool/Tools/ConvexVolumeToolImpl.cs @@ -1,9 +1,13 @@ -namespace DotRecast.Recast.DemoTool.Tools +using System; +using System.Collections.Generic; +using DotRecast.Core; + +namespace DotRecast.Recast.DemoTool.Tools { public class ConvexVolumeToolImpl : ISampleTool { private Sample _sample; - + public string GetName() { return "Create Convex Volumes"; @@ -19,5 +23,69 @@ return _sample; } + public ConvexVolume RemoveByPos(RcVec3f pos) + { + var geom = _sample.GetInputGeom(); + + // Delete + int nearestIndex = -1; + IList vols = geom.ConvexVolumes(); + for (int i = 0; i < vols.Count; ++i) + { + if (PolyUtils.PointInPoly(vols[i].verts, pos) && pos.y >= vols[i].hmin + && pos.y <= vols[i].hmax) + { + nearestIndex = i; + } + } + + // If end point close enough, delete it. + if (nearestIndex == -1) + return null; + + var removal = geom.ConvexVolumes()[nearestIndex]; + geom.ConvexVolumes().RemoveAt(nearestIndex); + return removal; + } + + public void Add(List pts, List hull, AreaModification areaType, float boxDescent, float boxHeight, float polyOffset) + { + // + if (hull.Count <= 2) + return; + + // Create shape. + float[] verts = new float[hull.Count * 3]; + for (int i = 0; i < hull.Count; ++i) + { + verts[i * 3] = pts[hull[i]].x; + verts[i * 3 + 1] = pts[hull[i]].y; + verts[i * 3 + 2] = pts[hull[i]].z; + } + + float minh = float.MaxValue, maxh = 0; + for (int i = 0; i < hull.Count; ++i) + { + minh = Math.Min(minh, verts[i * 3 + 1]); + } + + minh -= boxDescent; + maxh = minh + boxHeight; + + var geom = _sample.GetInputGeom(); + if (polyOffset > 0.01f) + { + float[] offset = new float[verts.Length * 2]; + int noffset = PolyUtils.OffsetPoly(verts, hull.Count, polyOffset, offset, offset.Length); + if (noffset > 0) + { + geom.AddConvexVolume(RcArrayUtils.CopyOf(offset, 0, noffset * 3), minh, maxh, areaType); + } + } + else + { + geom.AddConvexVolume(verts, minh, maxh, areaType); + } + } } } \ No newline at end of file diff --git a/src/DotRecast.Recast/PolyUtils.cs b/src/DotRecast.Recast/PolyUtils.cs index 304a860..4bda6cf 100644 --- a/src/DotRecast.Recast/PolyUtils.cs +++ b/src/DotRecast.Recast/PolyUtils.cs @@ -45,7 +45,7 @@ namespace DotRecast.Recast public static int OffsetPoly(float[] verts, int nverts, float offset, float[] outVerts, int maxOutVerts) { - float MITER_LIMIT = 1.20f; + const float MITER_LIMIT = 1.20f; int n = 0;