package debug import ( "image/color" "sync/atomic" "github.com/df-mc/dragonfly/server/world" "github.com/go-gl/mathgl/mgl64" ) var nextShapeID atomic.Int32 // Shape represents a shape that can be drawn to a player from any point in the world. type Shape interface { // ShapeID returns the unique identifier of the shape. This is used to either update or remove the shape // after it has been sent to the player. ShapeID() int } // shape is a base type for all shapes that implements the Shape interface. It contains a unique identifier // that is lazily initialised when the ShapeID method is called for the first time. type shape struct { id atomic.Int32 } // ShapeID ... func (s *shape) ShapeID() int { if id := s.id.Load(); id != 0 { return int(id) } s.id.CompareAndSwap(0, nextShapeID.Add(1)) return int(s.id.Load()) } // Arrow represents an arrow shape that can be drawn at any point in the world. It has a head which can also // be positioned anywhere, and the length, radius and number of segments can be changed. type Arrow struct { shape // Colour is the colour that will be used for the line and head. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // EndPosition is the end position of the arrow in the world. The arrow will be drawn from Position to // EndPosition, with the head being drawn at EndPosition. EndPosition mgl64.Vec3 // HeadLength is the length of the head to be drawn at the end of the arrow. If zero, it will default // to 1.0. HeadLength float64 // HeadRadius is the radius of the head to be drawn at the end of the arrow. If zero, it will default // to 0.5. HeadRadius float64 // HeadSegments is the number of segments that the head of the arrow will be drawn with. The more // segments, the smoother the head will look. If zero, it will default to 4. HeadSegments int // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Box represents a hollow box that can be drawn at any point in the world, with a bounds that can be set. type Box struct { shape // Colour is the colour that will be used for the outline. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0. Scale float64 // Bounds is the size of the box in the world, acting as an offset from the Position. If empty, // it will default to a 1x1x1 box. Bounds mgl64.Vec3 // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Circle represents a hollow circle that can be drawn at any point in the world, with the scale being used // to control the radius. type Circle struct { shape // Colour is the colour that will be used for the outline. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Scale is the radius of the circle. If zero, it will default to 1.0. Scale float64 // Segments is the number of segments that the circle will be drawn with. The more segments, the smoother // the circle will look. If empty, it will default to 20. Segments int // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Line represents a line that can be drawn at any point in the world, with a start and end position. type Line struct { shape // Colour is the colour that will be used for the line. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // EndPosition is the end position of the line in the world. The line will be drawn from Position to // EndPosition. EndPosition mgl64.Vec3 // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Sphere represents a hollow sphere that can be drawn at any point in the world, with one line in each axis. // The scale is used to control the radius of the sphere. type Sphere struct { shape // Colour is the colour that will be used for the outline. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Scale is the radius of the sphere. If zero, it will default to 1.0. Scale float64 // Segments is the number of segments that the circle will be drawn with. The more segments, the smoother // the circle will look. If empty, it will default to 20. Segments int // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Text represents text that can be drawn at any point in the world, looking like a normal entity nametag // without actually being attached to an entity. type Text struct { shape // Colour is the colour that will be used for the actual text. If empty, the text will default to white. Colour color.RGBA // BackgroundColour is the colour used for the text background. If empty, it will default to a // translucent black. BackgroundColour color.RGBA // HideBackground specifies whether the text background should be hidden entirely. Takes precedence // over BackgroundColour when set. HideBackground bool // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Rotation is the rotation of the shape, applied only when LockRotation is set. Rotation mgl64.Vec3 // Scale is the size of the text. If zero, it will default to 1.0. Scale float64 // Text is the text to be displayed on the shape. The background automatically scales to fit the text. Text string // LockRotation specifies whether the text should be locked to the orientation set by Rotation. // If false, the text will rotate to always face the camera. LockRotation bool // DisableDepthTest specifies whether the text should show through walls. If false, the text // will be occluded by geometry in front of it. DisableDepthTest bool // HideBackface specifies whether the background should be hidden on the back side of the shape. // Has no visible effect unless LockRotation is also set. HideBackface bool // HideBackfaceText specifies whether the text should be hidden on the back side of the shape. // Has no visible effect unless LockRotation is also set. HideBackfaceText bool // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Cylinder represents a hollow cylinder, or frustum, that can be drawn at any point in the world, with a // height running up the Y axis. The base and top each have their own radius on the X and Z axes, allowing // for tapered and elliptical cylinders. A Cone is the special case of a Cylinder with a zero top radius. type Cylinder struct { shape // Colour is the colour that will be used for the outline. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0. Scale float64 // BaseRadius is the radius of the cylinder's base along the X and Z axes. If empty, it will default to a // radius of 1.0 on each axis. Differing X and Z radii produce an elliptical cylinder. BaseRadius mgl64.Vec2 // TopRadius is the radius of the cylinder's top along the X and Z axes. If empty, it will default to // BaseRadius, producing a straight cylinder. A smaller TopRadius tapers the cylinder into a frustum. TopRadius mgl64.Vec2 // Height is the height of the cylinder. If zero, it will default to 1.0. Height float64 // Segments is the number of segments that the cylinder will be drawn with. The more segments, the // smoother the cylinder will look. If zero, it will default to 20. Segments int // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Pyramid represents a pyramid that can be drawn at any point in the world, with a base on the X and Z axes // and a height running up the Y axis to a single apex. type Pyramid struct { shape // Colour is the colour that will be used for the outline. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0. Scale float64 // Width is the width along the X axis of the pyramid base. If zero, it will default to 1.0. Width float64 // Depth is the depth along the Z axis of the pyramid base. If zero, it will default to Width. Depth float64 // Height is the height of the pyramid. If zero, it will default to 1.0. Height float64 // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Ellipsoid represents a hollow ellipsoid that can be drawn at any point in the world, with a radius along // each of the X, Y and Z axes. type Ellipsoid struct { shape // Colour is the colour that will be used for the outline. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0. Scale float64 // Radii are the radii of the ellipsoid along the X, Y and Z axes. If empty, it will default to a radius // of 1.0 on each axis. Radii mgl64.Vec3 // SegmentsPerAxis is the number of segments that the ellipsoid will be drawn with per axis. The more // segments, the smoother the ellipsoid will look. If zero, it will default to 20. SegmentsPerAxis int // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle } // Cone represents a cone that can be drawn at any point in the world, with a base on the X and Z axes and a // height running up the Y axis to a single apex. type Cone struct { shape // Colour is the colour that will be used for the outline. If empty, it will default to white. Colour color.RGBA // Position is the origin position of the shape in the world. Position mgl64.Vec3 // Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0. Scale float64 // Radii are the radii along the X and Z axes of the cone base. If empty, it will default to a radius of // 1.0 on each axis. Radii mgl64.Vec2 // Height is the height of the cone. If zero, it will default to 1.0. Height float64 // Segments is the number of segments that the cone will be drawn with. The more segments, the smoother // the cone will look. If zero, it will default to 20. Segments int // Entity is an optional entity handle to attach the shape to. Entity *world.EntityHandle }