forked from mirror/DotRecast
96 lines
3.4 KiB
C#
96 lines
3.4 KiB
C#
using DotRecast.Core;
|
|
using DotRecast.Recast.Demo.Draw;
|
|
using static DotRecast.Recast.RecastVectors;
|
|
using static DotRecast.Core.RecastMath;
|
|
using static DotRecast.Recast.Demo.Tools.Gizmos.GizmoHelper;
|
|
|
|
|
|
namespace DotRecast.Recast.Demo.Tools.Gizmos;
|
|
|
|
public class CylinderGizmo : ColliderGizmo
|
|
{
|
|
private readonly float[] vertices;
|
|
private readonly int[] triangles;
|
|
private readonly Vector3f center;
|
|
private readonly float[] gradient;
|
|
|
|
public CylinderGizmo(Vector3f start, Vector3f end, float radius)
|
|
{
|
|
center = Vector3f.Of(
|
|
0.5f * (start.x + end.x), 0.5f * (start.y + end.y),
|
|
0.5f * (start.z + end.z)
|
|
);
|
|
Vector3f axis = Vector3f.Of(end.x - start.x, end.y - start.y, end.z - start.z);
|
|
Vector3f[] normals = new Vector3f[3];
|
|
normals[1] = Vector3f.Of(end.x - start.x, end.y - start.y, end.z - start.z);
|
|
Normalize(ref normals[1]);
|
|
normals[0] = GetSideVector(axis);
|
|
normals[2] = Vector3f.Zero;
|
|
Cross(ref normals[2], normals[0], normals[1]);
|
|
Normalize(ref normals[2]);
|
|
triangles = GenerateCylindricalTriangles();
|
|
Vector3f trX = Vector3f.Of(normals[0].x, normals[1].x, normals[2].x);
|
|
Vector3f trY = Vector3f.Of(normals[0].y, normals[1].y, normals[2].y);
|
|
Vector3f trZ = Vector3f.Of(normals[0].z, normals[1].z, normals[2].z);
|
|
vertices = GenerateCylindricalVertices();
|
|
float halfLength = 0.5f * VLen(axis);
|
|
gradient = new float[vertices.Length / 3];
|
|
Vector3f v = new Vector3f();
|
|
for (int i = 0; i < vertices.Length; i += 3)
|
|
{
|
|
float offset = (i >= vertices.Length / 2) ? -halfLength : halfLength;
|
|
float x = radius * vertices[i];
|
|
float y = vertices[i + 1] + offset;
|
|
float z = radius * vertices[i + 2];
|
|
vertices[i] = x * trX.x + y * trX.y + z * trX.z + center.x;
|
|
vertices[i + 1] = x * trY.x + y * trY.y + z * trY.z + center.y;
|
|
vertices[i + 2] = x * trZ.x + y * trZ.y + z * trZ.z + center.z;
|
|
if (i < vertices.Length / 4 || i >= 3 * vertices.Length / 4)
|
|
{
|
|
gradient[i / 3] = 1;
|
|
}
|
|
else
|
|
{
|
|
v.x = vertices[i] - center.x;
|
|
v.y = vertices[i + 1] - center.y;
|
|
v.z = vertices[i + 2] - center.z;
|
|
Normalize(ref v);
|
|
gradient[i / 3] = Clamp(0.57735026f * (v.x + v.y + v.z), -1, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private Vector3f GetSideVector(Vector3f axis)
|
|
{
|
|
Vector3f side = Vector3f.Of(1, 0, 0);
|
|
if (axis.x > 0.8)
|
|
{
|
|
side = Vector3f.Of(0, 0, 1);
|
|
}
|
|
|
|
Vector3f forward = new Vector3f();
|
|
Cross(ref forward, side, axis);
|
|
Cross(ref side, axis, forward);
|
|
Normalize(ref side);
|
|
return side;
|
|
}
|
|
|
|
public void Render(RecastDebugDraw debugDraw)
|
|
{
|
|
debugDraw.Begin(DebugDrawPrimitives.TRIS);
|
|
for (int i = 0; i < triangles.Length; i += 3)
|
|
{
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
int v = triangles[i + j] * 3;
|
|
float c = gradient[triangles[i + j]];
|
|
int col = DebugDraw.DuLerpCol(DebugDraw.DuRGBA(32, 32, 0, 160), DebugDraw.DuRGBA(220, 220, 0, 160),
|
|
(int)(127 * (1 + c)));
|
|
debugDraw.Vertex(vertices[v], vertices[v + 1], vertices[v + 2], col);
|
|
}
|
|
}
|
|
|
|
debugDraw.End();
|
|
}
|
|
}
|