xyz

package
v0.3.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 10, 2024 License: BSD-3-Clause Imports: 32 Imported by: 6

README

XYZ

xyz is a 3D graphics framework written in Go. It is a separate standalone package that renders to an offscreen WebGPU framebuffer, which can easily be converted into a Go image.RGBA. The xyzcore package provides an integration of xyz in Cogent Core, for dynamic and efficient 3D rendering within 2D GUI windows.

xyz is built on the gpu WebGPU framework (specifically the phong rendering system, and uses the tree tree structure for the scenegraph. It currently supports standard Phong-based rendering with different types of lights and materials. It is designed for scientific and other non-game 3D applications, and lacks some of the advanced features one would expect in a modern 3D graphics framework. Thus, its primary advantage is its simplicity and support for directly programming 3D visualizations in Go, its broad cross-platform support across all major desktop, mobile, and web platforms, and the use of WebGPU which is highly efficient.

  • The physics sub-package provides a physics engine for simulating 3D virtual worlds, using xyz.

Updating

  • You must call SetMesh or SetTexture to update or add a new Mesh or Texture element. Just changing an existing mesh by itself does not trigger the proper updates.

  • The xyz.Scene.Update() method updates the scenegraph object matricies and triggers re-render. .Render() or NeedsRender() just drives a new render if only the camera parameters have changed, but this will not reflect changes in object poses.

  • xyzcore.Scene.UpdateWidget() is the cleanest way to trigger the Update on the underlying xyx.Scene and also a re-render of the core widget viewing that scene. If using an xyzcore.SceneEditor then use Editor.SceneWidget().UpdateWidget().

Basic elements

The 3D scenegraph is rooted at a xyz.Scene node, which contains all of the shared Mesh and Texture elements, along with Lights, Camera and a Library of loaded 3D objects that can be referenced by name.

Mesh and Texture elements use the "Set / Reset" approach, where Set does add or update, based on unique name id, and if there are large changes and unused elements, a Reset can be used to start over. After the GPU is up and running (e.g., after the main app window is opened in xyzcore), changes take effect immediately, but everything can be configured prior to that, and they will all be applied when the GPU is activated.

Children of the Scene are Node nodes, with Group and Solid as the main subtypes. NodeBase is the base implementation, which has a Pose for the full matrix transform of relative position, scale, rotation, and bounding boxes at multiple levels.

  • Group is a container -- most discrete objects should be organized into a Group, with Groups of Solids underneath. For maximum efficiency it is important to organize large scenegraphs into hierarchical groups by location, so that regions can be pruned for rendering. The Pose on the Group is inherited by everything under it, so things can be transformed at different levels as well.

  • Solid has a Material to define the color / texture of the solid, and the name of a Mesh that defines the shape. Thus, the scenegraph elements are very lightweight and basically point (by name) to shared larger resources on the Scene, where they can be efficiently shared among any number of Solid elements.

Objects that have uniform Material color properties on all surfaces can be a single Solid, but if you need e.g., different textures for each side of a box then that must be represented as a Group of Solids using Plane Meshes, each of which can then bind to a different Texture via their Material settings.

Node bounding boxes are in both local and World reference frames, and are used for visibility (render pruning) and event selection. Very large scenegraphs can be efficiently rendered by organizing elements into larger and larger Group collections: pruning automatically happens at the highest level where everything below is invisible. This same principle is used in eve for efficient collision detection.

Meshes are exclusively defined by indexed triangles, and there are standard shapes such as Box, Sphere, Cylinder, Capsule, and Lines (rendered as thin boxes with end points specified).

Textures are loaded from Go image files, stored by unique names on the Scene, and the Node-specific Material can optionally refer to a texture -- likewise allowing efficient re-use across different Solids.

The Scene also contains a Library of uniquely named "objects" (Groups) which can be loaded from 3D object files, and then added into the scenegraph as needed. Thus, a typical, efficient workflow is to initialize a Library of such objects, and then configure the specific scene from these objects. The library objects are Cloned into the scenegraph so they can be independently configured and manipulated there. Because the Group and Solid nodes are lightweight, this is all very efficient.

The Scene also holds the Camera and Lights for rendering -- there is no point in putting these out in the scenegraph -- if you want to add a Solid representing one of these elements, you can easily do so.

The Scene is fully in charge of the rendering process by iterating over the scene elements and culling out-of-view elements, ordering opaque then transparent elements, etc.

There are standard Render types that manage the relevant GPU programs / Pipelines to do the actual rendering, depending on Material and Mesh properties (e.g., uniform vs per-vertex color vs. texture).

Scenegraph Structure

  • Scene is the root node of the 3D scenegraph.

    • Camera is a field on the Scene that has all the current camera settings. By default the camera does a naturalistic Perspective projection, but you can enable Orthographic by ticking the Ortho button -- you will generally need to reduce the Far plane value to be able to see anything -- the Ortho projection shows you the entire scene within those two planes, and it scales accordingly to be able to fit everything.

    • Lights contain the lighting parameters for the scene -- if you don't have any lights, everything will be dark!

      • Ambient lights contribute generic lighting to every surface uniformly -- usually have this at a low level to represent scattered light that has bounced around everywhere.
      • Directional lights represent a distant light-source like the sun, with effectively parallel rays -- the position of the light determines its direction by pointing back from there to the origin -- think of it as the location of the sun. Only the normal direction value is used so the magnitude of the values doesn't matter.
      • Point lights have a specific position and radiate light uniformly in all directions from that point, with both a linear and quadratic decay term.
      • Spot lights are the most sophisticated lights, with both a position and direction, and an angular cutoff so light only spreads out in a cone, with appropriate decay factors.
    • Meshes are the library of Mesh shapes that can be used in the scene. These provide the triangle-based surfaces used to define shapes. The shape.go code provides the basic geometric primitives such as Box, Sphere, Cylinder, etc, and you can load mesh shapes from standard .obj files as exported by almost all 3D rendering programs. You can also write code to generate your own custom / dynamic shapes, as we do with the NetView in the emergent neural network simulation system.

    • Textures are the library of Texture files that define more complex colored surfaces for objects. These can be loaded from standard image files.

    • Solids are the Children of the Scene, and actually determine the content of the 3D scene. Each Solid has a Mesh field with the name of the mesh that defines its shape, and a Mat field that determines its material properties (Color, Texture, etc). In addition, each Solid has its own Pose field that determines its position, scale and orientation within the scene. Because each Solid is a tree.Node tree node, it can contain other scene elements as its Children -- they will inherit the Pose settings of the parent (and so-on up the tree -- all poses are cumulative) but not automatically any material settings. You can call CopyMatToChildren if you want to apply the current materials to the children nodes. And use Style parameters to set these according to node name or Class name.

    • Groups can be used to apply Pose settings to a set of Children that are all grouped together (e.g., a multi-part complex object can be moved together etc by putting a set of Solids into a Group)

Events, Selection, Manipulation

Mouse events are handled by the standard Cogent Core Window event dispatching methods, based on bounding boxes which are always updated -- this greatly simplifies gui interactions. There is default support for selection and Pose manipulation handling -- see manip.go code and NodeBase's ConnectEvents3D which responds to mouse clicks.

Embedded 2D Viewport

A full 2D Cogent Core GUI can be embedded within a 3D scene using the xyzcore.Embed2D Node type, which renders a core.Scene onto a Texture projected onto a Plane. It captures events within its own bounding box, and translates them into coordinates for the 2D embedded gui. This allows full 2D interactive control within whatever perspective is present in the 3D scene. However, things like cursors and popups render in the flat 2D screen and are only approximately located.

In addition to interactive guis, the embedded 2D node can be used for rendering full SVG graphics to a texture.

Documentation

Overview

Package xyz is a 3D graphics framework written in Go. It is a separate standalone package that renders to an offscreen Vulkan framebuffer, which can easily be converted into a Go `image.RGBA`. The xyzcore package provides an integration of xyz in Cogent Core, for dynamic and efficient 3D rendering within 2D GUI windows.

Children of the Scene are Node nodes, with Group and Solid as the main subtypes. NodeBase is the base implementation, which has a Pose for the full matrix transform of relative position, scale, rotation, and bounding boxes at multiple levels.

* Group is a container -- most discrete objects should be organized into a Group, with Groups of Solids underneath. For maximum efficiency it is important to organize large scenegraphs into hierarchical groups by location, so that regions can be pruned for rendering. The Pose on the Group is inherited by everything under it, so things can be transformed at different levels as well.

* Solid has a Material to define the color / texture of the solid, and the name of a Mesh that defines the shape.

Objects that have uniform Material color properties on all surfaces can be a single Solid, but if you need e.g., different textures for each side of a box then that must be represented as a Group of Solids using Plane Mesh's, each of which can then bind to a different Texture via their Material settings.

Node bounding boxes are in both local and World reference frames, and are used for visibility and event selection.

All Meshes are stored directly on the Scene, and must have unique names, as they are referenced from Solids by name. The Mesh contains all the vertices, etc that define a shape, and are the major memory-consuming elements of the scene (along with textures). Thus, the Solid is very lightweight and just points to the Mesh, so Meshes can be reused across multiple Solids for efficiency.

Meshes are only indexed triangles, and there are standard shapes such as Box, Sphere, Cylinder, Capsule, and Line (rendered as a thin Box with end points specified).

Textures are also stored by unique names on the Scene, and the Material can optionally refer to a texture -- likewise allowing efficient re-use across different Solids.

The Scene also contains a Library of uniquely named "objects" (Groups) which can be loaded from 3D object files, and then added into the scenegraph as needed. Thus, a typical, efficient workflow is to initialize a Library of such objects, and then configure the specific scene from these objects. The library objects are Cloned into the scenegraph -- because the Group and Solid nodes are lightweight, this is all very efficient.

The Scene also holds the Camera and Lights for rendering -- there is no point in putting these out in the scenegraph -- if you want to add a Solid representing one of these elements, you can easily do so.

The Scene is fully in charge of the rendering process by iterating over the scene elements and culling out-of-view elements, ordering opaque then transparent elements, etc.

There are standard Render types that manage the relevant GPU programs / Pipelines to do the actual rendering, depending on Material and Mesh properties (e.g., uniform vs per-vertex color vs. texture).

Any change to the Mesh after first initialization (Config) must be activated by calling Scene.InitMesh(nm) or Scene.InitMeshes() to redo all. The Update method on the Scene does Config and re-renders.

Mouse events are handled by the standard Cogent Core Window event dispatching methods, based on bounding boxes which are always updated -- this greatly simplifies gui interactions. There is default support for selection and Pose manipulation handling -- see manip.go code and NodeBase's ConnectEvents3D which responds to mouse clicks.

Package xyz provides a 3D graphics framework in Go.

Index

Constants

View Source
const (
	// CloseLines is used for the closed arg in NewLines:
	// connect first and last
	CloseLines = true

	// OpenLines is used for the closed arg in NewLines:
	// don't connect first and last
	OpenLines = false
)
View Source
const (
	// StartArrow specifies to add a starting arrow
	StartArrow = true

	// NoStartArrow specifies not to add a starting arrow
	NoStartArrow = false

	// EndArrow specifies to add a ending arrow
	EndArrow = true

	// EndArrow specifies not to add a ending arrow
	NoEndArrow = false
)
View Source
const (
	// Inactive is used for args indicating if node should be inactive
	Inactive = true

	// Active is used for args indicating if node should be inactive or not
	Active = false
)
View Source
const (
	// TrackCameraName is a reserved top-level Group name -- this group
	// will have its Pose updated to match that of the camera automatically.
	TrackCameraName = "TrackCamera"

	// Plane2DMeshName is the reserved name for the 2D plane mesh
	// used for Text2D and Embed2D
	Plane2DMeshName = "__Plane2D"

	// LineMeshName is the reserved name for a unit-sized Line segment
	LineMeshName = "__UnitLine"

	// ConeMeshName is the reserved name for a unit-sized Cone segment.
	// Has the number of segments appended.
	ConeMeshName = "__UnitCone"
)

Variables

View Source
var (
	OrbitFactor = float32(0.025)
	PanFactor   = float32(0.001)
)
View Source
var Decoders = map[string]Decoder{}

Decoders is the master list of decoders, indexed by the primary extension. .obj = Wavefront object file -- only has mesh data, not scene info.

View Source
var LightColorMap = map[LightColors]color.RGBA{
	DirectSun:    {255, 255, 255, 255},
	CarbonArc:    {255, 250, 244, 255},
	Halogen:      {255, 241, 224, 255},
	Tungsten100W: {255, 214, 170, 255},
	Tungsten40W:  {255, 197, 143, 255},
	Candle:       {255, 147, 41, 255},
	Overcast:     {201, 226, 255, 255},
	FluorWarm:    {255, 244, 229, 255},
	FluorStd:     {244, 255, 250, 255},
	FluorCool:    {212, 235, 255, 255},
	FluorFull:    {255, 244, 242, 255},
	FluorGrow:    {255, 239, 247, 255},
	MercuryVapor: {216, 247, 255, 255},
	SodiumVapor:  {255, 209, 178, 255},
	MetalHalide:  {242, 252, 255, 255},
}

LightColorMap provides a map of named light colors

View Source
var Update3DTrace = false

Set Update3DTrace to true to get a trace of 3D updating

Functions

func AsNode

func AsNode(n tree.Node) (Node, *NodeBase)

AsNode converts the given tree node to a Node and NodeBase, returning nil if that is not possible.

func SetLineStartEnd

func SetLineStartEnd(pose *Pose, st, ed math32.Vector3)

SetLineStartEnd sets line Pose such that it starts / ends at given poitns.

func UpdateWorldMatrix

func UpdateWorldMatrix(n tree.Node)

UpdateWorldMatrix updates the world matrix for node and everything inside it

Types

type Ambient added in v0.3.2

type Ambient struct {
	LightBase
}

Ambient provides diffuse uniform lighting; typically only one of these in a Scene.

func NewAmbient added in v0.3.2

func NewAmbient(sc *Scene, name string, lumens float32, color LightColors) *Ambient

NewAmbient adds Ambient to given scene, with given name, standard color, and lumens (0-1 normalized).

type BBox

type BBox struct {

	// bounding box in local coords
	BBox math32.Box3

	// bounding sphere in local coords
	BSphere math32.Sphere

	// area
	Area float32

	// volume
	Volume float32
}

BBox contains bounding box and other gross solid properties

func (*BBox) SetBounds

func (bb *BBox) SetBounds(min, max math32.Vector3)

SetBounds sets BBox from min, max and updates other factors based on that

func (*BBox) UpdateFromBBox added in v0.0.10

func (bb *BBox) UpdateFromBBox()

UpdateFromBBox updates other values from BBox

type Box

type Box struct {
	MeshBase

	// size along each dimension
	Size math32.Vector3

	// number of segments to divide each plane into (enforced to be at least 1) -- may potentially increase rendering quality to have > 1
	Segs math32.Vector3i
}

Box is a rectangular-shaped solid (cuboid)

func NewBox

func NewBox(sc *Scene, name string, width, height, depth float32) *Box

NewBox adds Box mesh to given scene, with given name and size

func (*Box) MeshSize added in v0.3.2

func (bx *Box) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*Box) Set

