Documentation
¶
Overview ¶
Package threed renders simple 3D models in a Termdash widget.
The public API is intentionally small:
stage, _ := threed.New(threed.ShowAxes(false), threed.UprightOnly(true)) stage.SetModel(threed.Cube(threed.ModelSize(2), threed.ModelColor(threed.NeonCyan)))
Models can come from primitives, charts, terminal boards, game maps, UTF-8 glyphs, images, KML, or custom faces. Higher-level helpers keep caller code short while the package owns projection, shading, glyph masks, and board construction details.
Primitive shapes:
model := threed.Pyramid(threed.ModelSize(1.8), threed.ModelRune('▲'))
Logic boards and game maps:
model := threed.LogicBoard([]string{
"╭──── CPU ────╮",
"│ ◆──◆──◆ █ │",
"╰────────────╯",
}, threed.ModelCellSize(0.06, 0.16))
UTF-8 glyphs and images:
glyph := threed.Glyph("✦", threed.ModelSize(1.2))
imageModel, err := threed.ModelFromImageFile("logo.png")
kmlModel, err := threed.ModelFromKMLURL(ctx, "https://example.com/map.kml")
Index ¶
- Variables
- func AddGlyphBillboard(model *Model, center Vector3D, size float64, glyph rune, color Color)
- func ImageToBrailleLines(img image.Image, cols, rows int) []string
- func RenderableRune(frame string, fallback rune) rune
- type Camera
- type Color
- type Coordinate
- type Document
- type Face
- type FaceRenderMode
- type Folder
- type KML
- type LineString
- type LinearRing
- type Model
- func BarChart(data []float64, opts ...ModelOption) *Model
- func CenteredGlyphBoard(center Vector3D, rows []string, cellWidth, cellHeight float64, ...) *Model
- func CreateCube(position Vector3D, size float64, char rune) *Model
- func CreateOctahedron(position Vector3D, size float64) *Model
- func CreatePyramid(position Vector3D, size float64, char rune) *Model
- func CreateSphere(position Vector3D, radius float64, latSegments, lonSegments int, char rune) *Model
- func CreateTetrahedron(position Vector3D, size float64) *Model
- func Cube(opts ...ModelOption) *Model
- func GameBoard(rows []string, opts ...ModelOption) *Model
- func GenerateBarChartModel(data []float64) *Model
- func GenerateLineChartModel(data []float64) *Model
- func GenerateModelFromKML(kml *KML, logger *log.Logger) (*Model, error)
- func Glyph(text string, opts ...ModelOption) *Model
- func GlyphBoard(origin Vector3D, rows []string, cellWidth, cellHeight float64, ...) *Model
- func ImageToModel(img image.Image) *Model
- func LineChart(data []float64, opts ...ModelOption) *Model
- func LoadImageModel(path string) (*Model, error)
- func LogicBoard(rows []string, opts ...ModelOption) *Model
- func ModelFromImage(img image.Image, opts ...ModelOption) *Model
- func ModelFromImageFile(path string, opts ...ModelOption) (*Model, error)
- func ModelFromKML(kml *KML, opts ...ModelOption) (*Model, error)
- func ModelFromKMLURL(ctx context.Context, url string, opts ...ModelOption) (*Model, error)
- func NetworkSpectrum(download, upload []float64, opts ...ModelOption) *Model
- func NewAnimatedSpinnerStarPrism(frame string, step int) *Model
- func NewAnimatedSymbolSpinner(frame string, step int) *Model
- func NewModel() *Model
- func Octahedron(opts ...ModelOption) *Model
- func Pyramid(opts ...ModelOption) *Model
- func Shape(kind ShapeKind, opts ...ModelOption) *Model
- func SpectrumAnalyzer(bands []float64, opts ...ModelOption) *Model
- func Sphere(opts ...ModelOption) *Model
- func SymbolSpinner(text string, step int) *Model
- func Tetrahedron(opts ...ModelOption) *Model
- func TextBoard(rows []string, opts ...ModelOption) *Model
- type ModelOption
- func ModelCellSize(width, height float64) ModelOption
- func ModelCentered(centered bool) ModelOption
- func ModelColor(color Color) ModelOption
- func ModelPosition(position Vector3D) ModelOption
- func ModelRune(char rune) ModelOption
- func ModelSegments(lat, lon int) ModelOption
- func ModelSize(size float64) ModelOption
- type Option
- func AmbientColor(color Color) Option
- func BackfaceCulling(enable bool) Option
- func DiffuseColor(color Color) Option
- func EnableLogging(_ bool) Optiondeprecated
- func LogWriter(w io.Writer) Option
- func RotationStep(step float64) Option
- func Shininess(shininess float64) Option
- func ShowAxes(show bool) Option
- func SpecularColor(color Color) Option
- func UprightOnly(enable bool) Option
- func ZoomScale(scale float64) Option
- type Options
- type OuterBoundary
- type Placemark
- type Point
- type Polygon
- type ProjectedFace
- type RotationMatrix
- type ShapeKind
- type ThreeD
- func (t *ThreeD) Draw(cvs *canvas.Canvas, _ *widgetapi.Meta) error
- func (t *ThreeD) Keyboard(k *terminalapi.Keyboard, _ *widgetapi.EventMeta) error
- func (t *ThreeD) Mouse(m *terminalapi.Mouse, _ *widgetapi.EventMeta) error
- func (t *ThreeD) Options() widgetapi.Options
- func (t *ThreeD) Rotate(delta Vector3D)
- func (t *ThreeD) SetModel(model *Model)
- type Vector2D
- type Vector3D
- func (v Vector3D) Add(other Vector3D) Vector3D
- func (v Vector3D) Cross(other Vector3D) Vector3D
- func (v Vector3D) Dot(other Vector3D) float64
- func (v Vector3D) Multiply(scalar float64) Vector3D
- func (v Vector3D) Normalize() Vector3D
- func (v Vector3D) Rotate(rot Vector3D) Vector3D
- func (v Vector3D) Subtract(other Vector3D) Vector3D
- type ZoomHandler
Constants ¶
This section is empty.
Variables ¶
var ( // NeonCyan is a crisp technical accent for wireframes and boards. NeonCyan = Color{R: 0.50, G: 0.92, B: 0.96} // NeonGreen is a bright signal color for nodes and highlights. NeonGreen = Color{R: 0.52, G: 0.98, B: 0.38} // Amber is a warm graph and warning accent. Amber = Color{R: 0.98, G: 0.78, B: 0.28} // Rose is a saturated block/module accent. Rose = Color{R: 0.96, G: 0.36, B: 0.52} // SoftWhite is readable foreground on dark terminals. SoftWhite = Color{R: 0.86, G: 0.88, B: 0.90} )
Functions ¶
func AddGlyphBillboard ¶
AddGlyphBillboard appends a square glyph face centered at a 3D position to model. size controls the face half-extent; color is applied to the face.
func ImageToBrailleLines ¶
ImageToBrailleLines converts an image.Image into a slice of braille-encoded text lines forming a pixel-art preview.
cols and rows control the output size in braille characters; each braille cell covers 2×4 pixels, so the preview is rendered at cols*2 × rows*4 pixel resolution.
Returns nil when the image is nil or contains no renderable pixels.
func RenderableRune ¶
RenderableRune converts a UTF-8 frame string into a rune that the threed renderer can safely use for face filling.
The threed renderer is cell-based, so wide glyphs and multi-symbol strings cannot be drawn reliably as face characters. This helper keeps simple single-cell symbols as-is, accepts harmless trailing variation selectors or combining marks, and falls back otherwise.
Types ¶
type Camera ¶
type Camera struct {
Width int // Viewport width in cells
Height int // Viewport height in cells
Scale float64 // Scale factor applied after projection
Direction Vector3D // Forward direction the camera looks (world space)
Zoom float64 // Distance from camera to scene origin along Z
// contains filtered or unexported fields
}
Camera represents the viewer's perspective.
func NewCamera ¶
NewCamera creates a new camera with default settings. The camera sits at z = -Zoom and looks in the +Z direction.
func (*Camera) AdjustScale ¶
AdjustScale sets the camera scale so the model fits within the viewport.
func (*Camera) Project ¶
Project maps a 3D point into 2D screen space using perspective projection. The per-frame constants (fovRadFactor, aspectRatio, halfW, halfH) are pre-cached by UpdateProjection; only a few multiplications and one division are needed here.
func (*Camera) UpdateProjection ¶
func (c *Camera) UpdateProjection()
UpdateProjection caches the aspect ratio and screen-centre values that Project uses for every vertex. Call this once after changing Width or Height rather than recomputing inside the hot per-vertex path.
type Color ¶
type Color struct {
R float64 // Red component (0.0 - 1.0)
G float64 // Green component (0.0 - 1.0)
B float64 // Blue component (0.0 - 1.0)
}
Color represents an RGB color with values between 0 and 1.
func (Color) ToCellColor ¶
ToCellColor converts the Color to a cell.Color using full 24-bit true-color encoding. Unlike ColorRGB24 (which quantises to 6 levels per channel), ColorTrueRGB preserves all 256 levels so Phong shading gradients remain smooth across the full dynamic range.
type Coordinate ¶
type Coordinate struct {
Longitude float64 // Longitude in degrees
Latitude float64 // Latitude in degrees
Altitude float64 // Altitude in meters
}
Coordinate represents a single geographic coordinate.
func ParseCoordinates ¶
func ParseCoordinates(coordStr string) ([]Coordinate, error)
ParseCoordinates parses a KML coordinates string into a slice of Coordinates.
type Document ¶
type Document struct {
XMLName xml.Name `xml:"Document"`
Name string `xml:"name"`
Placemarks []Placemark `xml:"Placemark"`
Folders []Folder `xml:"Folder"`
}
Document represents a KML Document element.
type Face ¶
type Face struct {
Vertices []Vector3D // Vertices of the face
Char rune // Character to render for this face
RenderMode FaceRenderMode // How the face character should be drawn
Color Color // Optional base color for this face
HasColor bool // Whether Color should override the widget diffuse color
Normal Vector3D // Pre-computed unit normal in model space; set by Model.AddFace.
}
Face represents a polygon face made up of vertices.
type FaceRenderMode ¶
type FaceRenderMode int
FaceRenderMode controls how a face character is drawn.
const ( // FaceRenderFill paints the entire polygon using the face character. FaceRenderFill FaceRenderMode = iota // FaceRenderGlyph draws the face character once at the projected face center. FaceRenderGlyph )
type Folder ¶
type Folder struct {
XMLName xml.Name `xml:"Folder"`
Name string `xml:"name"`
Placemarks []Placemark `xml:"Placemark"`
Folders []Folder `xml:"Folder"`
}
Folder represents a KML Folder element.
type LineString ¶
type LineString struct {
XMLName xml.Name `xml:"LineString"`
Coordinates string `xml:"coordinates"`
}
LineString represents a KML LineString element.
type LinearRing ¶
type LinearRing struct {
XMLName xml.Name `xml:"LinearRing"`
Coordinates string `xml:"coordinates"`
}
LinearRing represents a KML LinearRing element.
type Model ¶
type Model struct {
Faces []Face // Faces of the model
}
Model represents a 3D model composed of faces.
func BarChart ¶
func BarChart(data []float64, opts ...ModelOption) *Model
BarChart converts data into a 3D bar chart model.
func CenteredGlyphBoard ¶
func CenteredGlyphBoard(center Vector3D, rows []string, cellWidth, cellHeight float64, colorFn func(rune) Color) *Model
CenteredGlyphBoard centers all rows around center and then calls GlyphBoard.
func CreateCube ¶
CreateCube creates a cube model centered at the specified position.
func CreateOctahedron ¶
CreateOctahedron creates an octahedron model centered at the specified position.
func CreatePyramid ¶
CreatePyramid creates a square pyramid model centered at the specified position.
func CreateSphere ¶
func CreateSphere(position Vector3D, radius float64, latSegments, lonSegments int, char rune) *Model
CreateSphere creates a low-poly sphere model centered at the specified position.
func CreateTetrahedron ¶
CreateTetrahedron creates a tetrahedron model centered at the specified position.
func GameBoard ¶
func GameBoard(rows []string, opts ...ModelOption) *Model
GameBoard converts an ASCII/UTF-8 game map into a colored 3D model.
func GenerateBarChartModel ¶
GenerateBarChartModel generates a 3D bar chart model from data.
func GenerateLineChartModel ¶
GenerateLineChartModel generates a 3D line chart model from data.
func GenerateModelFromKML ¶
GenerateModelFromKML generates a 3D model from KML data.
func Glyph ¶
func Glyph(text string, opts ...ModelOption) *Model
Glyph converts a UTF-8 string into a single 3D glyph billboard.
func GlyphBoard ¶
func GlyphBoard(origin Vector3D, rows []string, cellWidth, cellHeight float64, colorFn func(rune) Color) *Model
GlyphBoard places each non-space rune from rows as a glyph billboard, starting at origin and stepping right/down by cellWidth/cellHeight. colorFn maps each rune to its face color; pass nil to use a neutral grey.
func ImageToModel ¶
ImageToModel converts any image.Image into an extruded 3D model suitable for the ThreeD widget spinner.
The model resolution is defaultSymbolModelResolution, preserving enough detail for terminal-sized 3D rendering. Pixel colors from the source image are preserved on the face geometry.
Returns nil when the image contains no renderable pixels.
func LineChart ¶
func LineChart(data []float64, opts ...ModelOption) *Model
LineChart converts data into a 3D line chart model.
func LoadImageModel ¶
LoadImageModel reads an image file from disk and converts it into an extruded 3D model that can be spun in the ThreeD widget.
PNG images with a transparent background work best — the alpha channel determines which pixels become geometry. For fully-opaque images (JPEG, flat PNG) dark/saturated pixels are treated as filled, which works well for dark logos on white backgrounds.
Returns nil, err if the file cannot be opened or decoded.
func LogicBoard ¶
func LogicBoard(rows []string, opts ...ModelOption) *Model
LogicBoard converts circuit/logic-board text into a colored 3D model.
func ModelFromImage ¶
func ModelFromImage(img image.Image, opts ...ModelOption) *Model
ModelFromImage converts an image into a 3D model.
func ModelFromImageFile ¶
func ModelFromImageFile(path string, opts ...ModelOption) (*Model, error)
ModelFromImageFile loads an image file and converts it into a 3D model.
func ModelFromKML ¶
func ModelFromKML(kml *KML, opts ...ModelOption) (*Model, error)
ModelFromKML converts parsed KML data into a 3D model.
func ModelFromKMLURL ¶
ModelFromKMLURL fetches a KML document and converts it into a 3D model.
func NetworkSpectrum ¶
func NetworkSpectrum(download, upload []float64, opts ...ModelOption) *Model
NetworkSpectrum converts download and upload rates into a split 3D spectrum.
func NewAnimatedSpinnerStarPrism ¶
NewAnimatedSpinnerStarPrism creates a dense star prism model that is sized and colored for spinner-driven animation sequences.
The frame argument may be any UTF-8 spinner frame. If the frame cannot be rendered safely as a single-cell face character, the model falls back to a compatible star glyph.
func NewAnimatedSymbolSpinner ¶
NewAnimatedSymbolSpinner creates a symbol-driven model for UTF-8 glyphs.
Symbols are rendered directly into a small animated prism. The helper does not fetch, embed, or rasterize external artwork.
func Octahedron ¶
func Octahedron(opts ...ModelOption) *Model
Octahedron creates an octahedron model.
func Shape ¶
func Shape(kind ShapeKind, opts ...ModelOption) *Model
Shape creates a built-in primitive model.
func SpectrumAnalyzer ¶
func SpectrumAnalyzer(bands []float64, opts ...ModelOption) *Model
SpectrumAnalyzer converts normalized band values into a 3D bar analyzer.
func SymbolSpinner ¶
SymbolSpinner converts a UTF-8 string into an animated symbol model.
func Tetrahedron ¶
func Tetrahedron(opts ...ModelOption) *Model
Tetrahedron creates a tetrahedron model.
func TextBoard ¶
func TextBoard(rows []string, opts ...ModelOption) *Model
TextBoard converts terminal text rows into centered 3D glyph billboards.
Use it for labels, lightweight diagrams, game maps, or any other terminal native composition where the source is already readable UTF-8 text.
func (*Model) AddFace ¶
AddFace adds a face to the model. It pre-computes the unit normal for faces with at least 3 vertices so the Draw loop can skip the per-frame cross-product.
type ModelOption ¶
type ModelOption interface {
// contains filtered or unexported methods
}
ModelOption configures shape, glyph, board, chart, and conversion helpers.
func ModelCellSize ¶
func ModelCellSize(width, height float64) ModelOption
ModelCellSize sets the cell spacing used by text, logic, and game boards.
func ModelCentered ¶
func ModelCentered(centered bool) ModelOption
ModelCentered controls whether text board helpers center their rows.
func ModelColor ¶
func ModelColor(color Color) ModelOption
ModelColor applies a fixed color to all faces produced by the helper.
func ModelPosition ¶
func ModelPosition(position Vector3D) ModelOption
ModelPosition sets the model origin or center.
func ModelSegments ¶
func ModelSegments(lat, lon int) ModelOption
ModelSegments sets sphere tessellation as latitude and longitude segments.
func ModelSize ¶
func ModelSize(size float64) ModelOption
ModelSize sets the size used by shapes and single glyphs.
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
Option represents a configuration option.
func AmbientColor ¶
AmbientColor sets the ambient light color.
func BackfaceCulling ¶
BackfaceCulling sets whether faces pointed away from the camera are skipped.
func DiffuseColor ¶
DiffuseColor sets the diffuse light color.
func EnableLogging
deprecated
func LogWriter ¶
LogWriter directs debug logs to w. Pass io.Discard (or omit the option) to silence all logging. New() never opens files; callers supply the writer.
func RotationStep ¶
RotationStep sets the rotation step size.
func SpecularColor ¶
SpecularColor sets the specular light color.
func UprightOnly ¶
UprightOnly locks the model upright so it cannot pitch or roll upside down.
type Options ¶
type Options struct {
RotationStep float64 // Rotation step size in radians
ZoomScale float64 // Initial zoom scale for the camera
UprightOnly bool // Whether to lock the model upright and rotate only around Y
ShowAxes bool // Whether to display axes
AmbientColor Color // Ambient light color
DiffuseColor Color // Diffuse light color
SpecularColor Color // Specular light color
Shininess float64 // Shininess factor for specular reflection
LogWriter io.Writer // Destination for debug logs; nil disables logging.
BackfaceCulling bool // Whether to skip faces pointed away from the camera
}
Options represents configuration options for the ThreeD widget.
type OuterBoundary ¶
type OuterBoundary struct {
XMLName xml.Name `xml:"outerBoundaryIs"`
LinearRing LinearRing `xml:"LinearRing"`
}
OuterBoundary represents the outer boundary of a KML Polygon.
type Placemark ¶
type Placemark struct {
XMLName xml.Name `xml:"Placemark"`
Name string `xml:"name"`
Description string `xml:"description"`
Point *Point `xml:"Point"`
LineString *LineString `xml:"LineString"`
Polygon *Polygon `xml:"Polygon"`
}
Placemark represents a KML Placemark element.
func ExtractPlacemarksFromDocument ¶
ExtractPlacemarksFromDocument extracts placemarks from a KML document.
func ExtractPlacemarksFromFolder ¶
ExtractPlacemarksFromFolder extracts placemarks from a KML folder.
type Polygon ¶
type Polygon struct {
XMLName xml.Name `xml:"Polygon"`
OuterBoundary OuterBoundary `xml:"outerBoundaryIs"`
}
Polygon represents a KML Polygon element.
type ProjectedFace ¶
type ProjectedFace struct {
Points []Vector2D // Projected 2D points
Depths []float64 // Per-point transformed Z values used for depth tests
Normal Vector3D // Normal vector of the face
Brightness float64 // Brightness for shading
Depth float64 // Average depth for sorting
Char rune // Character to render
RenderMode FaceRenderMode
Color Color // Optional base color for shading
HasColor bool // Whether Color should override the widget diffuse color
ShadeColor Color // Final shaded color used for rendering
}
ProjectedFace represents a face projected onto 2D space.
type RotationMatrix ¶
type RotationMatrix [3][3]float64
RotationMatrix is a pre-computed 3×3 rotation matrix that applies the same X→Y→Z Euler rotation as Vector3D.Rotate but at the cost of only 6 trig calls per frame instead of 6 per vertex.
func BuildRotationMatrix ¶
func BuildRotationMatrix(rot Vector3D) RotationMatrix
BuildRotationMatrix constructs a combined X→Y→Z rotation matrix from the given Euler angles (in radians). The resulting matrix matches the sequential application performed by Vector3D.Rotate.
Derivation:
cx,sx = cos/sin(rot.X), cy,sy = cos/sin(rot.Y), cz,sz = cos/sin(rot.Z)
R = [[ cy*cz, sx*sy*cz - cx*sz, cx*sy*cz + sx*sz ],
[ cy*sz, sx*sy*sz + cx*cz, cx*sy*sz - sx*cz ],
[ -sy, sx*cy, cx*cy ]]
func (RotationMatrix) Apply ¶
func (m RotationMatrix) Apply(v Vector3D) Vector3D
Apply rotates vector v by the pre-computed rotation matrix using 9 multiplications and no trigonometry.
type ShapeKind ¶
type ShapeKind int
ShapeKind identifies a built-in primitive shape.
const ( // ShapeCube is the built-in cube primitive. ShapeCube ShapeKind = iota // ShapePyramid is the built-in square pyramid primitive. ShapePyramid // ShapeTetrahedron is the built-in tetrahedron primitive. ShapeTetrahedron // ShapeOctahedron is the built-in octahedron primitive. ShapeOctahedron // ShapeSphere is the built-in sphere primitive. ShapeSphere )
type ThreeD ¶
type ThreeD struct {
// contains filtered or unexported fields
}
ThreeD is a custom Termdash widget that renders enhanced 3D objects.
type Vector3D ¶
type Vector3D struct {
X float64 // X coordinate
Y float64 // Y coordinate
Z float64 // Z coordinate
}
Vector3D represents a point or vector in 3D space.
func GeoTo3D ¶
func GeoTo3D(coord Coordinate) Vector3D
GeoTo3D converts geographical coordinates to 3D Cartesian coordinates.
type ZoomHandler ¶
type ZoomHandler struct {
Scale float64 // Current scale factor; default 20.0.
}
ZoomHandler manages the zoom scale for the ThreeD widget.
All methods are called with ThreeD.mu already held; no additional locking is needed here.
func NewZoomHandler ¶
func NewZoomHandler() *ZoomHandler
NewZoomHandler creates a ZoomHandler with the default scale.
func (*ZoomHandler) ZoomIn ¶
func (z *ZoomHandler) ZoomIn()
ZoomIn multiplies Scale by 1.1 and clamps to [minZoomScale, maxZoomScale].
func (*ZoomHandler) ZoomOut ¶
func (z *ZoomHandler) ZoomOut()
ZoomOut multiplies Scale by 0.9 and clamps to [minZoomScale, maxZoomScale].
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Binary threeddemo shows the threed widget as a polished multi-scene showcase.
|
Binary threeddemo shows the threed widget as a polished multi-scene showcase. |