public static void RenderAabb(this WorldView world, AxisAlignedBoundingBox bounds, Matrix4X4 matrix, Color color, double lineWidth = 1, double extendLineLength = 0)
        {
            GLHelper.PrepareFor3DLineRender(true);

            Frustum frustum = world.GetClippingFrustum();

            for (int i = 0; i < 4; i++)
            {
                Vector3 sideStartPosition = Vector3Ex.Transform(bounds.GetBottomCorner(i), matrix);
                Vector3 sideEndPosition   = Vector3Ex.Transform(bounds.GetTopCorner(i), matrix);

                Vector3 bottomStartPosition = sideStartPosition;
                Vector3 bottomEndPosition   = Vector3Ex.Transform(bounds.GetBottomCorner((i + 1) % 4), matrix);

                Vector3 topStartPosition = sideEndPosition;
                Vector3 topEndPosition   = Vector3Ex.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, lineWidth);
                world.Render3DLineNoPrep(frustum, topStartPosition, topEndPosition, color, lineWidth);
                world.Render3DLineNoPrep(frustum, bottomStartPosition, bottomEndPosition, color, lineWidth);
            }

            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);
                }
            }
        }