func (bx *Box) Set(vertex, normal, texcoord, clrs math32.ArrayF32, index math32.ArrayU32)

func (*Box) SetSegs

func (t *Box) SetSegs(v math32.Vector3i) *Box

SetSegs sets the [Box.Segs]: number of segments to divide each plane into (enforced to be at least 1) -- may potentially increase rendering quality to have > 1

func (*Box) SetSize

func (t *Box) SetSize(v math32.Vector3) *Box

SetSize sets the [Box.Size]: size along each dimension

type Camera

type Camera struct {

	// overall orientation and direction of the camera, relative to pointing at negative Z axis with up (positive Y) direction
	Pose Pose

	// target location for the camera -- where it is pointing at -- defaults to the origin, but moves with panning movements, and is reset by a call to LookAt method
	Target math32.Vector3

	// up direction for camera -- which way is up -- defaults to positive Y axis, and is reset by call to LookAt method
	UpDir math32.Vector3

	// default is a Perspective camera -- set this to make it Orthographic instead, in which case the view includes the volume specified by the Near - Far distance (i.e., you probably want to decrease Far).
	Ortho bool

	// field of view in degrees
	FOV float32

	// aspect ratio (width/height)
	Aspect float32

	// near plane z coordinate
	Near float32

	// far plane z coordinate
	Far float32

	// view matrix (inverse of the Pose.Matrix)
	ViewMatrix math32.Matrix4 `display:"-"`

	// projection matrix, defining the camera perspective / ortho transform
	ProjectionMatrix math32.Matrix4 `display:"-"`

	// inverse of the projection matrix
	InvProjectionMatrix math32.Matrix4 `display:"-"`

	// frustum of projection -- viewable space defined by 6 planes of a pyrammidal shape
	Frustum *math32.Frustum `display:"-"`
}

Camera defines the properties of the camera

func (*Camera) DefaultPose

func (cm *Camera) DefaultPose()

DefaultPose resets the camera pose to default location and orientation, looking at the origin from 0,0,10, with up Y axis

func (*Camera) Defaults

func (cm *Camera) Defaults()

func (*Camera) DistanceTo added in v0.1.4

func (cm *Camera) DistanceTo(pt math32.Vector3) float32

DistanceTo is the distance from camera to given point

func (*Camera) GenGoSet

func (cm *Camera) GenGoSet(path string) string

GenGoSet returns code to set values at given path (var.member etc)

func (*Camera) LookAt

func (cm *Camera) LookAt(target, upDir math32.Vector3)

LookAt points the camera at given target location, using given up direction, and sets the Target, UpDir fields for future camera movements.

func (*Camera) LookAtOrigin

func (cm *Camera) LookAtOrigin()

LookAtOrigin points the camera at origin with Y axis pointing Up (i.e., standard)

func (*Camera) LookAtTarget

func (cm *Camera) LookAtTarget()

LookAtTarget points the camera at current target using current up direction

func (*Camera) Orbit

func (cm *Camera) Orbit(delX, delY float32)

Orbit moves the camera along the given 2D axes in degrees (delX = left/right, delY = up/down), relative to current position and orientation, keeping the same distance from the Target, and rotating the camera and the Up direction vector to keep looking at the target.

func (*Camera) Pan

func (cm *Camera) Pan(delX, delY float32)

Pan moves the camera along the given 2D axes (left/right, up/down), relative to current position and orientation (i.e., in the plane of the current window view) and it moves the target by the same increment, changing the target position.

func (*Camera) PanAxis

func (cm *Camera) PanAxis(delX, delY float32)

PanAxis moves the camera and target along world X,Y axes

func (*Camera) PanTarget

func (cm *Camera) PanTarget(delX, delY, delZ float32)

PanTarget moves the target along world X,Y,Z axes and does LookAt at the new target location. It ensures that the target is not identical to the camera position.

func (*Camera) TargetFromView added in v0.0.10

func (cm *Camera) TargetFromView()

TargetFromView updates the target location from the current view matrix, by projecting the current target distance along the current camera view matrix.

func (*Camera) UpdateMatrix

func (cm *Camera) UpdateMatrix()

UpdateMatrix updates the view and projection matricies

func (*Camera) ViewMainAxis

func (cm *Camera) ViewMainAxis() (dim math32.Dims, sign float32)

ViewMainAxis returns the dimension along which the view vector is largest along with the sign of that axis (+1 for positive, -1 for negative). this is useful for determining how manipulations should function, for example.

func (*Camera) ViewVector

func (cm *Camera) ViewVector() math32.Vector3

ViewVector is the vector between the camera position and target

func (*Camera) Zoom

func (cm *Camera) Zoom(zoomPct float32)

Zoom moves along axis given pct closer or further from the target it always moves the target back also if it distance is < 1

func (*Camera) ZoomTo

func (cm *Camera) ZoomTo(pt, size image.Point, zoomPct float32)

ZoomTo moves along axis in vector pointing through the given 2D point as into the camera NDC normalized display coordinates. Point must be 0 normalized, (subtract the Scene ObjBBox.Min) and size of Scene is passed as size argument. ZoomPct is proportion closer (positive) or further (negative) from the target.

type Capsule

type Capsule struct {
	MeshBase

	// height of the cylinder portion
	Height float32

	// radius of the top -- set to 0 for a cone
	TopRad float32

	// radius of the bottom
	BotRad float32

	// number of radial segments (32 is a reasonable default for full circle)
	RadialSegs int `min:"1"`

	// number of height segments
	HeightSegs int

	// number of segments in the hemisphere cap ends (16 is a reasonable default)
	CapSegs int

	// starting angle in degrees, relative to -1,0,0 left side starting point
	AngStart float32 `min:"0" max:"360" step:"5"`

	// total angle to generate in degrees (max 360)
	AngLen float32 `min:"0" max:"360" step:"5"`
}

Capsule is a generalized capsule shape: a cylinder with hemisphere end caps. Supports different radii on each end. Height is along the Y axis -- total height is Height + TopRad + BotRad.

func NewCapsule

func NewCapsule(sc *Scene, name string, height, radius float32, segs, heightSegs int) *Capsule

NewCapsule creates a generalized capsule mesh (cylinder + hemisphere caps) with the specified height and radius, number of radial, sphere segments, and number of height segments Height is along the Y axis.

func (*Capsule) Defaults

func (cp *Capsule) Defaults()

func (*Capsule) MeshSize added in v0.3.2

func (cp *Capsule) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*Capsule) Set

func (cp *Capsule) Set(vertex, normal, texcoord, clrs math32.ArrayF32, index math32.ArrayU32)

func (*Capsule) SetAngLen

func (t *Capsule) SetAngLen(v float32) *Capsule

SetAngLen sets the [Capsule.AngLen]: total angle to generate in degrees (max 360)

func (*Capsule) SetAngStart

func (t *Capsule) SetAngStart(v float32) *Capsule

SetAngStart sets the [Capsule.AngStart]: starting angle in degrees, relative to -1,0,0 left side starting point

func (*Capsule) SetBotRad

func (t *Capsule) SetBotRad(v float32) *Capsule

SetBotRad sets the [Capsule.BotRad]: radius of the bottom

func (*Capsule) SetCapSegs

func (t *Capsule) SetCapSegs(v int) *Capsule

SetCapSegs sets the [Capsule.CapSegs]: number of segments in the hemisphere cap ends (16 is a reasonable default)

func (*Capsule) SetHeight

func (t *Capsule) SetHeight(v float32) *Capsule

SetHeight sets the [Capsule.Height]: height of the cylinder portion

func (*Capsule) SetHeightSegs

func (t *Capsule) SetHeightSegs(v int) *Capsule

SetHeightSegs sets the [Capsule.HeightSegs]: number of height segments

func (*Capsule) SetRadialSegs

func (t *Capsule) SetRadialSegs(v int) *Capsule

SetRadialSegs sets the [Capsule.RadialSegs]: number of radial segments (32 is a reasonable default for full circle)

func (*Capsule) SetTopRad

func (t *Capsule) SetTopRad(v float32) *Capsule

SetTopRad sets the [Capsule.TopRad]: radius of the top -- set to 0 for a cone

type Cylinder

type Cylinder struct {
	MeshBase

	// height of the cylinder
	Height float32

	// radius of the top -- set to 0 for a cone
	TopRad float32

	// radius of the bottom
	BotRad float32

	// number of radial segments (32 is a reasonable default for full circle)
	RadialSegs int `min:"1"`

	// number of height segments
	HeightSegs int

	// render the top disc
	Top bool

	// render the bottom disc
	Bottom bool

	// starting angle in degrees, relative to -1,0,0 left side starting point
	AngStart float32 `min:"0" max:"360" step:"5"`

	// total angle to generate in degrees (max 360)
	AngLen float32 `min:"0" max:"360" step:"5"`
}

Cylinder is a generalized cylinder shape, including a cone or truncated cone by having different size circles at either end. Height is up along the Y axis.

func NewCone

func NewCone(sc *Scene, name string, height, radius float32, radialSegs, heightSegs int, bottom bool) *Cylinder

NewCone creates a cone mesh with the specified base radius, height, number of radial segments, number of height segments, and presence of a bottom cap. Height is along the Y axis.

func NewCylinder

func NewCylinder(sc *Scene, name string, height, radius float32, radialSegs, heightSegs int, top, bottom bool) *Cylinder

NewCylinder creates a cylinder mesh with the specified radius, height, number of radial segments, number of height segments, and presence of a top and/or bottom cap. Height is along the Y axis.

func NewCylinderSector

func NewCylinderSector(sc *Scene, name string, height, topRad, botRad float32, radialSegs, heightSegs int, angStart, angLen float32, top, bottom bool) *Cylinder

