public static void RenderPathOutline(this WorldView world, Matrix4X4 worldMatrix, IVertexSource path, Color color, double lineWidth = 1) { GLHelper.PrepareFor3DLineRender(true); Frustum frustum = world.GetClippingFrustum(); Vector3 firstPosition = default(Vector3); Vector3 prevPosition = default(Vector3); foreach (var vertex in path.Vertices()) { if (vertex.command == ShapePath.FlagsAndCommand.MoveTo) { firstPosition = prevPosition = new Vector3(vertex.position).Transform(worldMatrix); } else if (vertex.command == ShapePath.FlagsAndCommand.LineTo) { var position = new Vector3(vertex.position).Transform(worldMatrix); world.Render3DLineNoPrep(frustum, prevPosition, position, color, lineWidth); prevPosition = position; } else if (vertex.command.HasFlag(ShapePath.FlagsAndCommand.FlagClose)) { world.Render3DLineNoPrep(frustum, prevPosition, firstPosition, color, lineWidth); } } // turn the lighting back on GL.Enable(EnableCap.Lighting); }
public static void RenderCylinderOutline(this WorldView world, Matrix4X4 worldMatrix, Vector3 center, double Diameter, double Height, int sides, Color color, double lineWidth = 1, double extendLineLength = 0) { GLHelper.PrepareFor3DLineRender(true); Frustum frustum = world.GetClippingFrustum(); for (int i = 0; i < sides; i++) { var rotatedPoint = new Vector3(Math.Cos(MathHelper.Tau * i / sides), Math.Sin(MathHelper.Tau * i / sides), 0) * Diameter / 2; var sideTop = Vector3.Transform(center + rotatedPoint + new Vector3(0, 0, Height / 2), worldMatrix); var sideBottom = Vector3.Transform(center + rotatedPoint + new Vector3(0, 0, -Height / 2), worldMatrix); var rotated2Point = new Vector3(Math.Cos(MathHelper.Tau * (i + 1) / sides), Math.Sin(MathHelper.Tau * (i + 1) / sides), 0) * Diameter / 2; var topStart = sideTop; var topEnd = Vector3.Transform(center + rotated2Point + new Vector3(0, 0, Height / 2), worldMatrix); var bottomStart = sideBottom; var bottomEnd = Vector3.Transform(center + rotated2Point + new Vector3(0, 0, -Height / 2), worldMatrix); if (extendLineLength > 0) { GLHelper.ExtendLineEnds(ref sideTop, ref sideBottom, extendLineLength); } world.Render3DLineNoPrep(frustum, sideTop, sideBottom, color, lineWidth); world.Render3DLineNoPrep(frustum, topStart, topEnd, color, lineWidth); world.Render3DLineNoPrep(frustum, bottomStart, bottomEnd, color, lineWidth); } // turn the lighting back on GL.Enable(EnableCap.Lighting); }
public static void RenderAabb(this WorldView world, AxisAlignedBoundingBox bounds, Matrix4X4 matrix, Color color, double width, double extendLineLength = 0) { GLHelper.PrepareFor3DLineRender(true); Frustum frustum = world.GetClippingFrustum(); for (int i = 0; i < 4; i++) { Vector3 sideStartPosition = Vector3.Transform(bounds.GetBottomCorner(i), matrix); Vector3 sideEndPosition = Vector3.Transform(bounds.GetTopCorner(i), matrix); Vector3 bottomStartPosition = sideStartPosition; Vector3 bottomEndPosition = Vector3.Transform(bounds.GetBottomCorner((i + 1) % 4), matrix); Vector3 topStartPosition = sideEndPosition; Vector3 topEndPosition = Vector3.Transform(bounds.GetTopCorner((i + 1) % 4), matrix); if (extendLineLength > 0) { GLHelper.ExtendLineEnds(ref sideStartPosition, ref sideEndPosition, extendLineLength); GLHelper.ExtendLineEnds(ref topStartPosition, ref topEndPosition, extendLineLength); GLHelper.ExtendLineEnds(ref bottomStartPosition, ref bottomEndPosition, extendLineLength); } // draw each of the edge lines (4) and their touching top and bottom lines (2 each) world.Render3DLineNoPrep(frustum, sideStartPosition, sideEndPosition, color, width); world.Render3DLineNoPrep(frustum, topStartPosition, topEndPosition, color, width); world.Render3DLineNoPrep(frustum, bottomStartPosition, bottomEndPosition, color, width); } GL.Enable(EnableCap.Lighting); }
public static void RenderCylinderOutline(this WorldView world, Matrix4X4 worldMatrix, Vector3 center, double diameter, double height, int sides, Color topBottomRingColor, Color sideLinesColor, double lineWidth = 1, double extendLineLength = 0, double phase = 0) { GLHelper.PrepareFor3DLineRender(true); Frustum frustum = world.GetClippingFrustum(); for (int i = 0; i < sides; i++) { var startAngle = MathHelper.Tau * i / sides + phase; var rotatedPoint = new Vector3(Math.Cos(startAngle), Math.Sin(startAngle), 0) * diameter / 2; var sideTop = Vector3Ex.Transform(center + rotatedPoint + new Vector3(0, 0, height / 2), worldMatrix); var sideBottom = Vector3Ex.Transform(center + rotatedPoint + new Vector3(0, 0, -height / 2), worldMatrix); var endAngle = MathHelper.Tau * (i + 1) / sides + phase; var rotated2Point = new Vector3(Math.Cos(endAngle), Math.Sin(endAngle), 0) * diameter / 2; var topStart = sideTop; var topEnd = Vector3Ex.Transform(center + rotated2Point + new Vector3(0, 0, height / 2), worldMatrix); var bottomStart = sideBottom; var bottomEnd = Vector3Ex.Transform(center + rotated2Point + new Vector3(0, 0, -height / 2), worldMatrix); if (extendLineLength > 0) { GLHelper.ExtendLineEnds(ref sideTop, ref sideBottom, extendLineLength); } if (sideLinesColor != Color.Transparent) { world.Render3DLineNoPrep(frustum, sideTop, sideBottom, sideLinesColor, lineWidth); } if (topBottomRingColor != Color.Transparent) { world.Render3DLineNoPrep(frustum, topStart, topEnd, topBottomRingColor, lineWidth); world.Render3DLineNoPrep(frustum, bottomStart, bottomEnd, topBottomRingColor, lineWidth); } } }
public static void RenderDirectionAxis(this WorldView world, DirectionAxis axis, Matrix4X4 matrix, double size) { GLHelper.PrepareFor3DLineRender(true); Frustum frustum = world.GetClippingFrustum(); Vector3 length = axis.Normal * size; var color = Agg.Color.Red; // draw center line { var min = axis.Origin - length; Vector3 start = Vector3Ex.Transform(min, matrix); var max = axis.Origin + length; Vector3 end = Vector3Ex.Transform(max, matrix); world.Render3DLineNoPrep(frustum, start, end, color, 1); } var perpendicular = Vector3.GetPerpendicular(axis.Normal, Vector3.Zero).GetNormal(); // draw some lines to mark the rotation plane int count = 20; bool first = true; var firstEnd = Vector3.Zero; var lastEnd = Vector3.Zero; var center = Vector3Ex.Transform(axis.Origin, matrix); for (int i = 0; i < count; i++) { var rotation = size / 4 * Vector3Ex.Transform(perpendicular, Matrix4X4.CreateRotation(axis.Normal, MathHelper.Tau * i / count)); // draw center line var max = axis.Origin + rotation; Vector3 end = Vector3Ex.Transform(max, matrix); world.Render3DLineNoPrep(frustum, center, end, color, 1); if (!first) { world.Render3DLineNoPrep(frustum, end, lastEnd, color, 1); } else { firstEnd = end; } lastEnd = end; first = false; } world.Render3DLineNoPrep(frustum, firstEnd, lastEnd, color, 1); GL.Enable(EnableCap.Lighting); }
public void Draw(GuiWidget sender, IObject3D item, bool isSelected, DrawEventArgs e, Matrix4X4 itemMaxtrix, WorldView world) { if (!isSelected || item.Mesh?.Faces.Count <= 0) { return; } var frustum = world.GetClippingFrustum(); var mesh = item.Mesh; foreach (var face in mesh.Faces) { int vertexCount = 0; Vector3Float faceCenter = Vector3Float.Zero; foreach (var v in new[] { face.v0, face.v1, face.v2 }) { var vertex = mesh.Vertices[v]; faceCenter += vertex; vertexCount++; } faceCenter /= vertexCount; var matrix = item.WorldMatrix(); var transformed1 = faceCenter.Transform(matrix); var normal = face.normal.TransformNormal(matrix).GetNormal(); world.Render3DLineNoPrep(frustum, transformed1, transformed1 + normal, Color.Red, 2); } }
public static void RenderAxis(this WorldView world, Vector3 position, Matrix4X4 matrix, double size, double lineWidth) { GLHelper.PrepareFor3DLineRender(true); Frustum frustum = world.GetClippingFrustum(); Vector3 length = Vector3.One * size; for (int i = 0; i < 3; i++) { var min = position; min[i] -= length[i]; Vector3 start = Vector3.Transform(min, matrix); var max = position; max[i] += length[i]; Vector3 end = Vector3.Transform(max, matrix); var color = Agg.Color.Red; switch (i) { case 1: color = Agg.Color.Green; break; case 2: color = Agg.Color.Blue; break; } // draw each of the edge lines (4) and their touching top and bottom lines (2 each) world.Render3DLineNoPrep(frustum, start, end, color, lineWidth); } GL.Enable(EnableCap.Lighting); }
public static void RenderRing(this WorldView world, Matrix4X4 worldMatrix, Vector3 center, double diameter, int sides, Color ringColor, double lineWidth = 1, double phase = 0, bool zBuffered = true) { GLHelper.PrepareFor3DLineRender(zBuffered); Frustum frustum = world.GetClippingFrustum(); for (int i = 0; i < sides; i++) { var startAngle = MathHelper.Tau * i / sides + phase; var rotatedPoint = new Vector3(Math.Cos(startAngle), Math.Sin(startAngle), 0) * diameter / 2; var sideTop = Vector3Ex.Transform(center + rotatedPoint, worldMatrix); var sideBottom = Vector3Ex.Transform(center + rotatedPoint, worldMatrix); var endAngle = MathHelper.Tau * (i + 1) / sides + phase; var rotated2Point = new Vector3(Math.Cos(endAngle), Math.Sin(endAngle), 0) * diameter / 2; var topStart = sideTop; var topEnd = Vector3Ex.Transform(center + rotated2Point, worldMatrix); if (ringColor != Color.Transparent) { world.Render3DLineNoPrep(frustum, topStart, topEnd, ringColor, lineWidth); } } // turn the lighting back on GL.Enable(EnableCap.Lighting); }
/// <summary> /// Draw a line in the scene in 3D but scale it such that it appears as a 2D line in the view. /// </summary> /// <param name="world"></param> /// <param name="clippingFrustum">This is a cache of the frustum from world. /// Much faster to pass this way if drawing lots of lines.</param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="color"></param> /// <param name="doDepthTest"></param> /// <param name="width"></param> public static void Render3DLine(this WorldView world, Frustum clippingFrustum, Vector3 start, Vector3 end, Color color, bool doDepthTest = true, double width = 1, bool startArrow = false, bool endArrow = false) { GL.PushAttrib(AttribMask.EnableBit); GLHelper.PrepareFor3DLineRender(doDepthTest); world.Render3DLineNoPrep(clippingFrustum, start, end, color, width, startArrow, endArrow); GL.PopAttrib(); }
public void Draw(GuiWidget sender, IObject3D item, bool isSelected, DrawEventArgs e, Matrix4X4 itemMaxtrix, WorldView world) { throw new NotImplementedException(); #if false if (item.Mesh?.Faces.Count <= 0) { return; } var frustum = world.GetClippingFrustum(); var mesh = item.Mesh; foreach (var face in mesh.Faces) { int vertexCount = 0; Vector3 faceCenter = Vector3.Zero; foreach (var v in new[] { face.v0, face.v1, face.v2 }) { var vertex = mesh.Vertices[v]; faceCenter += vertex.Position; vertexCount++; } faceCenter /= vertexCount; var matrix = item.WorldMatrix(); var transformed1 = Vector3Ex.Transform(faceCenter, matrix); var normal = Vector3Ex.TransformNormal(face.Normal, matrix).GetNormal(); world.Render3DLineNoPrep(frustum, transformed1, transformed1 + normal, Color.Red, 2); } #endif }
public static void Render3DLineNoPrep(this WorldView world, Frustum clippingFrustum, Vector3Float start, Vector3Float end, Color color, double width = 1, bool startArrow = false, bool endArrow = false) { world.Render3DLineNoPrep(clippingFrustum, new Vector3(start), new Vector3(end), new Color(color), width, startArrow, endArrow); }
/// <summary> /// Draw a line in the scene in 3D but scale it such that it appears as a 2D line in the view. /// </summary> /// <param name="world"></param> /// <param name="clippingFrustum">This is a cache of the frustum from world. /// Much faster to pass this way if drawing lots of lines.</param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="color"></param> /// <param name="doDepthTest"></param> /// <param name="width"></param> public static void Render3DLine(this WorldView world, Frustum clippingFrustum, Vector3 start, Vector3 end, Color color, bool doDepthTest = true, double width = 1) { PrepareFor3DLineRender(doDepthTest); world.Render3DLineNoPrep(clippingFrustum, start, end, color, width); }
public static void Render3DLineNoPrep(this WorldView world, Frustum clippingFrustum, Vector3Float start, Vector3Float end, Color color, double width = 1) { world.Render3DLineNoPrep(clippingFrustum, new Vector3(start), new Vector3(end), new Color(color), width); }