DotRecastNetSim/src/DotRecast.Recast.Demo/Tools/GizmoRenderer.cs

179 lines
6.4 KiB
C#

using System;
using DotRecast.Core;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset.Gizmos;
namespace DotRecast.Recast.Demo.Tools;
public static class GizmoRenderer
{
public static void Render(RecastDebugDraw dd, IRcGizmoMeshFilter gizmo)
{
if (gizmo is RcBoxGizmo box)
{
RenderBox(dd, box);
}
else if (gizmo is RcCapsuleGizmo capsule)
{
RenderCapsule(dd, capsule);
}
else if (gizmo is RcTrimeshGizmo trimesh)
{
RenderTrimesh(dd, trimesh);
}
else if (gizmo is RcCylinderGizmo cylinder)
{
RenderCylinder(dd, cylinder);
}
else if (gizmo is RcSphereGizmo sphere)
{
RenderSphere(dd, sphere);
}
else if (gizmo is RcCompositeGizmo composite)
{
RenderComposite(dd, composite);
}
}
public static int GetColorByNormal(float[] vertices, int v0, int v1, int v2)
{
RcVec3f e0 = new RcVec3f();
RcVec3f e1 = new RcVec3f();
RcVec3f normal = new RcVec3f();
for (int j = 0; j < 3; ++j)
{
e0[j] = vertices[v1 + j] - vertices[v0 + j];
e1[j] = vertices[v2 + j] - vertices[v0 + j];
}
normal.x = e0.y * e1.z - e0.z * e1.y;
normal.y = e0.z * e1.x - e0.x * e1.z;
normal.z = e0.x * e1.y - e0.y * e1.x;
RcVec3f.Normalize(ref normal);
float c = Math.Clamp(0.57735026f * (normal.x + normal.y + normal.z), -1, 1);
int col = DebugDraw.DuLerpCol(
DebugDraw.DuRGBA(32, 32, 0, 160),
DebugDraw.DuRGBA(220, 220, 0, 160),
(int)(127 * (1 + c))
);
return col;
}
public static void RenderBox(RecastDebugDraw debugDraw, RcBoxGizmo box)
{
var trX = RcVec3f.Of(box.halfEdges[0].x, box.halfEdges[1].x, box.halfEdges[2].x);
var trY = RcVec3f.Of(box.halfEdges[0].y, box.halfEdges[1].y, box.halfEdges[2].y);
var trZ = RcVec3f.Of(box.halfEdges[0].z, box.halfEdges[1].z, box.halfEdges[2].z);
float[] vertices = new float[8 * 3];
for (int i = 0; i < 8; i++)
{
vertices[i * 3 + 0] = RcVec3f.Dot(RcBoxGizmo.VERTS[i], trX) + box.center.x;
vertices[i * 3 + 1] = RcVec3f.Dot(RcBoxGizmo.VERTS[i], trY) + box.center.y;
vertices[i * 3 + 2] = RcVec3f.Dot(RcBoxGizmo.VERTS[i], trZ) + box.center.z;
}
debugDraw.Begin(DebugDrawPrimitives.TRIS);
for (int i = 0; i < 12; i++)
{
int col = DebugDraw.DuRGBA(200, 200, 50, 160);
if (i == 4 || i == 5 || i == 8 || i == 9)
{
col = DebugDraw.DuRGBA(160, 160, 40, 160);
}
else if (i > 4)
{
col = DebugDraw.DuRGBA(120, 120, 30, 160);
}
for (int j = 0; j < 3; j++)
{
int v = RcBoxGizmo.TRIANLGES[i * 3 + j] * 3;
debugDraw.Vertex(vertices[v], vertices[v + 1], vertices[v + 2], col);
}
}
debugDraw.End();
}
public static void RenderCapsule(RecastDebugDraw debugDraw, RcCapsuleGizmo capsule)
{
debugDraw.Begin(DebugDrawPrimitives.TRIS);
for (int i = 0; i < capsule.triangles.Length; i += 3)
{
for (int j = 0; j < 3; j++)
{
int v = capsule.triangles[i + j] * 3;
float c = capsule.gradient[capsule.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(capsule.vertices[v], capsule.vertices[v + 1], capsule.vertices[v + 2], col);
}
}
debugDraw.End();
}
public static void RenderCylinder(RecastDebugDraw debugDraw, RcCylinderGizmo cylinder)
{
debugDraw.Begin(DebugDrawPrimitives.TRIS);
for (int i = 0; i < cylinder.triangles.Length; i += 3)
{
for (int j = 0; j < 3; j++)
{
int v = cylinder.triangles[i + j] * 3;
float c = cylinder.gradient[cylinder.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(cylinder.vertices[v], cylinder.vertices[v + 1], cylinder.vertices[v + 2], col);
}
}
debugDraw.End();
}
public static void RenderSphere(RecastDebugDraw debugDraw, RcSphereGizmo sphere)
{
debugDraw.Begin(DebugDrawPrimitives.TRIS);
for (int i = 0; i < sphere.triangles.Length; i += 3)
{
for (int j = 0; j < 3; j++)
{
int v = sphere.triangles[i + j] * 3;
float c = Math.Clamp(0.57735026f * (sphere.vertices[v] + sphere.vertices[v + 1] + sphere.vertices[v + 2]), -1, 1);
int col = DebugDraw.DuLerpCol(DebugDraw.DuRGBA(32, 32, 0, 160), DebugDraw.DuRGBA(220, 220, 0, 160), (int)(127 * (1 + c)));
debugDraw.Vertex(
sphere.radius * sphere.vertices[v] + sphere.center.x,
sphere.radius * sphere.vertices[v + 1] + sphere.center.y,
sphere.radius * sphere.vertices[v + 2] + sphere.center.z,
col
);
}
}
debugDraw.End();
}
public static void RenderTrimesh(RecastDebugDraw debugDraw, RcTrimeshGizmo trimesh)
{
debugDraw.Begin(DebugDrawPrimitives.TRIS);
for (int i = 0; i < trimesh.triangles.Length; i += 3)
{
int v0 = 3 * trimesh.triangles[i];
int v1 = 3 * trimesh.triangles[i + 1];
int v2 = 3 * trimesh.triangles[i + 2];
int col = GetColorByNormal(trimesh.vertices, v0, v1, v2);
debugDraw.Vertex(trimesh.vertices[v0], trimesh.vertices[v0 + 1], trimesh.vertices[v0 + 2], col);
debugDraw.Vertex(trimesh.vertices[v1], trimesh.vertices[v1 + 1], trimesh.vertices[v1 + 2], col);
debugDraw.Vertex(trimesh.vertices[v2], trimesh.vertices[v2 + 1], trimesh.vertices[v2 + 2], col);
}
debugDraw.End();
}
public static void RenderComposite(RecastDebugDraw debugDraw, RcCompositeGizmo composite)
{
composite.gizmoMeshes.ForEach(g => Render(debugDraw, g));
}
}