NewCylinderSector creates a generalized cylinder (truncated cone) sector mesh with the specified top and bottom radii, height, number of radial segments, number of height segments, sector start angle in degrees, sector size angle in degrees, and presence of a top and/or bottom cap. Height is along the Y axis.

func UnitConeMesh

func UnitConeMesh(sc *Scene, segs int) *Cylinder

UnitConeMesh returns the unit-sized cone mesh, of name ConeMeshName-segs

func (*Cylinder) Defaults

func (cy *Cylinder) Defaults()

func (*Cylinder) MeshSize added in v0.3.2

func (cy *Cylinder) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*Cylinder) Set

func (cy *Cylinder) Set(vertex, normal, texcoord, clrs math32.ArrayF32, index math32.ArrayU32)

func (*Cylinder) SetAngLen

func (t *Cylinder) SetAngLen(v float32) *Cylinder

SetAngLen sets the [Cylinder.AngLen]: total angle to generate in degrees (max 360)

func (*Cylinder) SetAngStart

func (t *Cylinder) SetAngStart(v float32) *Cylinder

SetAngStart sets the [Cylinder.AngStart]: starting angle in degrees, relative to -1,0,0 left side starting point

func (*Cylinder) SetBotRad

func (t *Cylinder) SetBotRad(v float32) *Cylinder

SetBotRad sets the [Cylinder.BotRad]: radius of the bottom

func (*Cylinder) SetBottom

func (t *Cylinder) SetBottom(v bool) *Cylinder

SetBottom sets the [Cylinder.Bottom]: render the bottom disc

func (*Cylinder) SetHeight

func (t *Cylinder) SetHeight(v float32) *Cylinder

SetHeight sets the [Cylinder.Height]: height of the cylinder

func (*Cylinder) SetHeightSegs

func (t *Cylinder) SetHeightSegs(v int) *Cylinder

SetHeightSegs sets the [Cylinder.HeightSegs]: number of height segments

func (*Cylinder) SetRadialSegs

func (t *Cylinder) SetRadialSegs(v int) *Cylinder

SetRadialSegs sets the [Cylinder.RadialSegs]: number of radial segments (32 is a reasonable default for full circle)

func (*Cylinder) SetTop

func (t *Cylinder) SetTop(v bool) *Cylinder

SetTop sets the [Cylinder.Top]: render the top disc

func (*Cylinder) SetTopRad

func (t *Cylinder) SetTopRad(v float32) *Cylinder

SetTopRad sets the [Cylinder.TopRad]: radius of the top -- set to 0 for a cone

type Decoder

type Decoder interface {
	// New returns a new instance of the decoder used for a specific decoding
	New() Decoder

	// Desc returns the description of this decoder
	Desc() string

	// SetFile sets the file name being used for decoding, or error if not found.
	// Returns a list of files that should be loaded along with the main one, if needed.
	// For example, .obj decoder adds a corresponding .mtl file.  In addition,
	// decoded files may specify further files (textures, etc) that must be located
	// relative to the same fsys directory.
	// All file operations use the fsys file system for access, and this should be a
	// Sub FS anchored at the directory where the filename is located.
	SetFileFS(fsys fs.FS, fname string) ([]string, error)

	// Decode reads the given data and decodes it, returning a new instance
	// of the Decoder that contains all the decoded info.
	// Some formats (e.g., Wavefront .obj) have separate .obj and .mtl files
	// which are passed as two reader args.
	Decode(rs []io.Reader) error

	// SetGroup sets the group to contain the decoded objects within the
	// given scene.
	SetGroup(sc *Scene, gp *Group)

	// HasScene returns true if this decoder has full scene information --
	// otherwise it only supports objects to be used in SetGroup.
	HasScene() bool

	// SetScene sets the scene according to the decoded data.
	SetScene(sc *Scene)
}

Decoder parses 3D object / scene file(s) and imports into a Group or Scene. This interface is implemented by the different format-specific decoders.

func DecodeFile

func DecodeFile(fname string) (Decoder, error)

DecodeFile decodes the given file using a decoder based on the file extension. Returns decoder instance with full decoded state. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

func DecodeFileFS

func DecodeFileFS(fsys fs.FS, fname string) (Decoder, error)

DecodeFileFS decodes the given file from the given filesystem using a decoder based on the file extension. Returns decoder instance with full decoded state. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

type Directional added in v0.3.2

type Directional struct {
	LightBase

	// position of direct light, assumed to point at the origin
	// so this determines direction.
	Pos math32.Vector3
}

Directional is directional light, which is assumed to project light toward the origin based on its position, with no attenuation, like the Sun. For rendering, the position is negated and normalized to get the direction vector (i.e., absolute distance doesn't matter)

func NewDirectional added in v0.3.2

func NewDirectional(sc *Scene, name string, lumens float32, color LightColors) *Directional

NewDirectional adds direct light to given scene, with given name, standard color, and lumens (0-1 normalized). By default it is located overhead and toward the default camera (0, 1, 1), change Pos otherwise.

func (*Directional) ViewDir added in v0.3.2

func (dl *Directional) ViewDir(viewMat *math32.Matrix4) math32.Vector3

ViewDir gets the direction normal vector, pre-computing the view transform.

type GenMesh

type GenMesh struct {
	MeshBase
	Vertex   math32.ArrayF32
	Normal   math32.ArrayF32
	TexCoord math32.ArrayF32
	Color    math32.ArrayF32
	Index    math32.ArrayU32
}

GenMesh is a generic, arbitrary Mesh, storing its values

func (*GenMesh) MeshSize added in v0.3.2

func (ms *GenMesh) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*GenMesh) Set

func (ms *GenMesh) Set(vertex, normal, texcoord, clrs math32.ArrayF32, index math32.ArrayU32)

type Group

type Group struct {
	NodeBase
}

Group collects individual elements in a scene but does not have a Mesh or Material of its own. It does have a transform that applies to all nodes under it.

func NewArrow

func NewArrow(sc *Scene, parent tree.Node, name string, st, ed math32.Vector3, width float32, clr color.RGBA, startArrow, endArrow bool, arrowSize, arrowWidth float32, arrowSegs int) *Group

NewArrow adds a group with a new line + cone between two specified points, using shared mesh unit line and arrow heads, which are rotated and positioned to go between the designated points. The arrowSize is a multiplier on the width for the radius and length of the arrow head, with width providing an additional multiplicative factor for width to achieve "fat" vs. "thin" arrows. arrowSegs determines how many faces there are on the arrowhead -- 4 = a 4-sided pyramid, etc.

func NewGroup

func NewGroup(parent ...tree.Node) *Group

NewGroup returns a new Group with the given optional parent: Group collects individual elements in a scene but does not have a Mesh or Material of its own. It does have a transform that applies to all nodes under it.

func NewLineBox

func NewLineBox(sc *Scene, parent tree.Node, meshNm, boxNm string, bbox math32.Box3, width float32, clr color.RGBA, inactive bool) *Group

NewLineBox adds a new Group with Solid's and two Meshes defining the edges of a Box. This can be used for drawing a selection box around a Node in the scene, for example. offset is an arbitrary offset (for composing shapes). Meshes are named meshNm+"-front" and meshNm+"-side" -- need to be initialized, e.g., using sc.InitMesh() inactive indicates whether the box and solids should be flagged as inactive (not selectable).

func (*Group) Defaults

func (gp *Group) Defaults()

func (*Group) RaySolidIntersections

func (gp *Group) RaySolidIntersections(ray math32.Ray) []*SolidPoint

RaySolidIntersections returns a list of solids whose bounding box intersects with the given ray, with the point of intersection. Results are sorted from closest to furthest.

func (*Group) RenderClass

func (gp *Group) RenderClass() RenderClasses

func (*Group) SetAxisRotation

func (gp *Group) SetAxisRotation(x, y, z, angle float32) *Group

SetAxisRotation sets the [Pose.Quat] rotation of the solid, from local axis and angle in degrees.

func (*Group) SetEulerRotation

func (gp *Group) SetEulerRotation(x, y, z float32) *Group

SetEulerRotation sets the [Pose.Quat] rotation of the solid, from euler angles in degrees

func (*Group) SetPos

func (gp *Group) SetPos(x, y, z float32) *Group

SetPos sets the [Pose.Pos] position of the solid

func (*Group) SetScale

func (gp *Group) SetScale(x, y, z float32) *Group

SetScale sets the [Pose.Scale] scale of the solid

func (*Group) UpdateMeshBBox

func (gp *Group) UpdateMeshBBox()

UpdateMeshBBox updates the Mesh-based BBox info for all nodes. groups aggregate over elements

type Light

type Light interface {

	// AsLightBase returns the [LightBase] for this Light,
	// which provides the core functionality of a light.
	AsLightBase() *LightBase
}

Light represents a light that illuminates a scene. These are stored on the Scene object and not within the tree.

type LightBase

type LightBase struct {

	// Name is the name of the light, which matters since lights are accessed by name.
	Name string

	// On is whether the light is turned on. TODO: support this being false.
	On bool

	// Lumens is the brightness/intensity/strength of the light
	// in normalized 0-1 units.
	// It is just multiplied by the color, and is convenient
	// for easily modulating overall brightness.
	Lumens float32 `min:"0" step:"0.1"`

	// Color is the color of the light at full intensity.
	Color color.RGBA
}

LightBase provides the core implementation of the Light interface.

func (*LightBase) AsLightBase added in v0.2.0

func (lb *LightBase) AsLightBase() *LightBase

func (*LightBase) SetColor added in v0.2.0

func (t *LightBase) SetColor(v color.RGBA) *LightBase

SetColor sets the [LightBase.Color]: Color is the color of the light at full intensity.

func (*LightBase) SetLumens added in v0.2.0

func (t *LightBase) SetLumens(v float32) *LightBase

SetLumens sets the [LightBase.Lumens]: Lumens is the brightness/intensity/strength of the light in normalized 0-1 units. It is just multiplied by the color, and is convenient for easily modulating overall brightness.

func (*LightBase) SetName added in v0.2.0

func (t *LightBase) SetName(v string) *LightBase

SetName sets the [LightBase.Name]: Name is the name of the light, which matters since lights are accessed by name.

func (*LightBase) SetOn added in v0.2.0

func (t *LightBase) SetOn(v bool) *LightBase

SetOn sets the [LightBase.On]: On is whether the light is turned on. TODO: support this being false.

type LightColors

type LightColors int32 //enums:enum

LightColors are standard light colors for different light sources

const (
	DirectSun LightColors = iota
	CarbonArc
	Halogen
	Tungsten100W
	Tungsten40W
	Candle
	Overcast
	FluorWarm
	FluorStd
	FluorCool
	FluorFull
	FluorGrow
	MercuryVapor
	SodiumVapor
	MetalHalide
)
const LightColorsN LightColors = 15

LightColorsN is the highest valid value for type LightColors, plus one.

func LightColorsValues

func LightColorsValues() []LightColors

LightColorsValues returns all possible values for the type LightColors.

func (LightColors) Desc

func (i LightColors) Desc() string

Desc returns the description of the LightColors value.

func (LightColors) Int64

func (i LightColors) Int64() int64

Int64 returns the LightColors value as an int64.

func (LightColors) MarshalText

func (i LightColors) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*LightColors) SetInt64

func (i *LightColors) SetInt64(in int64)

SetInt64 sets the LightColors value from an int64.

func (*LightColors) SetString

func (i *LightColors) SetString(s string) error

SetString sets the LightColors value from its string representation, and returns an error if the string is invalid.

func (LightColors) String

func (i LightColors) String() string

String returns the string representation of this LightColors value.

func (*LightColors) UnmarshalText

func (i *LightColors) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (LightColors) Values

func (i LightColors) Values() []enums.Enum

Values returns all possible values for the type LightColors.

type Lines

type Lines struct {
	MeshBase

	// line points (must be 2 or more)
	Points []math32.Vector3

	// line width, Y = height perpendicular to line direction, and X = depth
	Width math32.Vector2

	// optional colors for each point -- actual color interpolates between
	Colors []color.RGBA

	// if true, connect the first and last points to form a closed shape
	Closed bool
}

Lines are lines rendered as long thin boxes defined by points and width parameters. The Mesh must be drawn in the XY plane (i.e., use Z = 0 or a constant unless specifically relevant to have full 3D variation). Rotate the solid to put into other planes.

func NewLineBoxMeshes

func NewLineBoxMeshes(sc *Scene, meshNm string, bbox math32.Box3, width float32) (front, side *Lines)

