change convexVolume tool impl for unity3d

This commit is contained in:
ikpil 2023-07-06 00:01:53 +09:00
parent bb047c5a1d
commit 846e1a9b65
4 changed files with 98 additions and 82 deletions

View File

@ -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<int> Convexhull(List<float> pts)
public static List<int> Convexhull(List<RcVec3f> pts)
{
int npts = pts.Count / 3;
int npts = pts.Count;
List<int> @out = new List<int>();
// 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;

View File

@ -41,7 +41,7 @@ public class ConvexVolumeTool : IRcTool
private float boxHeight = 6f;
private float boxDescent = 1f;
private float polyOffset = 0f;
private readonly List<float> pts = new();
private readonly List<RcVec3f> pts = new();
private readonly List<int> hull = new();
public ConvexVolumeTool()
@ -69,65 +69,16 @@ public class ConvexVolumeTool : IRcTool
if (shift)
{
// Delete
int nearestIndex = -1;
IList<ConvexVolume> 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();

View File

@ -1,4 +1,8 @@
namespace DotRecast.Recast.DemoTool.Tools
using System;
using System.Collections.Generic;
using DotRecast.Core;
namespace DotRecast.Recast.DemoTool.Tools
{
public class ConvexVolumeToolImpl : ISampleTool
{
@ -19,5 +23,69 @@
return _sample;
}
public ConvexVolume RemoveByPos(RcVec3f pos)
{
var geom = _sample.GetInputGeom();
// Delete
int nearestIndex = -1;
IList<ConvexVolume> 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<RcVec3f> pts, List<int> 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);
}
}
}
}

View File

@ -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;