mattercontrol/original/MatterControlLib/PartPreviewWindow/SceneViewer/FrustumDrawable.cs

104 lines
No EOL
3.1 KiB
C#

using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.PolygonMesh;
using MatterHackers.RenderOpenGl;
using MatterHackers.RenderOpenGl.OpenGl;
using MatterHackers.VectorMath;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class FrustumDrawable : IDrawable
{
public FrustumDrawable()
{
}
string IDrawable.Title => "Frustum visualization";
string IDrawable.Description => "When enabled, captures the current frustum and visualizes it.";
bool _enabled = false;
bool IDrawable.Enabled
{
get => _enabled;
set
{
_enabled = value;
meshes.Clear();
}
}
DrawStage IDrawable.DrawStage => DrawStage.TransparentContent;
readonly List<(Mesh mesh, Color color)> meshes = new List<(Mesh, Color)>();
static Mesh GetMesh(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
{
Mesh mesh = new Mesh();
mesh.Vertices.Add(a);
mesh.Vertices.Add(b);
mesh.Vertices.Add(c);
mesh.Vertices.Add(d);
mesh.Faces.Add(0, 1, 2, mesh.Vertices);
mesh.Faces.Add(0, 2, 3, mesh.Vertices);
return mesh;
}
void IDrawable.Draw(GuiWidget sender, DrawEventArgs e, Matrix4X4 itemMaxtrix, WorldView world)
{
if (meshes.Count == 0)
{
Vector3[] ndcCoords = new Vector3[] {
new Vector3(+1, +1, +1), // 0: far top right
new Vector3(-1, +1, +1), // 1: far top left
new Vector3(+1, -1, +1), // 2: far bottom right
new Vector3(-1, -1, +1), // 3: far bottom left
new Vector3(+1, +1, -1), // 4: near top right
new Vector3(-1, +1, -1), // 5: near top left
new Vector3(+1, -1, -1), // 6: near bottom right
new Vector3(-1, -1, -1), // 7: near bottom left
};
Vector3[] worldspaceCoords = ndcCoords.Select(p => world.NDCToViewspace(p).TransformPosition(world.InverseModelviewMatrix)).ToArray();
// X
meshes.Add((GetMesh(worldspaceCoords[1], worldspaceCoords[5], worldspaceCoords[7], worldspaceCoords[3]), Color.Red.WithAlpha(0.5)));
meshes.Add((GetMesh(worldspaceCoords[0], worldspaceCoords[2], worldspaceCoords[6], worldspaceCoords[4]), Color.Red.WithAlpha(0.5)));
// Y
meshes.Add((GetMesh(worldspaceCoords[3], worldspaceCoords[7], worldspaceCoords[6], worldspaceCoords[2]), Color.Green.WithAlpha(0.5)));
meshes.Add((GetMesh(worldspaceCoords[1], worldspaceCoords[0], worldspaceCoords[4], worldspaceCoords[5]), Color.Green.WithAlpha(0.5)));
// Z
meshes.Add((GetMesh(worldspaceCoords[0], worldspaceCoords[1], worldspaceCoords[3], worldspaceCoords[2]), Color.Blue.WithAlpha(0.5)));
meshes.Add((GetMesh(worldspaceCoords[4], worldspaceCoords[5], worldspaceCoords[7], worldspaceCoords[6]), Color.Blue.WithAlpha(0.5)));
}
GL.Disable(EnableCap.Lighting);
foreach (var mesh in meshes)
{
GLHelper.Render(mesh.mesh, mesh.color, forceCullBackFaces: false);
}
GL.Enable(EnableCap.Lighting);
}
AxisAlignedBoundingBox IDrawable.GetWorldspaceAABB()
{
var box = AxisAlignedBoundingBox.Empty();
foreach (var mesh in meshes)
{
box = AxisAlignedBoundingBox.Union(box, mesh.mesh.GetAxisAlignedBoundingBox());
}
return box;
}
}
}