NewLineBoxMeshes adds two Meshes defining the edges of a Box. Meshes are named meshNm+"-front" and meshNm+"-side" -- need to be initialized, e.g., using sc.InitMesh()

func NewLines

func NewLines(sc *Scene, name string, points []math32.Vector3, width math32.Vector2, closed bool) *Lines

NewLines adds Lines mesh to given scene, with given start, end, and width

func UnitLineMesh

func UnitLineMesh(sc *Scene) *Lines

UnitLineMesh returns the unit-sized line mesh, of name LineMeshName

func (*Lines) MeshSize added in v0.3.2

func (ln *Lines) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*Lines) Set

func (ln *Lines) Set(vertex, normal, texcoord, clrs math32.ArrayF32, indexArray math32.ArrayU32)

type Material

type Material struct {

	// Color is the main color of surface, used for both ambient and diffuse color in standard Phong model -- alpha component determines transparency -- note that transparent objects require more complex rendering
	Color color.RGBA

	// Emissive is the color that surface emits independent of any lighting -- i.e., glow -- can be used for marking lights with an object
	Emissive color.RGBA

	// Shiny is the specular shininess factor -- how focally vs. broad the surface shines back directional light -- this is an exponential factor, with 0 = very broad diffuse reflection, and higher values (typically max of 128 or so but can go higher) having a smaller more focal specular reflection.  Also set Reflective factor to change overall shininess effect.
	Shiny float32

	// Reflective is the specular reflectiveness factor -- how much it shines back directional light.  The specular reflection color is always white * the incoming light.
	Reflective float32

	// Bright is an overall multiplier on final computed color value -- can be used to tune the overall brightness of various surfaces relative to each other for a given set of lighting parameters
	Bright float32

	// TextureName is the name of the texture to provide color for the surface.
	TextureName TextureName `set:"-"`

	// Tiling is the texture tiling parameters: repeat and offset.
	Tiling phong.Tiling `display:"inline"`

	// CullBack indicates to cull the back-facing surfaces.
	CullBack bool

	// CullFront indicates to cull the front-facing surfaces.
	CullFront bool

	// Texture is the cached [Texture] object set based on [Material.TextureName].
	Texture Texture `set:"-" display:"-"`
}

Material describes the material properties of a surface (colors, shininess, texture) i.e., phong lighting parameters. Main color is used for both ambient and diffuse color, and alpha component is used for opacity. The Emissive color is only for glowing objects. The Specular color is always white (multiplied by light color). Textures are stored on the Scene and accessed by name

func (*Material) Defaults

func (mt *Material) Defaults()

Defaults sets default surface parameters

func (*Material) Disconnect

func (mt *Material) Disconnect()

Disconnect resets pointers etc

func (*Material) IsTransparent

func (mt *Material) IsTransparent() bool

IsTransparent returns true if texture says it is, or if color has alpha < 255

func (*Material) NoTexture

func (mt *Material) NoTexture()

NoTexture resets any texture setting that might have been set

func (*Material) SetBright

func (t *Material) SetBright(v float32) *Material

SetBright sets the [Material.Bright]: Bright is an overall multiplier on final computed color value -- can be used to tune the overall brightness of various surfaces relative to each other for a given set of lighting parameters

func (*Material) SetColor

func (t *Material) SetColor(v color.RGBA) *Material

SetColor sets the [Material.Color]: Color is the main color of surface, used for both ambient and diffuse color in standard Phong model -- alpha component determines transparency -- note that transparent objects require more complex rendering

func (*Material) SetCullBack

func (t *Material) SetCullBack(v bool) *Material

SetCullBack sets the [Material.CullBack]: CullBack indicates to cull the back-facing surfaces.

func (*Material) SetCullFront

func (t *Material) SetCullFront(v bool) *Material

SetCullFront sets the [Material.CullFront]: CullFront indicates to cull the front-facing surfaces.

func (*Material) SetEmissive

func (t *Material) SetEmissive(v color.RGBA) *Material

SetEmissive sets the [Material.Emissive]: Emissive is the color that surface emits independent of any lighting -- i.e., glow -- can be used for marking lights with an object

func (*Material) SetReflective

func (t *Material) SetReflective(v float32) *Material

SetReflective sets the [Material.Reflective]: Reflective is the specular reflectiveness factor -- how much it shines back directional light. The specular reflection color is always white * the incoming light.

func (*Material) SetShiny

func (t *Material) SetShiny(v float32) *Material

SetShiny sets the [Material.Shiny]: Shiny is the specular shininess factor -- how focally vs. broad the surface shines back directional light -- this is an exponential factor, with 0 = very broad diffuse reflection, and higher values (typically max of 128 or so but can go higher) having a smaller more focal specular reflection. Also set Reflective factor to change overall shininess effect.

func (*Material) SetTexture

func (mt *Material) SetTexture(tex Texture) *Material

SetTexture sets material to use given texture

func (*Material) SetTextureName

func (mt *Material) SetTextureName(sc *Scene, texName string) error

SetTextureName sets material to use given texture name (textures are accessed by name on Scene). If name is empty, then texture is reset

func (*Material) SetTiling

func (t *Material) SetTiling(v phong.Tiling) *Material

SetTiling sets the [Material.Tiling]: Tiling is the texture tiling parameters: repeat and offset.

func (*Material) ShowShow added in v0.0.5

func (mt *Material) ShowShow(field string) bool

func (Material) String

func (mt Material) String() string

func (*Material) Validate

func (mt *Material) Validate(sc *Scene) error

Validate does overall material validation, including checking that material texture is valid if set

type Mesh

type Mesh interface {
	shape.Mesh

	// AsMeshBase returns the [MeshBase] for this Mesh,
	// which provides the core functionality of a mesh.
	AsMeshBase() *MeshBase
}

Mesh parametrizes the mesh-based shape used for rendering a Solid, using the shape.Mesh interface for basic shape data. Only indexed triangle meshes are supported. All Meshes must know in advance the number of vertex and index points they require, and the Set method writes the mesh data to arrays of appropriate vector data. Per-vertex Color is optional.

type MeshBase

type MeshBase struct {
	// Name is the name of the mesh. [Mesh]es are linked to [Solid]s
	// by name so this matters.
	Name string

	// NumVertex is the number of [math32.Vector3] vertex points. This always
	// includes [math32.Vector3] normals and [math32.Vector2] texture coordinates.
	// This is only valid after [Mesh.Sizes] has been called.
	NumVertex int `set:"-"`

	// NumIndex is the number of [math32.ArrayU32] indexes.
	// This is only valid after [Mesh.Sizes] has been called.
	NumIndex int `set:"-"`

	// HasColor is whether the mesh has per-vertex colors
	// as [math32.Vector4] per vertex.
	HasColor bool

	// Transparent is whether the color has transparency;
	// not worth checking manually. This is only valid if
	// [MeshBase.HasColor] is true.
	Transparent bool

	// BBox has the computed bounding-box and other gross solid properties.
	BBox BBox `set:"-"`
}

MeshBase provides the core implementation of the Mesh interface.

func (*MeshBase) AsMeshBase

func (ms *MeshBase) AsMeshBase() *MeshBase

func (*MeshBase) ComputeNorms

func (ms *MeshBase) ComputeNorms(pos, norm math32.ArrayF32)

todo!!

func (*MeshBase) MeshBBox added in v0.3.2

func (ms *MeshBase) MeshBBox() math32.Box3

func (*MeshBase) MeshSize added in v0.3.2

func (ms *MeshBase) MeshSize() (numVertex, numIndex int, hasColor bool)

func (*MeshBase) Offsets added in v0.3.2

func (ms *MeshBase) Offsets() (vtxOffset, idxOffset int)

func (*MeshBase) SetHasColor added in v0.2.0

func (t *MeshBase) SetHasColor(v bool) *MeshBase

SetHasColor sets the [MeshBase.HasColor]: HasColor is whether the mesh has per-vertex colors as math32.Vector4 per vertex.

func (*MeshBase) SetName

func (t *MeshBase) SetName(v string) *MeshBase

SetName sets the [MeshBase.Name]: Name is the name of the mesh. [Mesh]es are linked to [Solid]s by name so this matters.

func (*MeshBase) SetOffsets added in v0.3.2

func (ms *MeshBase) SetOffsets(vtxOffset, idxOffset int)

func (*MeshBase) SetTransparent added in v0.2.0

func (t *MeshBase) SetTransparent(v bool) *MeshBase

SetTransparent sets the [MeshBase.Transparent]: Transparent is whether the color has transparency; not worth checking manually. This is only valid if [MeshBase.HasColor] is true.

type MeshName

type MeshName string

MeshName is a Mesh name. This type provides an automatic GUI chooser for meshes. It is used on Solid to link to meshes by name.

type Node

type Node interface {
	tree.Node

	// AsNodeBase returns the [NodeBase] for our node, which gives
	// access to all the base-level data structures and methods
	// without requiring interface methods.
	AsNodeBase() *NodeBase

	// IsSolid returns true if this is an [Solid] node (otherwise a [Group]).
	IsSolid() bool

	// AsSolid returns the node as a [Solid] (nil if not).
	AsSolid() *Solid

	// Validate checks that scene element is valid.
	Validate() error

	// UpdateWorldMatrix updates this node's local and world matrix based on parent's world matrix.
	UpdateWorldMatrix(parWorld *math32.Matrix4)

	// UpdateMeshBBox updates the Mesh-based BBox info for all nodes.
	// groups aggregate over elements. It is called from WalkPost traversal.
	UpdateMeshBBox()

	// IsVisible provides the definitive answer as to whether a given node
	// is currently visible.  It is only entirely valid after a render pass
	// for widgets in a visible window, but it checks the window and viewport
	// for their visibility status as well, which is available always.
	// Non-visible nodes are automatically not rendered and not connected to
	// window events.  The Invisible flag is one key element of the IsVisible
	// calculus; it is set by e.g., TabView for invisible tabs, and is also
	// set if a widget is entirely out of render range.  But again, use
	// IsVisible as the main end-user method.
	// For robustness, it recursively calls the parent; this is typically
	// a short path; propagating the Invisible flag properly can be
	// very challenging without mistakenly overwriting invisibility at various
	// levels.
	IsVisible() bool

	// IsTransparent returns true if solid has transparent color.
	IsTransparent() bool

	// Config configures the node.
	Config()

	// RenderClass returns the class of rendering for this solid.
	// It is used for organizing the ordering of rendering.
	RenderClass() RenderClasses

	// PreRender is called by Scene Render to upload
	// all the object data to the Phong renderer.
	PreRender()

	// Render is called by Scene Render to actually render.
	Render(rp *wgpu.RenderPassEncoder)
}

Node is the common interface for all xyz 3D tree nodes. Solid and Group are the two main types of nodes, which both extend NodeBase for the core functionality.

func NodesUnderPoint

func NodesUnderPoint(n tree.Node, pt image.Point) []Node

NodesUnderPoint returns list of nodes within given node that have their ScBBox within given 2D scene point (excludes starting node). This is a good first-pass step for node-level event handling based on 2D mouse events.

type NodeBase

type NodeBase struct {
	tree.NodeBase

	// Invisible is whether this node is invisible.
	Invisible bool

	// Pose is the complete specification of position and orientation.
	Pose Pose `set:"-"`

	// Scene is the cached [Scene].
	Scene *Scene `copier:"-" set:"-"`

	// mesh-based local bounding box (aggregated for groups)
	MeshBBox BBox `edit:"-" copier:"-" json:"-" xml:"-" set:"-"`

	// world coordinates bounding box
	WorldBBox BBox `edit:"-" copier:"-" json:"-" xml:"-" set:"-"`

	// normalized display coordinates bounding box, used for frustrum clipping
	NDCBBox math32.Box3 `edit:"-" copier:"-" json:"-" xml:"-" set:"-"`

	// raw original bounding box for the widget within its parent Scene.
	// This is prior to intersecting with Frame bounds.
	BBox image.Rectangle `edit:"-" copier:"-" json:"-" xml:"-" set:"-"`

	// 2D bounding box for region occupied within Scene Frame that we render onto.
	// This is BBox intersected with Frame bounds.
	SceneBBox image.Rectangle `edit:"-" copier:"-" json:"-" xml:"-" set:"-"`
	// contains filtered or unexported fields
}

NodeBase is the basic 3D tree node, which has the full transform information relative to parent, and computed bounding boxes, etc. It implements the Node interface and contains the core functionality common to all 3D nodes.

func NewNodeBase

func NewNodeBase(parent ...tree.Node) *NodeBase

NewNodeBase returns a new NodeBase with the given optional parent: NodeBase is the basic 3D tree node, which has the full transform information relative to parent, and computed bounding boxes, etc. It implements the Node interface and contains the core functionality common to all 3D nodes.

func (*NodeBase) AsNodeBase added in v0.2.0

func (nb *NodeBase) AsNodeBase() *NodeBase

AsNodeBase returns a generic NodeBase for our node, giving generic access to all the base-level data structures without requiring interface methods.

func (*NodeBase) AsSolid

func (nb *NodeBase) AsSolid() *Solid

func (*NodeBase) BaseInterface added in v0.1.4

func (nb *NodeBase) BaseInterface() reflect.Type

func (*NodeBase) Config

func (nb *NodeBase) Config()

func (*NodeBase) IsSolid

func (nb *NodeBase) IsSolid() bool

func (*NodeBase) IsTransparent

func (nb *NodeBase) IsTransparent() bool

func (*NodeBase) IsVisible

func (nb *NodeBase) IsVisible() bool

func (*NodeBase) NormDCBBox

func (nb *NodeBase) NormDCBBox() math32.Box3

NormDCBBox returns the normalized display coordinates bounding box which is used for clipping.

func (*NodeBase) OnAdd

func (nb *NodeBase) OnAdd()

OnAdd is called when nodes are added to a parent. It sets the scene of the node to that of its parent. It should be called by all other OnAdd functions defined by node types.

func (*NodeBase) PreRender added in v0.3.2

func (nb *NodeBase) PreRender()

func (*NodeBase) RayPick

func (nb *NodeBase) RayPick(pos image.Point) math32.Ray

RayPick converts a given 2D point in scene image coordinates into a ray from the camera position pointing through line of sight of camera into *local* coordinates of the solid. This can be used to find point of intersection in local coordinates relative to a given plane of interest, for example (see Ray methods for intersections). To convert mouse window-relative coords into scene-relative coords subtract the sc.ObjBBox.Min which includes any scrolling effects

func (*NodeBase) Render

func (nb *NodeBase) Render(rp *wgpu.RenderPassEncoder)

func (*NodeBase) SetInvisible added in v0.2.0

func (t *NodeBase) SetInvisible(v bool) *NodeBase

SetInvisible sets the [NodeBase.Invisible]: Invisible is whether this node is invisible.

func (*NodeBase) SetPosePos

func (nb *NodeBase) SetPosePos(pos math32.Vector3)

SetPosePos sets Pose.Pos position to given value

func (*NodeBase) SetPoseQuat

func (nb *NodeBase) SetPoseQuat(quat math32.Quat)

SetPoseQuat sets Pose.Quat to given value

func (*NodeBase) SetPoseScale

func (nb *NodeBase) SetPoseScale(scale math32.Vector3)

SetPoseScale sets Pose.Scale scale to given value

func (*NodeBase) TrackCamera

func (nb *NodeBase) TrackCamera()

TrackCamera moves this node to pose of camera

func (*NodeBase) TrackLight

func (nb *NodeBase) TrackLight(lightName string) error

TrackLight moves node to position of light of given name. For Spot, copies entire Pose. Does not work for Ambient light which has no position information.

func (*NodeBase) UpdateBBox2D

func (nb *NodeBase) UpdateBBox2D(size math32.Vector2)

UpdateBBox2D updates this node's 2D bounding-box information based on scene size and min offset position.

func (*NodeBase) UpdateMVPMatrix

func (nb *NodeBase) UpdateMVPMatrix(viewMat, projectionMat *math32.Matrix4)

UpdateMVPMatrix updates this node's MVP matrix based on given view, projection matricies from camera. Called during rendering.

func (*NodeBase) UpdateWorldMatrix

func (nb *NodeBase) UpdateWorldMatrix(parWorld *math32.Matrix4)

UpdateWorldMatrix updates this node's world matrix based on parent's world matrix. If a nil matrix is passed, then the previously set parent world matrix is used.

func (*NodeBase) Validate

func (nb *NodeBase) Validate() error

func (*NodeBase) WorldMatrix

func (nb *NodeBase) WorldMatrix() *math32.Matrix4

WorldMatrix returns the world matrix for this node

type Plane

type Plane struct {
	MeshBase

	// axis along which the normal perpendicular to the plane points.  E.g., if the Y axis is specified, then it is a standard X-Z ground plane -- see also NormalNeg for whether it is facing in the positive or negative of the given axis.
	NormAxis math32.Dims

	// if false, the plane normal facing in the positive direction along specified NormAxis, otherwise it faces in the negative if true
	NormalNeg bool

	// 2D size of plane
	Size math32.Vector2

	// number of segments to divide plane into (enforced to be at least 1) -- may potentially increase rendering quality to have > 1
	Segs math32.Vector2i

	// offset from origin along direction of normal to the plane
	Offset float32
}

Plane is a flat 2D plane, which can be oriented along any axis facing either positive or negative

func NewPlane

func NewPlane(sc *Scene, name string, width, height float32) *Plane

NewPlane adds Plane mesh to given scene, with given name and size, with its normal pointing by default in the positive Y axis (i.e., a "ground" plane). Offset is 0.

func (*Plane) MeshSize added in v0.3.2

func (pl *Plane) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*Plane) Set

func (pl *Plane) Set(vertex, normal, texcoord, clrs math32.ArrayF32, index math32.ArrayU32)

func (*Plane) SetNormAxis

func (t *Plane) SetNormAxis(v math32.Dims) *Plane

SetNormAxis sets the [Plane.NormAxis]: axis along which the normal perpendicular to the plane points. E.g., if the Y axis is specified, then it is a standard X-Z ground plane -- see also NormalNeg for whether it is facing in the positive or negative of the given axis.

func (*Plane) SetNormalNeg added in v0.3.2

func (t *Plane) SetNormalNeg(v bool) *Plane

SetNormalNeg sets the [Plane.NormalNeg]: if false, the plane normal facing in the positive direction along specified NormAxis, otherwise it faces in the negative if true

func (*Plane) SetOffset

func (t *Plane) SetOffset(v float32) *Plane

SetOffset sets the [Plane.Offset]: offset from origin along direction of normal to the plane

func (*Plane) SetSegs

func (t *Plane) SetSegs(v math32.Vector2i) *Plane

SetSegs sets the [Plane.Segs]: number of segments to divide plane into (enforced to be at least 1) -- may potentially increase rendering quality to have > 1

func (*Plane) SetSize

func (t *Plane) SetSize(v math32.Vector2) *Plane

SetSize sets the [Plane.Size]: 2D size of plane

type Point added in v0.3.2

type Point struct {
	LightBase

	// position of light in world coordinates.
	Pos math32.Vector3

	// Distance linear decay factor, defaults to .1
	LinDecay float32

	// Distance quadratic decay factor, defaults to .01. Dominates at longer distances.
	QuadDecay float32
}

Point is an omnidirectional light with a position and associated decay factors, which divide the light intensity as a function of linear and quadratic distance. The quadratic factor dominates at longer distances.

func NewPoint added in v0.3.2

func NewPoint(sc *Scene, name string, lumens float32, color LightColors) *Point

NewPoint adds point light to given scene, with given name, standard color, and lumens (0-1 normalized). By default it is located at 0,5,5 (up and between default camera and origin) -- set Pos to change.

func (*Point) ViewPos added in v0.3.2

func (pl *Point) ViewPos(viewMat *math32.Matrix4) math32.Vector3

ViewPos gets the position vector, pre-computing the view transform

type Pose

type Pose struct {

	// position of center of element (relative to parent)
	Pos math32.Vector3

	// scale (relative to parent)
	Scale math32.Vector3

	// Node rotation specified as a Quat (relative to parent)
	Quat math32.Quat `display:"inline"`

	// Local matrix. Contains all position/rotation/scale information (relative to parent)
	Matrix math32.Matrix4 `display:"-"`

	// Parent's world matrix -- we cache this so that we can independently update our own matrix
	ParMatrix math32.Matrix4 `display:"-"`

	// World matrix. Contains all absolute position/rotation/scale information (i.e. relative to very top parent, generally the scene)
	WorldMatrix math32.Matrix4 `display:"-"`

	// model * view matrix -- tranforms into camera-centered coords
	MVMatrix math32.Matrix4 `display:"-"`

	// model * view * projection matrix -- full final render matrix
	MVPMatrix math32.Matrix4 `display:"-"`

	// normal matrix has no offsets, for normal vector rotation only, based on MVMatrix
	NormMatrix math32.Matrix3 `display:"-"`
}

Pose contains the full specification of position and orientation, always relevant to the parent element.

func (*Pose) CopyFrom

func (ps *Pose) CopyFrom(op *Pose)

CopyFrom copies just the pose information from the other pose, critically not copying the ParMatrix so that is preserved in the receiver.

func (*Pose) Defaults

func (ps *Pose) Defaults()

Defaults sets defaults only if current values are nil

func (*Pose) EulerRotation

func (ps *Pose) EulerRotation() math32.Vector3

EulerRotation returns the current rotation in Euler angles (degrees).

func (*Pose) EulerRotationRad

func (ps *Pose) EulerRotationRad() math32.Vector3

EulerRotationRad returns the current rotation in Euler angles (radians).

func (*Pose) GenGoSet

func (ps *Pose) GenGoSet(path string) string

GenGoSet returns code to set values at given path (var.member etc)

func (*Pose) LookAt

func (ps *Pose) LookAt(target, upDir math32.Vector3)

LookAt points the element at given target location using given up direction.

func (*Pose) MoveOnAxis

func (ps *Pose) MoveOnAxis(x, y, z, dist float32)

MoveOnAxis moves (translates) the specified distance on the specified local axis, relative to the current rotation orientation.

func (*Pose) MoveOnAxisAbs

func (ps *Pose) MoveOnAxisAbs(x, y, z, dist float32)

MoveOnAxisAbs moves (translates) the specified distance on the specified local axis, in absolute X,Y,Z coordinates.

func (*Pose) MulMatrix

func (ps *Pose) MulMatrix(mat *math32.Matrix4)

MulMatrix multiplies current pose Matrix by given Matrix, and re-extracts the Pos, Scale, Quat from resulting matrix.

func (*Pose) RotateEuler

func (ps *Pose) RotateEuler(x, y, z float32)

RotateEuler rotates by given Euler angles (in degrees) relative to existing rotation.

func (*Pose) RotateEulerRad

func (ps *Pose) RotateEulerRad(x, y, z, angle float32)

RotateEulerRad rotates by given Euler angles (in radians) relative to existing rotation.

func (*Pose) RotateOnAxis

func (ps *Pose) RotateOnAxis(x, y, z, angle float32)

RotateOnAxis rotates around the specified local axis the specified angle in degrees.

func (*Pose) RotateOnAxisRad

func (ps *Pose) RotateOnAxisRad(x, y, z, angle float32)

RotateOnAxisRad rotates around the specified local axis the specified angle in radians.

func (*Pose) SetAxisRotation

func (ps *Pose) SetAxisRotation(x, y, z, angle float32)

SetAxisRotation sets rotation from local axis and angle in degrees.

func (*Pose) SetAxisRotationRad

func (ps *Pose) SetAxisRotationRad(x, y, z, angle float32)

SetAxisRotationRad sets rotation from local axis and angle in radians.

func (*Pose) SetEulerRotation

func (ps *Pose) SetEulerRotation(x, y, z float32)

SetEulerRotation sets the rotation in Euler angles (degrees).

func (*Pose) SetEulerRotationRad

func (ps *Pose) SetEulerRotationRad(x, y, z float32)

SetEulerRotationRad sets the rotation in Euler angles (radians).

func (*Pose) SetIdentity added in v0.3.3

func (ps *Pose) SetIdentity()

SetIdentity sets the Pose to the identity transform.

func (*Pose) SetMatrix

func (ps *Pose) SetMatrix(m *math32.Matrix4)

SetMatrix sets the local transformation matrix and updates Pos, Scale, Quat.

func (*Pose) String

func (ps *Pose) String() string

func (*Pose) UpdateMVPMatrix

func (ps *Pose) UpdateMVPMatrix(viewMat, projectionMat *math32.Matrix4)

UpdateMVPMatrix updates the model * view, * projection matricies based on camera view, projection matricies Assumes that WorldMatrix has been updated

func (*Pose) UpdateMatrix

func (ps *Pose) UpdateMatrix()

UpdateMatrix updates the local transform matrix based on its position, quaternion, and scale. Also checks for degenerate nil values

func (*Pose) UpdateWorldMatrix

func (ps *Pose) UpdateWorldMatrix(parWorld *math32.Matrix4)

UpdateWorldMatrix updates the world transform matrix based on Matrix and parent's WorldMatrix. Does NOT call UpdateMatrix so that can include other factors as needed.

func (*Pose) WorldEulerRotation

func (ps *Pose) WorldEulerRotation() math32.Vector3

WorldEulerRotation returns the current world rotation in Euler angles.

func (*Pose) WorldPos

func (ps *Pose) WorldPos() math32.Vector3

WorldPos returns the current world position.

func (*Pose) WorldQuat

func (ps *Pose) WorldQuat() math32.Quat

WorldQuat returns the current world quaternion.

func (*Pose) WorldScale

func (ps *Pose) WorldScale() math32.Vector3

WorldScale returns he current world scale.

type RenderClasses

type RenderClasses int32 //enums:enum -trim-prefix RClass

RenderClasses define the different classes of rendering

const (
	RClassNone          RenderClasses = iota
	RClassOpaqueTexture               // textures tend to be in background
	RClassOpaqueUniform
	RClassOpaqueVertex
	RClassTransTexture
	RClassTransUniform
	RClassTransVertex
)
const RenderClassesN RenderClasses = 7

RenderClassesN is the highest valid value for type RenderClasses, plus one.

func RenderClassesValues

func RenderClassesValues() []RenderClasses

RenderClassesValues returns all possible values for the type RenderClasses.

func (RenderClasses) Desc

func (i RenderClasses) Desc() string

Desc returns the description of the RenderClasses value.

func (RenderClasses) Int64

func (i RenderClasses) Int64() int64

Int64 returns the RenderClasses value as an int64.

func (RenderClasses) MarshalText

func (i RenderClasses) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*RenderClasses) SetInt64

func (i *RenderClasses) SetInt64(in int64)

SetInt64 sets the RenderClasses value from an int64.

func (*RenderClasses) SetString

func (i *RenderClasses) SetString(s string) error

SetString sets the RenderClasses value from its string representation, and returns an error if the string is invalid.

func (RenderClasses) String

func (i RenderClasses) String() string

String returns the string representation of this RenderClasses value.

func (*RenderClasses) UnmarshalText

func (i *RenderClasses) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (RenderClasses) Values

func (i RenderClasses) Values() []enums.Enum

Values returns all possible values for the type RenderClasses.

type Scene

type Scene struct {
	tree.NodeBase

	// Background is the background of the scene,
	// which is used directly as a solid color in Vulkan.
	Background image.Image

	// NeedsUpdate means that Node Pose has changed and an update pass
	// is required to update matrix and bounding boxes.
	NeedsUpdate bool `set:"-"`

	// NeedsRender means that something has been updated (minimally the
	// Camera pose) and a new Render is required.
	NeedsRender bool `set:"-"`

	// Viewport-level viewbox within any parent Viewport2D
	Geom math32.Geom2DInt `set:"-"`

	// number of samples in multisampling. Default of 4 produces smooth
	// rendering.
	MultiSample int `default:"4"`

	// render using wireframe instead of filled polygons.
	// This must be set prior to configuring the Phong rendering
	// system (i.e., just after Scene is made).
	// note: not currently working in WebGPU.
	Wireframe bool `default:"false"`

	// camera determines view onto scene
	Camera Camera `set:"-"`

	// all lights used in the scene
	Lights ordmap.Map[string, Light] `set:"-"`

	// meshes
	Meshes ordmap.Map[string, Mesh] `set:"-"`

	// textures
	Textures ordmap.Map[string, Texture] `set:"-"`

	// library of objects that can be used in the scene
	Library map[string]*Group `set:"-"`

	// don't activate the standard navigation keyboard and mouse
	// event processing to move around the camera in the scene.
	NoNav bool

	// saved cameras, can Save and Set these to view the scene
	// from different angles
	SavedCams map[string]Camera `set:"-"`

	// the phong rendering system
	Phong *phong.Phong `set:"-"`

	// the gpu render frame holding the rendered scene
	Frame *gpu.RenderTexture `set:"-"`
	// contains filtered or unexported fields
}

Scene is the overall scenegraph containing nodes as children. It renders to its own gpu.RenderTexture. The Image of this Frame is usable directly or, via xyzcore.Scene, where it is copied into an overall core.Scene image.

There is default navigation event processing (disabled by setting NoNav) where mouse drag events Orbit the camera (Shift = Pan, Alt = PanTarget) and arrow keys do Orbit, Pan, PanTarget with same key modifiers. Spacebar restores original "default" camera, and numbers save (1st time) or restore (subsequently) camera views (Control = always save)

A Group at the top-level named "TrackCamera" will automatically track the camera (i.e., its Pose is copied) -- Solids in that group can set their relative Pos etc to display relative to the camera, to achieve "first person" effects.

func NewOffscreenScene added in v0.1.3

func NewOffscreenScene() *Scene

NewOffscreenScene returns a new Scene designed for offscreen rendering of 3D content. This can be used in unit tests and other cases not involving xyzcore. It makes a new gpu.NoDisplayGPU.

func NewScene

func NewScene(parent ...tree.Node) *Scene

NewScene returns a new Scene with the given optional parent: Scene is the overall scenegraph containing nodes as children. It renders to its own gpu.RenderTexture. The Image of this Frame is usable directly or, via xyzcore.Scene, where it is copied into an overall core.Scene image.

There is default navigation event processing (disabled by setting NoNav) where mouse drag events Orbit the camera (Shift = Pan, Alt = PanTarget) and arrow keys do Orbit, Pan, PanTarget with same key modifiers. Spacebar restores original "default" camera, and numbers save (1st time) or restore (subsequently) camera views (Control = always save)

A Group at the top-level named "TrackCamera" will automatically track the camera (i.e., its Pose is copied) -- Solids in that group can set their relative Pos etc to display relative to the camera, to achieve "first person" effects.

func (*Scene) AddFromLibrary added in v0.0.10

func (sc *Scene) AddFromLibrary(nm string, parent tree.Node) (*Group, error)

AddFromLibrary adds a Clone of named item in the Library under given parent in the scenegraph. Returns an error if item not found.

func (*Scene) AddLight

func (sc *Scene) AddLight(lt Light)

AddLight adds given light to lights see NewX for convenience methods to add specific lights

func (*Scene) AddMeshUnique

func (sc *Scene) AddMeshUnique(ms Mesh)

AddMeshUniqe adds given mesh, ensuring that it has a unique name if one already exists. This is used e.g., in loading external files which may not obey this constraint.

func (*Scene) AddToLibrary

func (sc *Scene) AddToLibrary(gp *Group)

AddToLibrary adds given Group to library, using group's name as unique key in Library map.

func (*Scene) AssertImage added in v0.1.3

func (sc *Scene) AssertImage(t imagex.TestingT, filename string)

AssertImage asserts the Scene.Image at the given filename using imagex.Assert. It first configures, updates, and renders the scene.

func (*Scene) ConfigFrame

func (sc *Scene) ConfigFrame(gp *gpu.GPU, dev *gpu.Device)

ConfigFrame configures framebuffer for GPU rendering, using given gpu and device, and size set in Geom.Size. Must be called on the main thread. If Frame already exists, it ensures that the Size is correct.

func (*Scene) ConfigFrameFromSurface

func (sc *Scene) ConfigFrameFromSurface(surf *gpu.Surface)

ConfigFrameFromSurface configures framebuffer for GPU rendering Using GPU and Device from given gpuSurface

func (*Scene) ConfigNodes

func (sc *Scene) ConfigNodes()

ConfigNodes runs Config on all nodes

func (*Scene) DeleteUnusedMeshes

func (sc *Scene) DeleteUnusedMeshes()

DeleteUnusedMeshes deletes all unused meshes

func (*Scene) DepthImage

func (sc *Scene) DepthImage() ([]float32, error)

DepthImage returns the current rendered depth image

func (*Scene) Destroy

func (sc *Scene) Destroy()

func (*Scene) DoUpdate

func (sc *Scene) DoUpdate() bool

DoUpdate handles needed updates based on Scene Flags. If no updates are required, then false is returned, else true.

func (*Scene) Image

func (sc *Scene) Image() (*image.RGBA, error)

Image returns the current rendered image from the Frame RenderTexture. This version returns a direct pointer to the underlying host version of the GPU image, and should only be used immediately (for saving or writing to another image). You must call ImageDone() when done with the image. See [ImageCopy] for a version that returns a copy of the image, which will be usable until the next call to ImageCopy.

func (*Scene) ImageCopy

func (sc *Scene) ImageCopy() (*image.RGBA, error)

ImageCopy returns a copy of the current rendered image from the Frame RenderTexture. A re-used image.RGBA is returned. This same image is used across calls to avoid large memory allocations, so it will automatically update after the next ImageCopy call. The underlying image is in the [ImgCopy] field. If a persistent image is required, call imagex.CloneAsRGBA.

func (*Scene) ImageDone

func (sc *Scene) ImageDone()

ImageDone must be called when done using the image returned by Scene.Image.

func (*Scene) ImageUpdate added in v0.1.3

func (sc *Scene) ImageUpdate() (*image.RGBA, error)

ImageUpdate configures, updates, and renders the scene, then returns Scene.Image.

func (*Scene) Init added in v0.2.0

func (sc *Scene) Init()

func (*Scene) IsLive added in v0.3.2

func (sc *Scene) IsLive() bool

IsLive indicates whether the Phong system is active and we can directly update that, vs just creating elements to be added later.

func (*Scene) KeyChordEvent

func (sc *Scene) KeyChordEvent(e events.Event)

func (*Scene) MeshByName

func (sc *Scene) MeshByName(nm string) (Mesh, error)

MeshByName looks for mesh by name, returning error if not found.

func (*Scene) MeshList

func (sc *Scene) MeshList() []string

MeshList returns a list of available meshes (e.g., for chooser)

func (*Scene) MouseScrollEvent

func (sc *Scene) MouseScrollEvent(e *events.MouseScroll)

func (*Scene) NavKeyEvents

func (sc *Scene) NavKeyEvents(kt events.Event)

NavKeyEvents handles standard viewer keyboard navigation events

func (*Scene) NewInLibrary

func (sc *Scene) NewInLibrary(nm string) *Group

NewInLibrary makes a new Group in library, using given name as unique key in Library map.

func (*Scene) OpenNewObj

func (sc *Scene) OpenNewObj(fname string, parent tree.Node) (*Group, error)

OpenNewObj opens object(s) from given file into a new group under given parent, using a decoder based on the file extension. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

func (*Scene) OpenNewObjFS

func (sc *Scene) OpenNewObjFS(fsys fs.FS, fname string, parent tree.Node) (*Group, error)

OpenNewObjFS opens object(s) from given file in the given filesystem into a new group under given parent, using a decoder based on the file extension. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

func (*Scene) OpenObj

func (sc *Scene) OpenObj(fname string, gp *Group) error

OpenObj opens object(s) from given file into given group in scene, using a decoder based on the file extension. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

func (*Scene) OpenObjFS

func (sc *Scene) OpenObjFS(fsys fs.FS, fname string, gp *Group) error

OpenObjFS opens object(s) from given file in the given filesystem into given group in scene, using a decoder based on the file extension. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

func (*Scene) OpenScene

func (sc *Scene) OpenScene(fname string) error

OpenScene opens a scene from the given file, using a decoder based on the file extension in first file name. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.
Does not support full scene data so only objects are loaded
into a new group in scene.

func (*Scene) OpenSceneFS

func (sc *Scene) OpenSceneFS(fsys fs.FS, fname string) error

OpenSceneFS opens a scene from the given file in the given filesystem, using a decoder based on the file extension in first file name. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.
Does not support full scene data so only objects are loaded
into a new group in scene.

func (*Scene) OpenToLibrary

func (sc *Scene) OpenToLibrary(fname string, libnm string) (*Group, error)

OpenToLibrary opens object(s) from given file into the scene's Library using a decoder based on the file extension. The library key name must be unique, and is given by libnm -- if empty, then the filename (only) without extension is used. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

func (*Scene) OpenToLibraryFS

func (sc *Scene) OpenToLibraryFS(fsys fs.FS, fname string, libnm string) (*Group, error)

OpenToLibraryFS opens object(s) from given file in the given filesystem into the scene's Library using a decoder based on the file extension. The library key name must be unique, and is given by libnm -- if empty, then the filename (only) without extension is used. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.

func (*Scene) PlaneMesh2D

func (sc *Scene) PlaneMesh2D() Mesh

PlaneMesh2D returns the special Plane mesh used for Text2D and Embed2D (creating it if it does not yet exist). This is a 1x1 plane with a normal pointing in +Z direction.

func (*Scene) ReadObj

func (sc *Scene) ReadObj(fname string, rs []io.Reader, gp *Group) error

ReadObj reads object(s) from given reader(s) into given group in scene, using a decoder based on the extension of the given file name -- even though the file name is not directly used to read the file, it is required for naming and decoding selection. This method can be used for loading data embedded in an executable for example. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

is the 2nd reader arg, or a default material is used.

func (*Scene) ReadScene

func (sc *Scene) ReadScene(fname string, rs []io.Reader, gp *Group) error

ReadScene reads scene from given reader(s), using a decoder based on the file name extension -- even though the file name is not directly used to read the file, it is required for naming and decoding selection. This method can be used for loading data embedded in an executable for example. Supported formats include: .obj = Wavefront OBJ format, including associated materials (.mtl) which

must have same name as .obj, or a default material is used.
Does not support full scene data so only objects are loaded
into a new group in scene.

func (*Scene) Rebuild added in v0.3.2

func (sc *Scene) Rebuild()

Rebuild updates all the data resources. Is only effective when the GPU render is active.

func (*Scene) Render

func (sc *Scene) Render() bool

Render renders the scene to the Frame framebuffer. Only the Camera pose view matrix is updated here. If nodes require their own pose etc updates, UpdateNodes must be called prior to render. Returns false if currently already rendering.

func (*Scene) RenderImpl

func (sc *Scene) RenderImpl()

RenderImpl renders the scene to the framebuffer. all scene-level resources must be initialized and activated at this point

func (*Scene) ResetMeshes added in v0.3.2

func (sc *Scene) ResetMeshes()

ResetMeshes removes all meshes. Use this to remove unused meshes after significant update. Note that there is no Delete mechanism because the GPU Phong system does not support it for efficiency reasons.

func (*Scene) SaveCamera

func (sc *Scene) SaveCamera(name string)

SaveCamera saves the current camera with given name -- can be restored later with SetCamera. "default" is a special name that is automatically saved on first render, and restored with the spacebar under default NavEvents. Numbered cameras 0-9 also saved / restored with corresponding keys.

func (*Scene) SetBackground added in v0.2.1

func (t *Scene) SetBackground(v image.Image) *Scene

SetBackground sets the [Scene.Background]: Background is the background of the scene, which is used directly as a solid color in Vulkan.

func (*Scene) SetCamera

func (sc *Scene) SetCamera(name string) error

SetCamera sets the current camera to that of given name -- error if not found. "default" is a special name that is automatically saved on first render, and restored with the spacebar under default NavEvents. Numbered cameras 0-9 also saved / restored with corresponding keys.

func (*Scene) SetMesh added in v0.3.2

func (sc *Scene) SetMesh(ms Mesh)

SetMesh sets / updates the given mesh, updating any existing mesh of the same name. See NewX for convenience methods to add specific shapes.

func (*Scene) SetMultiSample

func (t *Scene) SetMultiSample(v int) *Scene

SetMultiSample sets the [Scene.MultiSample]: number of samples in multisampling. Default of 4 produces smooth rendering.

func (*Scene) SetNeedsRender

func (sc *Scene) SetNeedsRender()

SetNeedsRender sets [Scene.NeedsRender] to true.

func (*Scene) SetNeedsUpdate

func (sc *Scene) SetNeedsUpdate()

SetNeedsUpdate sets Scene.SetNeedsUpdate to true.

func (*Scene) SetNoNav

func (t *Scene) SetNoNav(v bool) *Scene

SetNoNav sets the [Scene.NoNav]: don't activate the standard navigation keyboard and mouse event processing to move around the camera in the scene.

func (*Scene) SetSize

func (sc *Scene) SetSize(sz image.Point) *Scene

SetSize sets the size of the [Scene.Frame].

func (*Scene) SetTexture added in v0.3.2

func (sc *Scene) SetTexture(tx Texture)

SetTexture adds given texture to texture collection see NewTextureFile to add a texture that loads from file

func (*Scene) SetWireframe

func (t *Scene) SetWireframe(v bool) *Scene

SetWireframe sets the [Scene.Wireframe]: render using wireframe instead of filled polygons. This must be set prior to configuring the Phong rendering system (i.e., just after Scene is made). note: not currently working in WebGPU.

func (*Scene) SlideMoveEvent

func (sc *Scene) SlideMoveEvent(e events.Event)

func (*Scene) SolidsIntersectingPoint

func (sc *Scene) SolidsIntersectingPoint(pos image.Point) []Node

SolidsIntersectingPoint finds all the solids that contain given 2D window coordinate

func (*Scene) TextureByName

func (sc *Scene) TextureByName(nm string) (Texture, error)

TextureByName looks for texture by name, returning error if not found.

func (*Scene) TextureList

func (sc *Scene) TextureList() []string

TextureList returns a list of available textures (e.g., for chooser)

func (*Scene) TrackCamera

func (sc *Scene) TrackCamera() bool

TrackCamera -- a Group at the top-level named "TrackCamera" will automatically track the camera (i.e., its Pose is copied). Solids in that group can set their relative Pos etc to display relative to the camera, to achieve "first person" effects.

func (*Scene) Update

func (sc *Scene) Update()

Update is a global update of everything: config, update, and re-render

func (*Scene) UpdateMVPMatrix

func (sc *Scene) UpdateMVPMatrix()

UpdateMVPMatrix updates the Model-View-Projection matrix for all scene elements and BBox2D

func (*Scene) UpdateMeshBBox

func (sc *Scene) UpdateMeshBBox()

UpdateMeshBBox updates the Mesh-based BBox info for all nodes. groups aggregate over elements

func (*Scene) UpdateNodes

func (sc *Scene) UpdateNodes()

func (*Scene) UpdateNodesIfNeeded

func (sc *Scene) UpdateNodesIfNeeded()

UpdateNodesIfNeeded can be called to update prior to an ad-hoc render if the NeedsUpdate flag has been set (resets flag)

func (*Scene) Validate

func (sc *Scene) Validate() error

Validate traverses the scene and validates all the elements -- errors are logged and a non-nil return indicates that at least one error was found.

type Solid

type Solid struct {
	NodeBase

	// MeshName is the name of the mesh shape information used for rendering
	// this solid; all meshes are collected on the Scene.
	MeshName MeshName `set:"-"`

	// Material contains the material properties of the surface (color, shininess, texture, etc).
	Material Material `display:"add-fields"`

	// Mesh is the cached [Mesh] object set from [Solid.MeshName].
	Mesh Mesh `display:"-" set:"-"`
}

Solid represents an individual 3D solid element. It has its own unique spatial transforms and material properties, and points to a mesh structure defining the shape of the solid.

func NewLine

func NewLine(sc *Scene, parent tree.Node, name string, st, ed math32.Vector3, width float32, clr color.RGBA) *Solid

NewLine adds a new line between two specified points, using a shared mesh unit line, which is rotated and positioned to go between the designated points.

func NewSolid

func NewSolid(parent ...tree.Node) *Solid

NewSolid returns a new Solid with the given optional parent: Solid represents an individual 3D solid element. It has its own unique spatial transforms and material properties, and points to a mesh structure defining the shape of the solid.

func (*Solid) AsSolid

func (sld *Solid) AsSolid() *Solid

func (*Solid) Config

func (sld *Solid) Config()

func (*Solid) Defaults

func (sld *Solid) Defaults()

Defaults sets default initial settings for solid params. This is called automatically Init.

func (*Solid) Init added in v0.2.0

func (sld *Solid) Init()

func (*Solid) IsSolid

func (sld *Solid) IsSolid() bool

func (*Solid) IsTransparent

func (sld *Solid) IsTransparent() bool

func (*Solid) IsVisible

func (sld *Solid) IsVisible() bool

func (*Solid) ParentMaterial

func (sld *Solid) ParentMaterial() *Material

ParentMaterial returns parent's material or nil if not avail

func (*Solid) PreRender added in v0.3.2

func (sld *Solid) PreRender()

PreRender activates this solid for rendering

func (*Solid) Render

func (sld *Solid) Render(rp *wgpu.RenderPassEncoder)

Render activates this solid for rendering

func (*Solid) RenderClass

func (sld *Solid) RenderClass() RenderClasses

RenderClass returns the class of rendering for this solid used for organizing the ordering of rendering

func (*Solid) SetAxisRotation

func (sld *Solid) SetAxisRotation(x, y, z, angle float32) *Solid

SetAxisRotation sets the [Pose.Quat] rotation of the solid, from local axis and angle in degrees.

func (*Solid) SetBright

func (sld *Solid) SetBright(v float32) *Solid

SetBright sets the [Material.Bright]: prop: bright = overall multiplier on final computed color value -- can be used to tune the overall brightness of various surfaces relative to each other for a given set of lighting parameters

func (*Solid) SetColor

func (sld *Solid) SetColor(v color.RGBA) *Solid

SetColor sets the [Material.Color]: prop: color = main color of surface, used for both ambient and diffuse color in standard Phong model -- alpha component determines transparency -- note that transparent objects require more complex rendering

func (*Solid) SetEmissive

func (sld *Solid) SetEmissive(v color.RGBA) *Solid

SetEmissive sets the [Material.Emissive]: prop: emissive = color that surface emits independent of any lighting -- i.e., glow -- can be used for marking lights with an object

func (*Solid) SetEulerRotation

func (sld *Solid) SetEulerRotation(x, y, z float32) *Solid

SetEulerRotation sets the [Pose.Quat] rotation of the solid, from euler angles in degrees

func (*Solid) SetMaterial added in v0.2.0

func (t *Solid) SetMaterial(v Material) *Solid

SetMaterial sets the [Solid.Material]: Material contains the material properties of the surface (color, shininess, texture, etc).

func (*Solid) SetMesh

func (sld *Solid) SetMesh(ms Mesh) *Solid

SetMesh sets mesh

func (*Solid) SetMeshName

func (sld *Solid) SetMeshName(meshName string) error

SetMeshName sets mesh to given mesh name.

func (*Solid) SetPos

func (sld *Solid) SetPos(x, y, z float32) *Solid

SetPos sets the [Pose.Pos] position of the solid

func (*Solid) SetReflective

func (sld *Solid) SetReflective(v float32) *Solid

SetReflective sets the [Material.Reflective]: prop: reflective = specular reflectiveness factor -- how much it shines back directional light. The specular reflection color is always white * the incoming light.

func (*Solid) SetScale

func (sld *Solid) SetScale(x, y, z float32) *Solid

SetScale sets the [Pose.Scale] scale of the solid

func (*Solid) SetShiny

func (sld *Solid) SetShiny(v float32) *Solid

SetShiny sets the [Material.Shiny]: prop: shiny = specular shininess factor -- how focally vs. broad the surface shines back directional light -- this is an exponential factor, with 0 = very broad diffuse reflection, and higher values (typically max of 128 or so but can go higher) having a smaller more focal specular reflection. Also set Reflective factor to change overall shininess effect.

func (*Solid) SetTexture

func (sld *Solid) SetTexture(tex Texture) *Solid

SetTexture sets material to use given texture

func (*Solid) SetTextureName

func (sld *Solid) SetTextureName(texName string) *Solid

SetTextureName sets material to use given texture name (textures are accessed by name on Scene). If name is empty, then texture is reset

func (*Solid) UpdateMeshBBox

func (sld *Solid) UpdateMeshBBox()

UpdateMeshBBox updates the Mesh-based BBox info for all nodes. groups aggregate over elements

func (*Solid) Validate

func (sld *Solid) Validate() error

Validate checks that solid has valid mesh and texture settings, etc

type SolidPoint

type SolidPoint struct {
	Solid *Solid
	Point math32.Vector3
}

SolidPoint contains a Solid and a Point on that solid

type Sphere

type Sphere struct {
	MeshBase

	// radius of the sphere
	Radius float32

	// number of segments around the width of the sphere (32 is reasonable default for full circle)
	WidthSegs int `min:"3"`

	// number of height segments (32 is reasonable default for full height)
	HeightSegs int `min:"3"`

	// starting radial angle in degrees, relative to -1,0,0 left side starting point
	AngStart float32 `min:"0" max:"360" step:"5"`

	// total radial angle to generate in degrees (max = 360)
	AngLen float32 `min:"0" max:"360" step:"5"`

	// starting elevation (height) angle in degrees - 0 = top of sphere, and Pi is bottom
	ElevStart float32 `min:"0" max:"180" step:"5"`

	// total angle to generate in degrees (max = 180)
	ElevLen float32 `min:"0" max:"180" step:"5"`
}

Sphere is a sphere mesh

func NewSphere

func NewSphere(sc *Scene, name string, radius float32, segs int) *Sphere

NewSphere creates a sphere mesh with the specified radius, number of segments (resolution).

func (*Sphere) Defaults

func (sp *Sphere) Defaults()

func (*Sphere) MeshSize added in v0.3.2

func (sp *Sphere) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*Sphere) Set

func (sp *Sphere) Set(vertex, normal, texcoord, clrs math32.ArrayF32, index math32.ArrayU32)

func (*Sphere) SetAngLen

func (t *Sphere) SetAngLen(v float32) *Sphere

SetAngLen sets the [Sphere.AngLen]: total radial angle to generate in degrees (max = 360)

func (*Sphere) SetAngStart

func (t *Sphere) SetAngStart(v float32) *Sphere

SetAngStart sets the [Sphere.AngStart]: starting radial angle in degrees, relative to -1,0,0 left side starting point

func (*Sphere) SetElevLen

func (t *Sphere) SetElevLen(v float32) *Sphere

SetElevLen sets the [Sphere.ElevLen]: total angle to generate in degrees (max = 180)

func (*Sphere) SetElevStart

func (t *Sphere) SetElevStart(v float32) *Sphere

SetElevStart sets the [Sphere.ElevStart]: starting elevation (height) angle in degrees - 0 = top of sphere, and Pi is bottom

func (*Sphere) SetHeightSegs

func (t *Sphere) SetHeightSegs(v int) *Sphere

SetHeightSegs sets the [Sphere.HeightSegs]: number of height segments (32 is reasonable default for full height)

func (*Sphere) SetRadius

func (t *Sphere) SetRadius(v float32) *Sphere

SetRadius sets the [Sphere.Radius]: radius of the sphere

func (*Sphere) SetWidthSegs

func (t *Sphere) SetWidthSegs(v int) *Sphere

SetWidthSegs sets the [Sphere.WidthSegs]: number of segments around the width of the sphere (32 is reasonable default for full circle)

type Spot added in v0.3.2

type Spot struct {
	LightBase

	Pose Pose // position and orientation.

	// Angular decay factor, defaults to 15.
	AngDecay float32

	// Cut off angle (in degrees), defaults to 45; max of 90.
	CutoffAngle float32 `max:"90" min:"1"`

	// Distance linear decay factor, defaults to .01.
	LinDecay float32

	// Distance quadratic decay factor, defaults to .001; dominates at longer distances.
	QuadDecay float32
}

Spotlight is a light with a position and direction and associated decay factors and angles, which divide the light intensity as a function of linear and quadratic distance. The quadratic factor dominates at longer distances.

func NewSpot added in v0.3.2

func NewSpot(sc *Scene, name string, lumens float32, color LightColors) *Spot

NewSpot adds spot light to given scene, with given name, standard color, and lumens (0-1 normalized). By default it is located at 0,5,5 (up and between default camera and origin) and pointing at the origin. Use the Pose LookAt function to point it at other locations. In its unrotated state, it points down the -Z axis (i.e., into the scene using default view parameters)

func (*Spot) LookAt added in v0.3.2

func (sl *Spot) LookAt(target, upDir math32.Vector3)

LookAt points the spotlight at given target location, using given up direction.

func (*Spot) LookAtOrigin added in v0.3.2

func (sl *Spot) LookAtOrigin()

LookAtOrigin points the spotlight at origin with Y axis pointing Up (i.e., standard)

func (*Spot) ViewDir added in v0.3.2

func (sl *Spot) ViewDir() math32.Vector3

ViewDir gets the direction normal vector, pre-computing the view transform

type Text2D

type Text2D struct {
	Solid

	// the text string to display
	Text string

	// styling settings for the text
	Styles styles.Style `set:"-" json:"-" xml:"-"`

	// position offset of start of text rendering relative to upper-left corner
	TextPos math32.Vector2 `set:"-" xml:"-" json:"-"`

	// render data for text label
	TextRender paint.Text `set:"-" xml:"-" json:"-"`

	// render state for rendering text
	RenderState paint.State `set:"-" copier:"-" json:"-" xml:"-" display:"-"`
	// contains filtered or unexported fields
}

Text2D presents 2D rendered text on a vertically oriented plane, using a texture. Call SetText() which calls RenderText to update fortext changes (re-renders texture). The native scale is such that a unit height value is the height of the default font set by the font-size property, and the X axis is scaled proportionally based on the rendered text size to maintain the aspect ratio. Further scaling can be applied on top of that by setting the Pose.Scale values as usual. Standard styling properties can be set on the node to set font size, family, and text alignment relative to the Pose.Pos position (e.g., Left, Top puts the upper-left corner of text at Pos). Note that higher quality is achieved by using a larger font size (36 default). The margin property creates blank margin of the background color around the text (2 px default) and the background-color defaults to transparent but can be set to any color.

func NewText2D

func NewText2D(parent ...tree.Node) *Text2D

NewText2D returns a new Text2D with the given optional parent: Text2D presents 2D rendered text on a vertically oriented plane, using a texture. Call SetText() which calls RenderText to update fortext changes (re-renders texture). The native scale is such that a unit height value is the height of the default font set by the font-size property, and the X axis is scaled proportionally based on the rendered text size to maintain the aspect ratio. Further scaling can be applied on top of that by setting the Pose.Scale values as usual. Standard styling properties can be set on the node to set font size, family, and text alignment relative to the Pose.Pos position (e.g., Left, Top puts the upper-left corner of text at Pos). Note that higher quality is achieved by using a larger font size (36 default). The margin property creates blank margin of the background color around the text (2 px default) and the background-color defaults to transparent but can be set to any color.

func (*Text2D) Config

func (txt *Text2D) Config()

func (*Text2D) Defaults

func (txt *Text2D) Defaults()

func (*Text2D) Init added in v0.2.0

func (txt *Text2D) Init()

func (*Text2D) IsTransparent

func (txt *Text2D) IsTransparent() bool

func (*Text2D) RenderClass

func (txt *Text2D) RenderClass() RenderClasses

func (*Text2D) RenderText

func (txt *Text2D) RenderText()

func (*Text2D) SetText

func (t *Text2D) SetText(v string) *Text2D

SetText sets the [Text2D.Text]: the text string to display

func (*Text2D) TextSize

func (txt *Text2D) TextSize() (math32.Vector2, bool)

TextSize returns the size of the text plane, applying all *local* scaling factors if nothing rendered yet, returns false

func (*Text2D) UpdateWorldMatrix

func (txt *Text2D) UpdateWorldMatrix(parWorld *math32.Matrix4)

func (*Text2D) Validate

func (txt *Text2D) Validate() error

Validate checks that text has valid mesh and texture settings, etc

type Texture

type Texture interface {
	// AsTextureBase returns the [TextureBase] for this texture,
	// which contains the core data and functionality.
	AsTextureBase() *TextureBase

	// Image returns the image for the texture in the [image.RGBA] format used internally.
	Image() *image.RGBA
}

Texture is the interface for all textures.

type TextureBase

type TextureBase struct {
	// Name is the name of the texture;
	// textures are connected to [Material]s by name.
	Name string

	// Transprent is whether the texture has transparency.
	Transparent bool

	// RGBA is the cached internal representation of the image.
	RGBA *image.RGBA
}

TextureBase is the base texture implementation. It uses an image.RGBA as the underlying image storage to facilitate interface with GPU.

func (*TextureBase) AsTextureBase added in v0.2.0

func (tx *TextureBase) AsTextureBase() *TextureBase

func (*TextureBase) Image

func (tx *TextureBase) Image() *image.RGBA

func (*TextureBase) SetName added in v0.2.0

func (t *TextureBase) SetName(v string) *TextureBase

SetName sets the [TextureBase.Name]: Name is the name of the texture; textures are connected to [Material]s by name.

func (*TextureBase) SetRGBA added in v0.2.0

func (t *TextureBase) SetRGBA(v *image.RGBA) *TextureBase

SetRGBA sets the [TextureBase.RGBA]: RGBA is the cached internal representation of the image.

func (*TextureBase) SetTransparent

func (t *TextureBase) SetTransparent(v bool) *TextureBase

SetTransparent sets the [TextureBase.Transparent]: Transprent is whether the texture has transparency.

type TextureCore added in v0.2.0

type TextureCore struct {
	TextureBase
}

TextureCore is a dynamic texture material driven by a core.Scene. Anything rendered to the scene will be projected onto the surface of any solid using this texture. TODO: update this along with embed2d

type TextureFile

type TextureFile struct {
	TextureBase

	// filesystem for embedded etc
	FS fs.FS

	// filename for the texture
	File string
}

TextureFile is a texture loaded from a file

func NewTextureFile

func NewTextureFile(sc *Scene, name string, filename string) *TextureFile

NewTextureFile adds a new texture from file of given name and filename

func NewTextureFileFS

func NewTextureFileFS(fsys fs.FS, sc *Scene, name string, filename string) *TextureFile

NewTextureFileFS adds a new texture from file of given name and filename

func (*TextureFile) Image

func (tx *TextureFile) Image() *image.RGBA

type TextureName added in v0.2.0

type TextureName string

TextureName provides a GUI interface for choosing textures.

type Torus

type Torus struct {
	MeshBase

	// larger radius of the torus ring
	Radius float32

	// radius of the solid tube
	TubeRadius float32

	// number of segments around the radius of the torus (32 is reasonable default for full circle)
	RadialSegs int `min:"1"`

	// number of segments for the tube itself (32 is reasonable default for full height)
	TubeSegs int `min:"1"`

	// starting radial angle in degrees relative to 1,0,0 starting point
	AngStart float32 `min:"0" max:"360" step:"5"`

	// total radial angle to generate in degrees (max = 360)
	AngLen float32 `min:"0" max:"360" step:"5"`
}

Torus is a torus mesh, defined by the radius of the solid tube and the larger radius of the ring.

func NewTorus

func NewTorus(sc *Scene, name string, radius, tubeRadius float32, segs int) *Torus

NewTorus creates a sphere mesh with the specified outer ring radius, solid tube radius, and number of segments (resolution).

func (*Torus) Defaults

func (tr *Torus) Defaults()

func (*Torus) MeshSize added in v0.3.2

func (tr *Torus) MeshSize() (numVertex, nIndex int, hasColor bool)

func (*Torus) Set

func (tr *Torus) Set(vertex, normal, texcoord, clrs math32.ArrayF32, index math32.ArrayU32)

Set sets points for torus in given allocated arrays

func (*Torus) SetAngLen

func (t *Torus) SetAngLen(v float32) *Torus

SetAngLen sets the [Torus.AngLen]: total radial angle to generate in degrees (max = 360)

func (*Torus) SetAngStart

func (t *Torus) SetAngStart(v float32) *Torus

SetAngStart sets the [Torus.AngStart]: starting radial angle in degrees relative to 1,0,0 starting point

func (*Torus) SetRadialSegs

func (t *Torus) SetRadialSegs(v int) *Torus

SetRadialSegs sets the [Torus.RadialSegs]: number of segments around the radius of the torus (32 is reasonable default for full circle)

func (*Torus) SetRadius

func (t *Torus) SetRadius(v float32) *Torus

SetRadius sets the [Torus.Radius]: larger radius of the torus ring

func (*Torus) SetTubeRadius

func (t *Torus) SetTubeRadius(v float32) *Torus

SetTubeRadius sets the [Torus.TubeRadius]: radius of the solid tube

func (*Torus) SetTubeSegs

func (t *Torus) SetTubeSegs(v int) *Torus

SetTubeSegs sets the [Torus.TubeSegs]: number of segments for the tube itself (32 is reasonable default for full height)

Directories

Path Synopsis
examples
io
obj
Package obj is used to parse the Wavefront OBJ file format (*.obj), including associated materials (*.mtl).
Package obj is used to parse the Wavefront OBJ file format (*.obj), including associated materials (*.mtl).
Package xyzcore provides a GUI view for a 3D xyz scene.
Package xyzcore provides a GUI view for a 3D xyz scene.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL