xyz

package module
v0.5.20 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2023 License: BSD-3-Clause Imports: 36 Imported by: 6

README

XYZ

Go Reference

xyz is a 3D graphics framework written in Go. It was originally developed as gi3d, included in the GoGi GUI framework, but is now a separate standalone package that renders to an offscreen Vulkan framebuffer, which can easily be converted into a Go image.RGBA. The xyzv package in GoGi provides an integration of xyz in GoGi, for dynamic and efficient 3D rendering within 2D GUI windows.

xyz is built on the vgpu Vulkan GPU framework, and uses the goki 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 almost all 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 and mobile platforms, and the use of Vulkan which is highly efficient. See eve for a virtual environment framework built on top of xyz, which provides a physics engine for simulating 3D worlds (for use in training neural network models).

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.

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.
      • Dir ectional 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 ki.Ki 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 GoGi 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 GoGi GUI can be embedded within a 3D scene using the xyzv.Embed2D Node type, which renders a gi.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 provides a 3D scenegraph for the GoGi GUI framework.

The scenegraph is rooted at a xyz.Scene node which is like gi.Viewport2D, where the scene is rendered, similar to the svg.SVG node for SVG drawings.

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 verticies, 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 GoGi 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.

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"
)
View Source
const (
	// Version is the version of this package being used
	Version = "v0.5.20"
	// GitCommit is the commit just before the latest version commit
	GitCommit = "a26ec3c"
	// VersionDate is the date-time of the latest version commit in UTC (in the format 'YYYY-MM-DD HH:MM', which is the Go format '2006-01-02 15:04')
	VersionDate = "2023-12-26 23:36"
)

Variables

View Source
var (
	OrbitFactor = float32(0.025)
	PanFactor   = float32(0.001)
)
View Source
var CameraProps = ki.Props{
	"Toolbar": ki.PropSlice{
		{"Defaults", ki.Props{
			"label": "Defaults",
			"icon":  icons.DeviceReset,
		}},
		{"LookAt", ki.Props{
			"icon": icons.Visibility,
			"Args": ki.PropSlice{
				{"Target", ki.BlankProp{}},
				{"UpDir", ki.BlankProp{}},
			},
		}},
		{"Orbit", ki.Props{
			"icon": icons.X3DRotation,
			"Args": ki.PropSlice{
				{"DeltaX", ki.BlankProp{}},
				{"DeltaY", ki.BlankProp{}},
			},
		}},
		{"Pan", ki.Props{
			"icon": icons.PanTool,
			"Args": ki.PropSlice{
				{"DeltaX", ki.BlankProp{}},
				{"DeltaY", ki.BlankProp{}},
			},
		}},
		{"PanAxis", ki.Props{
			"icon": icons.PanTool,
			"Args": ki.PropSlice{
				{"DeltaX", ki.BlankProp{}},
				{"DeltaY", ki.BlankProp{}},
			},
		}},
		{"PanTarget", ki.Props{
			"icon": icons.PanTool,
			"Args": ki.PropSlice{
				{"DeltaX", ki.BlankProp{}},
				{"DeltaY", ki.BlankProp{}},
				{"DeltaZ", ki.BlankProp{}},
			},
		}},
		{"Zoom", ki.Props{
			"icon": icons.ZoomIn,
			"Args": ki.PropSlice{
				{"ZoomPct", ki.BlankProp{}},
			},
		}},
	},
}

CameraProps define the Toolbar and MenuBar for StructView

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 GroupType = gti.AddType(&gti.Type{
	Name:       "goki.dev/xyz.Group",
	ShortName:  "xyz.Group",
	IDName:     "group",
	Doc:        "Group collects individual elements in a scene but does not have a Mesh or Material of\nits own.  It does have a transform that applies to all nodes under it.",
	Directives: gti.Directives{},
	Fields:     ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{}),
	Embeds: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"NodeBase", &gti.Field{Name: "NodeBase", Type: "goki.dev/xyz.NodeBase", LocalType: "NodeBase", Doc: "", Directives: gti.Directives{}, Tag: ""}},
	}),
	Methods:  ordmap.Make([]ordmap.KeyVal[string, *gti.Method]{}),
	Instance: &Group{},
})

GroupType is the gti.Type for Group

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 NodeBaseType = gti.AddType(&gti.Type{
	Name:       "goki.dev/xyz.NodeBase",
	ShortName:  "xyz.NodeBase",
	IDName:     "node-base",
	Doc:        "NodeBase is the basic 3D scenegraph node, which has the full transform information\nrelative to parent, and computed bounding boxes, etc.\nThere are only two different kinds of Nodes: Group and Solid",
	Directives: gti.Directives{},
	Fields: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"Pose", &gti.Field{Name: "Pose", Type: "goki.dev/xyz.Pose", LocalType: "Pose", Doc: "complete specification of position and orientation", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"Sc", &gti.Field{Name: "Sc", Type: "*goki.dev/xyz.Scene", LocalType: "*Scene", Doc: "Sc is the cached Scene", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"PoseMu", &gti.Field{Name: "PoseMu", Type: "sync.RWMutex", LocalType: "sync.RWMutex", Doc: "mutex on pose access -- needed for parallel updating", Directives: gti.Directives{}, Tag: "view:\"-\" copy:\"-\" json:\"-\" xml:\"-\"  set:\"-\""}},
		{"MeshBBox", &gti.Field{Name: "MeshBBox", Type: "goki.dev/xyz.BBox", LocalType: "BBox", Doc: "mesh-based local bounding box (aggregated for groups)", Directives: gti.Directives{}, Tag: "edit:\"-\" copy:\"-\" json:\"-\" xml:\"-\" set:\"-\""}},
		{"WorldBBox", &gti.Field{Name: "WorldBBox", Type: "goki.dev/xyz.BBox", LocalType: "BBox", Doc: "world coordinates bounding box", Directives: gti.Directives{}, Tag: "edit:\"-\" copy:\"-\" json:\"-\" xml:\"-\" set:\"-\""}},
		{"NDCBBox", &gti.Field{Name: "NDCBBox", Type: "goki.dev/mat32/v2.Box3", LocalType: "mat32.Box3", Doc: "normalized display coordinates bounding box, used for frustrum clipping", Directives: gti.Directives{}, Tag: "edit:\"-\" copy:\"-\" json:\"-\" xml:\"-\" set:\"-\""}},
		{"BBox", &gti.Field{Name: "BBox", Type: "image.Rectangle", LocalType: "image.Rectangle", Doc: "raw original bounding box for the widget within its parent Scene.\nThis is prior to intersecting with Frame bounds.", Directives: gti.Directives{}, Tag: "edit:\"-\" copy:\"-\" json:\"-\" xml:\"-\" set:\"-\""}},
		{"ScBBox", &gti.Field{Name: "ScBBox", Type: "image.Rectangle", LocalType: "image.Rectangle", Doc: "2D bounding box for region occupied within Scene Frame that we render onto.\nThis is BBox intersected with Frame bounds.", Directives: gti.Directives{}, Tag: "edit:\"-\" copy:\"-\" json:\"-\" xml:\"-\" set:\"-\""}},
	}),
	Embeds: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"Node", &gti.Field{Name: "Node", Type: "goki.dev/ki/v2.Node", LocalType: "ki.Node", Doc: "", Directives: gti.Directives{}, Tag: ""}},
	}),
	Methods:  ordmap.Make([]ordmap.KeyVal[string, *gti.Method]{}),
	Instance: &NodeBase{},
})

NodeBaseType is the gti.Type for NodeBase

View Source
var SceneType = gti.AddType(&gti.Type{
	Name:      "goki.dev/xyz.Scene",
	ShortName: "xyz.Scene",
	IDName:    "scene",
	Doc:       "Scene is the overall scenegraph containing nodes as children.\nIt renders to its own vgpu.RenderFrame.\nThe Image of this Frame is usable directly or, via gi3v.Scene,\nwhere it is copied into an overall gi.Scene image.\n\nThere is default navigation event processing (disabled by setting NoNav)\nwhere mouse drag events Orbit the camera (Shift = Pan, Alt = PanTarget)\nand arrow keys do Orbit, Pan, PanTarget with same key modifiers.\nSpacebar restores original \"default\" camera, and numbers save (1st time)\nor restore (subsequently) camera views (Control = always save)\n\nA Group at the top-level named \"TrackCamera\" will automatically track\nthe camera (i.e., its Pose is copied) -- Solids in that group can\nset their relative Pos etc to display relative to the camera, to achieve\n\"first person\" effects.",
	Directives: gti.Directives{
		&gti.Directive{Tool: "goki", Directive: "no-new", Args: []string{}},
		&gti.Directive{Tool: "goki", Directive: "embedder", Args: []string{}},
	},
	Fields: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"Geom", &gti.Field{Name: "Geom", Type: "goki.dev/mat32/v2.Geom2DInt", LocalType: "mat32.Geom2DInt", Doc: "Viewport-level viewbox within any parent Viewport2D", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"MultiSample", &gti.Field{Name: "MultiSample", Type: "int", LocalType: "int", Doc: "number of samples in multisampling -- must be a power of 2, and must be 1 if grabbing the Depth buffer back from the RenderFrame", Directives: gti.Directives{}, Tag: "def:\"4\""}},
		{"Wireframe", &gti.Field{Name: "Wireframe", Type: "bool", LocalType: "bool", Doc: "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)", Directives: gti.Directives{}, Tag: "def:\"false\""}},
		{"Camera", &gti.Field{Name: "Camera", Type: "goki.dev/xyz.Camera", LocalType: "Camera", Doc: "camera determines view onto scene", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"BackgroundColor", &gti.Field{Name: "BackgroundColor", Type: "image/color.RGBA", LocalType: "color.RGBA", Doc: "background color", Directives: gti.Directives{}, Tag: ""}},
		{"Lights", &gti.Field{Name: "Lights", Type: "goki.dev/ordmap.Map", LocalType: "ordmap.Map[string, Light]", Doc: "all lights used in the scene", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"Meshes", &gti.Field{Name: "Meshes", Type: "goki.dev/ordmap.Map", LocalType: "ordmap.Map[string, Mesh]", Doc: "meshes -- holds all the mesh data -- must be configured prior to rendering", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"Textures", &gti.Field{Name: "Textures", Type: "goki.dev/ordmap.Map", LocalType: "ordmap.Map[string, Texture]", Doc: "textures -- must be configured prior to rendering -- a maximum of 16 textures is supported for full cross-platform portability", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"Library", &gti.Field{Name: "Library", Type: "map[string]*goki.dev/xyz.Group", LocalType: "map[string]*Group", Doc: "library of objects that can be used in the scene", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"NoNav", &gti.Field{Name: "NoNav", Type: "bool", LocalType: "bool", Doc: "don't activate the standard navigation keyboard and mouse event processing to move around the camera in the scene", Directives: gti.Directives{}, Tag: ""}},
		{"SavedCams", &gti.Field{Name: "SavedCams", Type: "map[string]goki.dev/xyz.Camera", LocalType: "map[string]Camera", Doc: "saved cameras -- can Save and Set these to view the scene from different angles", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"SetDragCursor", &gti.Field{Name: "SetDragCursor", Type: "bool", LocalType: "bool", Doc: "has dragging cursor been set yet?", Directives: gti.Directives{}, Tag: "view:\"-\" set:\"-\""}},
		{"Phong", &gti.Field{Name: "Phong", Type: "goki.dev/vgpu/v2/vphong.Phong", LocalType: "vphong.Phong", Doc: "the vphong rendering system", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"Frame", &gti.Field{Name: "Frame", Type: "*goki.dev/vgpu/v2/vgpu.RenderFrame", LocalType: "*vgpu.RenderFrame", Doc: "the vgpu render frame holding the rendered scene", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"ImgCopy", &gti.Field{Name: "ImgCopy", Type: "image.RGBA", LocalType: "image.RGBA", Doc: "image used to hold a copy of the Frame image, for ImageCopy() call.\nThis is re-used across calls to avoid large memory allocations,\nso it will automatically update after every ImageCopy call.\nIf a persistent image is required, call [glop/images.CloneAsRGBA].", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"DirUpIdx", &gti.Field{Name: "DirUpIdx", Type: "int", LocalType: "int", Doc: "index in list of window direct uploading images", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"RenderMu", &gti.Field{Name: "RenderMu", Type: "sync.Mutex", LocalType: "sync.Mutex", Doc: "mutex on rendering", Directives: gti.Directives{}, Tag: "view:\"-\" copy:\"-\" json:\"-\" xml:\"-\" set:\"-\""}},
	}),
	Embeds: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"Node", &gti.Field{Name: "Node", Type: "goki.dev/ki/v2.Node", LocalType: "ki.Node", Doc: "", Directives: gti.Directives{}, Tag: ""}},
	}),
	Methods:  ordmap.Make([]ordmap.KeyVal[string, *gti.Method]{}),
	Instance: &Scene{},
})

SceneType is the gti.Type for Scene

View Source
var SolidType = gti.AddType(&gti.Type{
	Name:       "goki.dev/xyz.Solid",
	ShortName:  "xyz.Solid",
	IDName:     "solid",
	Doc:        "Solid represents an individual 3D solid element.\nIt has its own unique spatial transforms and material properties,\nand points to a mesh structure defining the shape of the solid.",
	Directives: gti.Directives{},
	Fields: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"Mesh", &gti.Field{Name: "Mesh", Type: "goki.dev/xyz.MeshName", LocalType: "MeshName", Doc: "name of the mesh shape information used for rendering this solid -- all meshes are collected on the Scene", Directives: gti.Directives{}, Tag: "set:\"-\""}},
		{"Mat", &gti.Field{Name: "Mat", Type: "goki.dev/xyz.Material", LocalType: "Material", Doc: "material properties of the surface (color, shininess, texture, etc)", Directives: gti.Directives{}, Tag: "view:\"add-fields\""}},
		{"MeshPtr", &gti.Field{Name: "MeshPtr", Type: "goki.dev/xyz.Mesh", LocalType: "Mesh", Doc: "cached pointer to mesh", Directives: gti.Directives{}, Tag: "view:\"-\" set:\"-\""}},
	}),
	Embeds: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"NodeBase", &gti.Field{Name: "NodeBase", Type: "goki.dev/xyz.NodeBase", LocalType: "NodeBase", Doc: "", Directives: gti.Directives{}, Tag: ""}},
	}),
	Methods:  ordmap.Make([]ordmap.KeyVal[string, *gti.Method]{}),
	Instance: &Solid{},
})

SolidType is the gti.Type for Solid

View Source
var Text2DType = gti.AddType(&gti.Type{
	Name:       "goki.dev/xyz.Text2D",
	ShortName:  "xyz.Text2D",
	IDName:     "text-2-d",
	Doc:        "Text2D presents 2D rendered text on a vertically-oriented plane, using a texture.\nCall SetText() which calls RenderText to update fortext changes (re-renders texture).\nThe native scale is such that a unit height value is the height of the default font\nset by the font-size property, and the X axis is scaled proportionally based on the\nrendered text size to maintain the aspect ratio.  Further scaling can be applied on\ntop of that by setting the Pose.Scale values as usual.\nStandard styling properties can be set on the node to set font size, family,\nand text alignment relative to the Pose.Pos position (e.g., Left, Top puts the\nupper-left corner of text at Pos).\nNote that higher quality is achieved by using a larger font size (36 default).\nThe margin property creates blank margin of the background color around the text\n(2 px default) and the background-color defaults to transparent\nbut can be set to any color.",
	Directives: gti.Directives{},
	Fields: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"Text", &gti.Field{Name: "Text", Type: "string", LocalType: "string", Doc: "the text string to display", Directives: gti.Directives{}, Tag: ""}},
		{"Styles", &gti.Field{Name: "Styles", Type: "goki.dev/girl/styles.Style", LocalType: "styles.Style", Doc: "styling settings for the text", Directives: gti.Directives{}, Tag: "set:\"-\" json:\"-\" xml:\"-\""}},
		{"TxtPos", &gti.Field{Name: "TxtPos", Type: "goki.dev/mat32/v2.Vec2", LocalType: "mat32.Vec2", Doc: "position offset of start of text rendering relative to upper-left corner", Directives: gti.Directives{}, Tag: "set:\"-\" xml:\"-\" json:\"-\""}},
		{"TxtRender", &gti.Field{Name: "TxtRender", Type: "goki.dev/girl/paint.Text", LocalType: "paint.Text", Doc: "render data for text label", Directives: gti.Directives{}, Tag: "set:\"-\" xml:\"-\" json:\"-\""}},
		{"RenderState", &gti.Field{Name: "RenderState", Type: "goki.dev/girl/paint.State", LocalType: "paint.State", Doc: "render state for rendering text", Directives: gti.Directives{}, Tag: "set:\"-\" copy:\"-\" json:\"-\" xml:\"-\" view:\"-\""}},
	}),
	Embeds: ordmap.Make([]ordmap.KeyVal[string, *gti.Field]{
		{"Solid", &gti.Field{Name: "Solid", Type: "goki.dev/xyz.Solid", LocalType: "Solid", Doc: "", Directives: gti.Directives{}, Tag: ""}},
	}),
	Methods:  ordmap.Make([]ordmap.KeyVal[string, *gti.Method]{}),
	Instance: &Text2D{},
})

Text2DType is the gti.Type for Text2D

View Source
var Update3DTrace = false

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

Functions

func AsNode

func AsNode(k ki.Ki) (Node, *NodeBase)

AsNode converts Ki to a Node interface and a NodeBase obj -- nil if not.

func SetLineStartEnd

func SetLineStartEnd(ln *Solid, st, ed mat32.Vec3)

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

func UpdateWorldMatrix added in v0.5.18

func UpdateWorldMatrix(n ki.Ki)

UpdateWorldMatrix updates the world matrix for node and everything inside it

Types

type AmbientLight

type AmbientLight struct {
	LightBase
}

AmbientLight provides diffuse uniform lighting -- typically only one of these

func NewAmbientLight

func NewAmbientLight(sc *Scene, name string, lumens float32, color LightColors) *AmbientLight

NewAmbientLight 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 mat32.Box3

	// bounding sphere in local coords
	BSphere mat32.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 mat32.Vec3)

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

func (*BBox) UpdateFmBBox

func (bb *BBox) UpdateFmBBox()

UpdateFmBBox updates other values from BBox

type Box

type Box struct {
	MeshBase

	// size along each dimension
	Size mat32.Vec3

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

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) Set

func (bx *Box) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.ArrayU32)

func (*Box) SetColor

func (t *Box) SetColor(v bool) *Box

SetColor sets the [Box.Color]

func (*Box) SetDynamic

func (t *Box) SetDynamic(v bool) *Box

SetDynamic sets the [Box.Dynamic]

func (*Box) SetSegs

func (t *Box) SetSegs(v mat32.Vec3i) *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 mat32.Vec3) *Box

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

func (*Box) SetTrans

func (t *Box) SetTrans(v bool) *Box

SetTrans sets the [Box.Trans]

func (*Box) Sizes

func (bx *Box) Sizes() (nVtx, nIdx int, hasColor bool)

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

	// mutex protecting camera data
	CamMu sync.RWMutex

	// 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 mat32.Vec3

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

	// 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 mat32.Mat4 `view:"-"`

	// projection matrix, defining the camera perspective / ortho transform
	PrjnMatrix mat32.Mat4 `view:"-"`

	// vulkan projection matrix -- required for vgpu -- produces same effect as PrjnMatrix, which should be used for all other math
	VkPrjnMatrix mat32.Mat4 `view:"-"`

	// inverse of the projection matrix
	InvPrjnMatrix mat32.Mat4 `view:"-"`

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

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) DistTo

func (cm *Camera) DistTo(pt mat32.Vec3) float32

DistTo 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 mat32.Vec3)

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) TargetFmView

func (cm *Camera) TargetFmView()

TargetFmView 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 prjn matricies

func (*Camera) ViewMainAxis

func (cm *Camera) ViewMainAxis() (dim mat32.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() mat32.Vec3

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) Set

func (cp *Capsule) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.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) SetColor

func (t *Capsule) SetColor(v bool) *Capsule

SetColor sets the [Capsule.Color]

func (*Capsule) SetDynamic

func (t *Capsule) SetDynamic(v bool) *Capsule

SetDynamic sets the [Capsule.Dynamic]

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

func (*Capsule) SetTrans

func (t *Capsule) SetTrans(v bool) *Capsule

SetTrans sets the [Capsule.Trans]

func (*Capsule) Sizes

func (cp *Capsule) Sizes() (nVtx, nIdx int, hasColor bool)

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) Set

func (cy *Cylinder) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.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) SetColor

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

SetColor sets the [Cylinder.Color]

func (*Cylinder) SetDynamic

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

SetDynamic sets the [Cylinder.Dynamic]

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

func (*Cylinder) SetTrans

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

SetTrans sets the [Cylinder.Trans]

func (*Cylinder) Sizes

func (cy *Cylinder) Sizes() (nVtx, nIdx int, hasColor bool)

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 DirLight

type DirLight struct {
	LightBase

	// position of direct light -- assumed to point at the origin so this determines direction
	Pos mat32.Vec3
}

DirLight 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 NewDirLight

func NewDirLight(sc *Scene, name string, lumens float32, color LightColors) *DirLight

NewDirLight 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 (*DirLight) ViewDir

func (dl *DirLight) ViewDir(viewMat *mat32.Mat4) mat32.Vec3

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

type GenMesh

type GenMesh struct {
	MeshBase
	Vtx  mat32.ArrayF32
	Norm mat32.ArrayF32
	Tex  mat32.ArrayF32
	Clr  mat32.ArrayF32
	Idx  mat32.ArrayU32
}

GenMesh is a generic, arbitrary Mesh, storing its values

func (*GenMesh) Set

func (ms *GenMesh) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.ArrayU32)

func (*GenMesh) Sizes

func (ms *GenMesh) Sizes() (nVtx, nIdx int, hasColor bool)

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 ki.Ki, name string, st, ed mat32.Vec3, 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(par ki.Ki, name ...string) *Group

NewGroup adds a new Group with the given name to the given parent. If the name is unspecified, it defaults to the ID (kebab-case) name of the type, plus the ki.Ki.NumLifetimeChildren of the given parent.

func NewLineBox

func NewLineBox(sc *Scene, parent ki.Ki, meshNm, boxNm string, bbox mat32.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) CopyFieldsFrom

func (gp *Group) CopyFieldsFrom(frm any)

func (*Group) Defaults

func (gp *Group) Defaults()

func (*Group) KiType

func (t *Group) KiType() *gti.Type

KiType returns the *gti.Type of Group

func (*Group) New

func (t *Group) New() ki.Ki

New returns a new *Group value

func (*Group) RaySolidIntersections

func (gp *Group) RaySolidIntersections(ray mat32.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 {
	// Name returns name of the light -- lights are accessed by name
	Name() string

	// Color returns color of light
	Color() color.RGBA

	// Lumens returns brightness of light
	Lumens() float32
}

Light represents a light that illuminates a scene these are stored on the Scene object and not within the graph

type LightBase

type LightBase struct {

	// name of light -- lights accessed by name so it matters
	Nm string

	// whether light is on or off
	On bool

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

	// color of light a full intensity
	Clr color.RGBA
}

LightBase provides the base implementation for Light interface

func (*LightBase) Color

func (lb *LightBase) Color() color.RGBA

func (*LightBase) Lumens

func (lb *LightBase) Lumens() float32

func (*LightBase) Name

func (lb *LightBase) Name() string

Name returns name of the light -- lights are accessed by name

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) IsValid

func (i LightColors) IsValid() bool

IsValid returns whether the value is a valid option for type LightColors.

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 []mat32.Vec3

	// line width, Y = height perpendicular to line direction, and X = depth
	Width mat32.Vec2

	// 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 mat32.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 []mat32.Vec3, width mat32.Vec2, 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) Set

func (ln *Lines) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.ArrayU32)

func (*Lines) Sizes

func (ln *Lines) Sizes() (nVtx, nIdx int, hasColor bool)

type Material

type Material struct {

	// 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
	Color color.RGBA

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

	// 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.
	Shiny float32

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

	// 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
	Bright float32

	// prop: texture = texture to provide color for the surface
	Texture TexName `set:"-"`

	// texture tiling parameters -- repeat and offset
	Tiling Tiling `view:"inline" viewif:"Texture!=''"`

	// prop: cull-back = cull the back-facing surfaces
	CullBack bool

	// prop: cull-front = cull the front-facing surfaces
	CullFront bool

	// pointer to texture
	TexPtr Texture `set:"-" view:"-"`
}

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) Render

func (mt *Material) Render(sc *Scene)

func (*Material) SetBright

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

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 (*Material) SetColor

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

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 (*Material) SetCullBack

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

SetCullBack sets the [Material.CullBack]: prop: cull-back = cull the back-facing surfaces

func (*Material) SetCullFront

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

SetCullFront sets the [Material.CullFront]: prop: cull-front = cull the front-facing surfaces

func (*Material) SetEmissive

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

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 (*Material) SetReflective

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

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 (*Material) SetShiny

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

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 (*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 Tiling) *Material

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

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 {
	// Name returns name of the mesh
	Name() string

	// SetName sets the name of the mesh
	SetName(nm string)

	// AsMeshBase returns the MeshBase for this Mesh
	AsMeshBase() *MeshBase

	// Sizes returns the number of vertex and index elements required for this mesh
	// including a bool representing whether it has per-vertex color.
	Sizes() (nVtx, nIdx int, hasColor bool)

	// Set sets the mesh points into given arrays, which have been allocated
	// according to the Sizes() returned by this Mesh.
	// The mesh is automatically marked with SetMod so that does not need to be done here.
	Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.ArrayU32)

	// Update updates the mesh points into given arrays, which have previously
	// been set with SetVerticies -- this can optimize by only updating whatever might
	// need to be updated for dynamically changing meshes.
	// You must call SetMod if the mesh was actually updated at this point.
	Update(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.ArrayU32)

	// SetMod flags that the mesh data has been modified and will be sync'd
	// at next sync of the Scene.Phong render system.
	SetMod(sc *Scene)

	// ComputeNorms automatically computes the normals from existing vertex data
	ComputeNorms(pos, norm mat32.ArrayF32)

	// HasColor returns true if this mesh has vertex-specific colors available
	HasColor() bool

	// IsTransparent returns true if this mesh has vertex-specific colors available
	// and at least some are transparent.
	IsTransparent() bool
}

Mesh parameterizes the mesh-based shape used for rendering a Solid. Only indexed triangle meshes are supported. All Mesh's must know in advance the number of vertex and index points they require, and the SetVerticies method operates on data from the vgpu staging buffer to set the relevant data post-allocation. The vgpu vshape library is used for all basic shapes, and it follows this same logic. Per-vertex Color is optional, as is the ability to update the data after initial SetVerticies call (default is to do nothing).

type MeshBase

type MeshBase struct {

	// name of mesh -- meshes are linked to Solids by name so this matters
	Nm string `set:"-"`

	// number of vertex points, as mat32.Vec3 -- always includes mat32.Vec3 normals and mat32.Vec2 texture coordinates -- only valid after Sizes() has been called
	NVtx int `set:"-"`

	// number of indexes, as mat32.ArrayU32 -- only valid after Sizes() has been called
	NIdx int `set:"-"`

	// has per-vertex colors, as mat32.Vec4 per vertex
	Color bool

	// if true, this mesh changes frequently -- otherwise considered to be static
	Dynamic bool

	// set to true if color has transparency -- not worth checking manually
	Trans bool

	// computed bounding-box and other gross solid properties
	BBox BBox `set:"-"`

	// mutex on bbox access
	BBoxMu sync.RWMutex `view:"-" copy:"-" json:"-" xml:"-" set:"-"`
}

MeshBase provides the core implementation of Mesh interface

func (*MeshBase) AsMeshBase

func (ms *MeshBase) AsMeshBase() *MeshBase

func (*MeshBase) ComputeNorms

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

todo!!

func (*MeshBase) HasColor

func (ms *MeshBase) HasColor() bool

func (*MeshBase) IsTransparent

func (ms *MeshBase) IsTransparent() bool

func (*MeshBase) Name

func (ms *MeshBase) Name() string

func (*MeshBase) SetColor

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

SetColor sets the [MeshBase.Color]: has per-vertex colors, as mat32.Vec4 per vertex

func (*MeshBase) SetDynamic

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

SetDynamic sets the [MeshBase.Dynamic]: if true, this mesh changes frequently -- otherwise considered to be static

func (*MeshBase) SetMod

func (ms *MeshBase) SetMod(sc *Scene)

func (*MeshBase) SetName

func (ms *MeshBase) SetName(nm string)

func (*MeshBase) SetTrans

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

SetTrans sets the [MeshBase.Trans]: set to true if color has transparency -- not worth checking manually

func (*MeshBase) Sizes

func (ms *MeshBase) Sizes() (nVtx, nIdx int, hasColor bool)

func (*MeshBase) Update

func (ms *MeshBase) Update(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.ArrayU32)

type MeshName

type MeshName string

MeshName is a mesh name -- provides an automatic gui chooser for meshes. Used on Solid to link to meshes by name.

type Node

type Node interface {
	ki.Ki

	// IsSolid returns true if this is an Solid node (else a Group)
	IsSolid() bool

	// AsNode3D returns a generic NodeBase for our node -- gives generic
	// access to all the base-level data structures without requiring
	// interface methods.
	AsNode() *NodeBase

	// AsSolid returns a node as 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
	// This sets the WorldMatrixUpdated flag but does not check that flag -- calling
	// routine can optionally do so.
	UpdateWorldMatrix(parWorld *mat32.Mat4)

	// UpdateMVPMatrix updates this node's MVP matrix based on
	// given view and prjn matrix from camera.
	// Called during rendering.
	UpdateMVPMatrix(viewMat, prjnMat *mat32.Mat4)

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

	// UpdateBBox2D updates this node's 2D bounding-box information based on scene
	// size and other scene bbox info from scene
	UpdateBBox2D(size mat32.Vec2)

	// 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).
	RayPick(pos image.Point) mat32.Ray

	// WorldMatrix returns the world matrix for this node, under read-lock protection.
	WorldMatrix() *mat32.Mat4

	// NormDCBBox returns the normalized display coordinates bounding box
	// which is used for clipping.  This is read-lock protected.
	NormDCBBox() mat32.Box3

	// 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()

	// UpdateNode does arbitrary node updating during render process
	UpdateNode()

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

	// Render is called by Scene Render on main thread,
	// everything ready to go..
	Render()

	// SetPosePos sets Pose.Pos position to given value, under write lock protection
	SetPosePos(pos mat32.Vec3)

	// SetPoseScale sets Pose.Scale scale to given value, under write lock protection
	SetPoseScale(scale mat32.Vec3)

	// SetPoseQuat sets Pose.Quat to given value, under write lock protection
	SetPoseQuat(quat mat32.Quat)
}

Node is the common interface for all xyz scenegraph nodes

func NodesUnderPoint added in v0.5.18

func NodesUnderPoint(n ki.Ki, 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 {
	ki.Node

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

	// Sc is the cached Scene
	Sc *Scene `set:"-"`

	// mutex on pose access -- needed for parallel updating
	PoseMu sync.RWMutex `view:"-" copy:"-" json:"-" xml:"-"  set:"-"`

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

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

	// normalized display coordinates bounding box, used for frustrum clipping
	NDCBBox mat32.Box3 `edit:"-" copy:"-" 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:"-" copy:"-" json:"-" xml:"-" set:"-"`

	// 2D bounding box for region occupied within Scene Frame that we render onto.
	// This is BBox intersected with Frame bounds.
	ScBBox image.Rectangle `edit:"-" copy:"-" json:"-" xml:"-" set:"-"`
}

NodeBase is the basic 3D scenegraph node, which has the full transform information relative to parent, and computed bounding boxes, etc. There are only two different kinds of Nodes: Group and Solid

func AsNodeBase

func AsNodeBase(k ki.Ki) *NodeBase

AsNodeBase converts Ki to a *NodeBase -- use when known to be at least of this type, not-nil, etc

func NewNodeBase

func NewNodeBase(par ki.Ki, name ...string) *NodeBase

NewNodeBase adds a new NodeBase with the given name to the given parent. If the name is unspecified, it defaults to the ID (kebab-case) name of the type, plus the ki.Ki.NumLifetimeChildren of the given parent.

func (*NodeBase) AsNode

func (nb *NodeBase) AsNode() *NodeBase

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

func (*NodeBase) AsSolid

func (nb *NodeBase) AsSolid() *Solid

func (*NodeBase) BaseIface

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

func (*NodeBase) Config

func (nb *NodeBase) Config()

func (*NodeBase) CopyFieldsFrom

func (nb *NodeBase) CopyFieldsFrom(frm any)

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) KiType

func (t *NodeBase) KiType() *gti.Type

KiType returns the *gti.Type of NodeBase

func (*NodeBase) New

func (t *NodeBase) New() ki.Ki

New returns a new *NodeBase value

func (*NodeBase) NormDCBBox

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

NormDCBBox returns the normalized display coordinates bounding box which is used for clipping. This is read-lock protected.

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) RayPick

func (nb *NodeBase) RayPick(pos image.Point) mat32.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()

func (*NodeBase) SetPosePos

func (nb *NodeBase) SetPosePos(pos mat32.Vec3)

SetPosePos sets Pose.Pos position to given value, under write lock protection

func (*NodeBase) SetPoseQuat

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

SetPoseQuat sets Pose.Quat to given value, under write lock protection

func (*NodeBase) SetPoseScale

func (nb *NodeBase) SetPoseScale(scale mat32.Vec3)

SetPoseScale sets Pose.Scale scale to given value, under write lock protection

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 SpotLight, copies entire Pose. Does not work for Ambient light which has no position information.

func (*NodeBase) UpdateBBox2D

func (nb *NodeBase) UpdateBBox2D(size mat32.Vec2)

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

func (*NodeBase) UpdateEnd

func (nb *NodeBase) UpdateEnd(updt bool)

UpdateEnd resets the scene ScUpdating flag

func (*NodeBase) UpdateMVPMatrix

func (nb *NodeBase) UpdateMVPMatrix(viewMat, prjnMat *mat32.Mat4)

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

func (*NodeBase) UpdateNode

func (nb *NodeBase) UpdateNode()

func (*NodeBase) UpdateStart

func (nb *NodeBase) UpdateStart() bool

UpdateStart sets the scene ScUpdating flag to prevent render updates during construction on a scene.

func (*NodeBase) UpdateWorldMatrix

func (nb *NodeBase) UpdateWorldMatrix(parWorld *mat32.Mat4)

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. This sets the WorldMatrixUpdated flag but does not check that flag -- calling routine can optionally do so.

func (*NodeBase) Validate

func (nb *NodeBase) Validate() error

func (*NodeBase) WorldMatrix

func (nb *NodeBase) WorldMatrix() *mat32.Mat4

WorldMatrix returns the world matrix for this node, under read lock protection

type NodeFlags

type NodeFlags ki.Flags //enums:bitflag

NodeFlags extend ki.Flags to hold 3D node state

const (
	// WorldMatrixUpdated means that the Pose.WorldMatrix has been updated
	WorldMatrixUpdated NodeFlags = NodeFlags(ki.FlagsN) + iota

	// VectorsUpdated means that the rendering vectors information is updated
	VectorsUpdated

	// Invisible marks this node as invisible
	Invisible
)
const NodeFlagsN NodeFlags = 10

NodeFlagsN is the highest valid value for type NodeFlags, plus one.

func NodeFlagsValues

func NodeFlagsValues() []NodeFlags

NodeFlagsValues returns all possible values for the type NodeFlags.

func (NodeFlags) BitIndexString

func (i NodeFlags) BitIndexString() string

BitIndexString returns the string representation of this NodeFlags value if it is a bit index value (typically an enum constant), and not an actual bit flag value.

func (NodeFlags) Desc

func (i NodeFlags) Desc() string

Desc returns the description of the NodeFlags value.

func (NodeFlags) HasFlag

func (i NodeFlags) HasFlag(f enums.BitFlag) bool

HasFlag returns whether these bit flags have the given bit flag set.

func (NodeFlags) Int64

func (i NodeFlags) Int64() int64

Int64 returns the NodeFlags value as an int64.

func (NodeFlags) IsValid

func (i NodeFlags) IsValid() bool

IsValid returns whether the value is a valid option for type NodeFlags.

func (NodeFlags) MarshalText

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

MarshalText implements the encoding.TextMarshaler interface.

func (*NodeFlags) SetFlag

func (i *NodeFlags) SetFlag(on bool, f ...enums.BitFlag)

SetFlag sets the value of the given flags in these flags to the given value.

func (*NodeFlags) SetInt64

func (i *NodeFlags) SetInt64(in int64)

SetInt64 sets the NodeFlags value from an int64.

func (*NodeFlags) SetString

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

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

func (*NodeFlags) SetStringOr

func (i *NodeFlags) SetStringOr(s string) error

SetStringOr sets the NodeFlags value from its string representation while preserving any bit flags already set, and returns an error if the string is invalid.

func (NodeFlags) String

func (i NodeFlags) String() string

String returns the string representation of this NodeFlags value.

func (*NodeFlags) UnmarshalText

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

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (NodeFlags) Values

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

Values returns all possible values for the type NodeFlags.

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 NormNeg for whether it is facing in the positive or negative of the given axis.
	NormAxis mat32.Dims

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

	// 2D size of plane
	Size mat32.Vec2

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

	// 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) Set

func (pl *Plane) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.ArrayU32)

func (*Plane) SetColor

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

SetColor sets the [Plane.Color]

func (*Plane) SetDynamic

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

SetDynamic sets the [Plane.Dynamic]

func (*Plane) SetNormAxis

func (t *Plane) SetNormAxis(v mat32.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 NormNeg for whether it is facing in the positive or negative of the given axis.

func (*Plane) SetNormNeg

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

SetNormNeg sets the [Plane.NormNeg]: 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 mat32.Vec2i) *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 mat32.Vec2) *Plane

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

func (*Plane) SetTrans

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

SetTrans sets the [Plane.Trans]

func (*Plane) Sizes

func (pl *Plane) Sizes() (nVtx, nIdx int, hasColor bool)

type PointLight

type PointLight struct {
	LightBase

	// position of light in world coordinates
	Pos mat32.Vec3

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

	// Distance quadratic decay factor -- defaults to .01 -- dominates at longer distances
	QuadDecay float32
}

PointLight 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 NewPointLight

func NewPointLight(sc *Scene, name string, lumens float32, color LightColors) *PointLight

NewPointLight 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 (*PointLight) ViewPos

func (pl *PointLight) ViewPos(viewMat *mat32.Mat4) mat32.Vec3

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

type Pose

type Pose struct {

	// position of center of element (relative to parent)
	Pos mat32.Vec3

	// scale (relative to parent)
	Scale mat32.Vec3

	// Node rotation specified as a Quat (relative to parent)
	Quat mat32.Quat

	// Local matrix. Contains all position/rotation/scale information (relative to parent)
	Matrix mat32.Mat4 `view:"-"`

	// Parent's world matrix -- we cache this so that we can independently update our own matrix
	ParMatrix mat32.Mat4 `view:"-"`

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

	// model * view matrix -- tranforms into camera-centered coords
	MVMatrix mat32.Mat4 `view:"-"`

	// model * view * projection matrix -- full final render matrix
	MVPMatrix mat32.Mat4 `view:"-"`

	// normal matrix has no offsets, for normal vector rotation only, based on MVMatrix
	NormMatrix mat32.Mat3 `view:"-"`
}

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() mat32.Vec3

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

func (*Pose) EulerRotationRad

func (ps *Pose) EulerRotationRad() mat32.Vec3

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 mat32.Vec3)

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 *mat32.Mat4)

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) SetMatrix

func (ps *Pose) SetMatrix(m *mat32.Mat4)

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

func (*Pose) String added in v0.5.18

func (ps *Pose) String() string

func (*Pose) UpdateMVPMatrix

func (ps *Pose) UpdateMVPMatrix(viewMat, prjnMat *mat32.Mat4)

UpdateMVPMatrix updates the model * view, * projection matricies based on camera view, prjn 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 *mat32.Mat4)

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() mat32.Vec3

WorldEulerRotation returns the current world rotation in Euler angles.

func (*Pose) WorldPos

func (ps *Pose) WorldPos() mat32.Vec3

WorldPos returns the current world position.

func (*Pose) WorldQuat

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

WorldQuat returns the current world quaternion.

func (*Pose) WorldScale

func (ps *Pose) WorldScale() mat32.Vec3

WorldScale returns he current world scale.

type RenderClasses

type RenderClasses int32 //enums:enum -trimprefix 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) IsValid

func (i RenderClasses) IsValid() bool

IsValid returns whether the value is a valid option for type RenderClasses.

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 ScFlags

type ScFlags ki.Flags //enums:bitflag

ScFlags has critical state information signaling when rendering, updating, or config needs to be done

const (
	// ScUpdating means scene is in the process of updating:
	// set for any kind of tree-level update.
	// skip any further update passes until it goes off.
	ScUpdating ScFlags = ScFlags(ki.FlagsN) + iota

	// ScNeedsConfig means that a GPU resource (Lights, Texture, Meshes,
	// or more complex Nodes that require ConfigNodes) has been changed
	// and a Config call is required.
	ScNeedsConfig

	// ScNeedsUpdate means that Node Pose has changed and an update pass
	// is required to update matrix and bounding boxes.
	ScNeedsUpdate

	// ScNeedsRender means that something has been updated (minimally the
	// Camera pose) and a new Render is required.
	ScNeedsRender
)
const ScFlagsN ScFlags = 11

ScFlagsN is the highest valid value for type ScFlags, plus one.

func ScFlagsValues

func ScFlagsValues() []ScFlags

ScFlagsValues returns all possible values for the type ScFlags.

func (ScFlags) BitIndexString

func (i ScFlags) BitIndexString() string

BitIndexString returns the string representation of this ScFlags value if it is a bit index value (typically an enum constant), and not an actual bit flag value.

func (ScFlags) Desc

func (i ScFlags) Desc() string

Desc returns the description of the ScFlags value.

func (ScFlags) HasFlag

func (i ScFlags) HasFlag(f enums.BitFlag) bool

HasFlag returns whether these bit flags have the given bit flag set.

func (ScFlags) Int64

func (i ScFlags) Int64() int64

Int64 returns the ScFlags value as an int64.

func (ScFlags) IsValid

func (i ScFlags) IsValid() bool

IsValid returns whether the value is a valid option for type ScFlags.

func (ScFlags) MarshalText

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

MarshalText implements the encoding.TextMarshaler interface.

func (*ScFlags) SetFlag

func (i *ScFlags) SetFlag(on bool, f ...enums.BitFlag)

SetFlag sets the value of the given flags in these flags to the given value.

func (*ScFlags) SetInt64

func (i *ScFlags) SetInt64(in int64)

SetInt64 sets the ScFlags value from an int64.

func (*ScFlags) SetString

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

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

func (*ScFlags) SetStringOr

func (i *ScFlags) SetStringOr(s string) error

SetStringOr sets the ScFlags value from its string representation while preserving any bit flags already set, and returns an error if the string is invalid.

func (ScFlags) String

func (i ScFlags) String() string

String returns the string representation of this ScFlags value.

func (*ScFlags) UnmarshalText

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

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (ScFlags) Values

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

Values returns all possible values for the type ScFlags.

type Scene

type Scene struct {
	ki.Node

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

	// number of samples in multisampling -- must be a power of 2, and must be 1 if grabbing the Depth buffer back from the RenderFrame
	MultiSample int `def:"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)
	Wireframe bool `def:"false"`

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

	// background color
	BackgroundColor color.RGBA

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

	// meshes -- holds all the mesh data -- must be configured prior to rendering
	Meshes ordmap.Map[string, Mesh] `set:"-"`

	// textures -- must be configured prior to rendering -- a maximum of 16 textures is supported for full cross-platform portability
	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:"-"`

	// has dragging cursor been set yet?
	SetDragCursor bool `view:"-" set:"-"`

	// the vphong rendering system
	Phong vphong.Phong `set:"-"`

	// the vgpu render frame holding the rendered scene
	Frame *vgpu.RenderFrame `set:"-"`

	// image used to hold a copy of the Frame image, for ImageCopy() call.
	// This is re-used across calls to avoid large memory allocations,
	// so it will automatically update after every ImageCopy call.
	// If a persistent image is required, call [glop/images.CloneAsRGBA].
	ImgCopy image.RGBA `set:"-"`

	// index in list of window direct uploading images
	DirUpIdx int `set:"-"`

	// mutex on rendering
	RenderMu sync.Mutex `view:"-" copy:"-" json:"-" xml:"-" set:"-"`
}

Scene is the overall scenegraph containing nodes as children. It renders to its own vgpu.RenderFrame. The Image of this Frame is usable directly or, via xyzv.Scene, where it is copied into an overall gi.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 AsScene

func AsScene(k ki.Ki) *Scene

AsScene returns the given value as a value of type Scene if the type of the given value embeds Scene, or nil otherwise

func NewScene

func NewScene(name ...string) *Scene

NewScene creates a new Scene to contain a 3D scenegraph.

func (*Scene) AddFmLibrary

func (sc *Scene) AddFmLibrary(nm string, parent ki.Ki) (*Group, error)

AddFmLibrary 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) AddMesh

func (sc *Scene) AddMesh(ms Mesh)

AddMesh adds given mesh to mesh collection. Any existing mesh of the same name is deleted. see NewX for convenience methods to add specific shapes

func (*Scene) AddMeshUnique

func (sc *Scene) AddMeshUnique(ms Mesh)

AddMeshUniqe adds given mesh to mesh collection, ensuring that it has a unique name if one already exists.

func (*Scene) AddTexture

func (sc *Scene) AddTexture(tx Texture)

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

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) AsScene

func (t *Scene) AsScene() *Scene

AsScene satisfies the SceneEmbedder interface

func (*Scene) Config

func (sc *Scene) Config()

Config configures the Scene to prepare for rendering. The Frame should already have been configured. This includes the Phong system and frame. It must be called before the first render, or after any change in the lights, meshes, textures, or any changes to the nodes that require Config updates. This must be called on the main thread.

func (*Scene) ConfigFrame

func (sc *Scene) ConfigFrame(gpu *vgpu.GPU, dev *vgpu.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 *vgpu.Surface)

ConfigFrameFromSurface configures framebuffer for GPU rendering Using GPU and Device from given vgpu.Surface

func (*Scene) ConfigLights

func (sc *Scene) ConfigLights()

ConfigLights configures 3D rendering for current lights

func (*Scene) ConfigMeshes

func (sc *Scene) ConfigMeshes()

ConfigMeshes configures meshes for rendering must be called after adding or deleting any meshes or altering the number of verticies.

func (*Scene) ConfigMeshesTextures

func (sc *Scene) ConfigMeshesTextures()

ConfigMeshesTextures configures the meshes and the textures to the Phong rendering system. Called by ConfigRender -- can be called separately if just these elements are updated -- see also ReconfigMeshes and ReconfigTextures

func (*Scene) ConfigNodes

func (sc *Scene) ConfigNodes()

ConfigNodes runs Config on all nodes

func (*Scene) ConfigTextures

func (sc *Scene) ConfigTextures()

must be called after adding or deleting any meshes or altering the number of verticies.

func (*Scene) Defaults

func (sc *Scene) Defaults()

Defaults sets default scene params (camera, bg = white)

func (*Scene) DeleteMesh

func (sc *Scene) DeleteMesh(nm string)

DeleteMesh removes given mesh -- returns error if mesh not found.

func (*Scene) DeleteMeshes

func (sc *Scene) DeleteMeshes()

DeleteMeshes removes all meshes

func (*Scene) DeleteTexture

func (sc *Scene) DeleteTexture(nm string)

DeleteTexture deletes texture of given name -- returns error if not found must call ConfigTextures or Config to reset after deleting

func (*Scene) DeleteTextures

func (sc *Scene) DeleteTextures()

DeleteTextures removes all textures must call ConfigTextures or Config to reset after deleting

func (*Scene) DeleteUnusedMeshes

func (sc *Scene) DeleteUnusedMeshes()

DeleteUnusedMeshes deletes all unused meshes

func (*Scene) DepthImage added in v0.5.18

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 ScUpdating is set, then an update is in progress and false is returned. If no updates are required, then false is also returned, else true. ScNeedsConfig is NOT handled here because it must be done on main thread, so this must be checked separately (e.g., in xyzv.Scene, as it requires a separate RunOnMainThread call).

func (*Scene) Image

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

Image returns the current rendered image from the Frame RenderFrame. 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 RenderFrame. 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 glop/images.CloneAsRGBA.

func (*Scene) ImageDone

func (sc *Scene) ImageDone()

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

func (*Scene) IsConfiged

func (sc *Scene) IsConfiged() bool

IsConfiged Returns true if the scene has already been configured

func (*Scene) KeyChordEvent

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

func (*Scene) KiType

func (t *Scene) KiType() *gti.Type

KiType returns the *gti.Type of Scene

func (*Scene) MeshByName

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

MeshByName looks for mesh by name -- returns nil if not found

func (*Scene) MeshByNameTry

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

MeshByNameTry looks for mesh by name -- returns 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) New

func (t *Scene) New() ki.Ki

New returns a new *Scene value

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 ki.Ki) (*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 ki.Ki) (*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) ReconfigMeshes

func (sc *Scene) ReconfigMeshes()

ReconfigMeshes reconfigures meshes on the Phong renderer if there has been any change to the mesh structure. Config does a full configure of everything -- this is optimized just for mesh changes.

func (*Scene) ReconfigTextures

func (sc *Scene) ReconfigTextures()

ReconfigTextures reconfigures textures on the Phong renderer if there has been a change to the mesh structure Config does a full configure of everything -- this is optimized just for texture changes.

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) 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) SetBackgroundColor

func (t *Scene) SetBackgroundColor(v color.RGBA) *Scene

SetBackgroundColor sets the [Scene.BackgroundColor]: background color

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) SetMeshes

func (sc *Scene) SetMeshes()

SetMeshes sets the meshes after config

func (*Scene) SetMultiSample

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

SetMultiSample sets the [Scene.MultiSample]: number of samples in multisampling -- must be a power of 2, and must be 1 if grabbing the Depth buffer back from the RenderFrame

func (*Scene) SetNeedsConfig

func (sc *Scene) SetNeedsConfig()

func (*Scene) SetNeedsRender

func (sc *Scene) SetNeedsRender()

func (*Scene) SetNeedsUpdate

func (sc *Scene) SetNeedsUpdate()

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

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)

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

TextureByName looks for texture by name -- returns nil if not found

func (*Scene) TextureByNameTry

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

TextureByNameTry looks for texture by name -- returns 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 and re-render

func (*Scene) UpdateEnd

func (sc *Scene) UpdateEnd(updt bool)

UpdateEnd resets the scene ScUpdating flag if updt = true

func (*Scene) UpdateEndConfig

func (sc *Scene) UpdateEndConfig(updt bool)

UpdateEndConfig resets the scene ScUpdating flag if updt = true and sets the ScNeedsConfig flag; updt is from UpdateStart(). Config is for Texture, Lighting Meshes or more complex nodes).

func (*Scene) UpdateEndRender

func (sc *Scene) UpdateEndRender(updt bool)

UpdateEndRender resets the scene ScUpdating flag if updt = true and sets the ScNeedsRender flag; updt is from UpdateStart(). Render only updates based on camera changes, not any node-level changes. See [UpdateEndUpdate].

func (*Scene) UpdateEndUpdate

func (sc *Scene) UpdateEndUpdate(updt bool)

UpdateEndUpdate resets the scene ScUpdating flag if updt = true and sets the ScNeedsUpdate flag; updt is from UpdateStart(). Update is for when any node Pose or material changes happen. See [UpdateEndConfig] for major changes.

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) UpdateMeshes

func (sc *Scene) UpdateMeshes()

UpdateMeshes iterates over meshes and calls their Update method each mesh Update method must call SetMod to trigger the update

func (*Scene) UpdateNodes

func (sc *Scene) UpdateNodes()

func (*Scene) UpdateNodesIfNeeded added in v0.5.18

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) UpdateStart

func (sc *Scene) UpdateStart() bool

UpdateStart sets the scene ScUpdating flag to prevent render updates during construction on a scene. if already updating, returns false. Pass the result to UpdateEnd* methods.

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 SceneEmbedder

type SceneEmbedder interface {
	AsScene() *Scene
}

SceneEmbedder is an interface that all types that embed Scene satisfy

type Solid

type Solid struct {
	NodeBase

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

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

	// cached pointer to mesh
	MeshPtr Mesh `view:"-" 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 ki.Ki, name string, st, ed mat32.Vec3, 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(par ki.Ki, name ...string) *Solid

NewSolid adds a new Solid with the given name to the given parent. If the name is unspecified, it defaults to the ID (kebab-case) name of the type, plus the ki.Ki.NumLifetimeChildren of the given parent.

func (*Solid) AsSolid

func (sld *Solid) AsSolid() *Solid

func (*Solid) Config

func (sld *Solid) Config()

func (*Solid) CopyFieldsFrom

func (sld *Solid) CopyFieldsFrom(frm any)

func (*Solid) Defaults

func (sld *Solid) Defaults()

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

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) KiType

func (t *Solid) KiType() *gti.Type

KiType returns the *gti.Type of Solid

func (*Solid) New

func (t *Solid) New() ki.Ki

New returns a new *Solid value

func (*Solid) OnInit

func (sld *Solid) OnInit()

func (*Solid) ParentMaterial

func (sld *Solid) ParentMaterial() *Material

ParentMaterial returns parent's material or nil if not avail

func (*Solid) Render

func (sld *Solid) Render()

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) SetMat

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

SetMat sets the [Solid.Mat]: 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 mat32.Vec3
}

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) Set

func (sp *Sphere) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.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) SetColor

func (t *Sphere) SetColor(v bool) *Sphere

SetColor sets the [Sphere.Color]

func (*Sphere) SetDynamic

func (t *Sphere) SetDynamic(v bool) *Sphere

SetDynamic sets the [Sphere.Dynamic]

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) SetTrans

func (t *Sphere) SetTrans(v bool) *Sphere

SetTrans sets the [Sphere.Trans]

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)

func (*Sphere) Sizes

func (sp *Sphere) Sizes() (nVtx, nIdx int, hasColor bool)

type SpotLight

type SpotLight 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 NewSpotLight

func NewSpotLight(sc *Scene, name string, lumens float32, color LightColors) *SpotLight

NewSpotLight 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 (*SpotLight) LookAt

func (sl *SpotLight) LookAt(target, upDir mat32.Vec3)

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

func (*SpotLight) LookAtOrigin

func (sl *SpotLight) LookAtOrigin()

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

func (*SpotLight) ViewDir

func (sl *SpotLight) ViewDir() mat32.Vec3

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

type TexName

type TexName string

TexName provides a GUI interface for choosing textures

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
	TxtPos mat32.Vec2 `set:"-" xml:"-" json:"-"`

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

	// render state for rendering text
	RenderState paint.State `set:"-" copy:"-" json:"-" xml:"-" view:"-"`
}

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(par ki.Ki, name ...string) *Text2D

NewText2D adds a new Text2D with the given name to the given parent. If the name is unspecified, it defaults to the ID (kebab-case) name of the type, plus the ki.Ki.NumLifetimeChildren of the given parent.

func (*Text2D) Config

func (txt *Text2D) Config()

func (*Text2D) Defaults

func (txt *Text2D) Defaults()

func (*Text2D) IsTransparent

func (txt *Text2D) IsTransparent() bool

func (*Text2D) KiType

func (t *Text2D) KiType() *gti.Type

KiType returns the *gti.Type of Text2D

func (*Text2D) New

func (t *Text2D) New() ki.Ki

New returns a new *Text2D value

func (*Text2D) OnInit

func (txt *Text2D) OnInit()

func (*Text2D) RenderClass

func (txt *Text2D) RenderClass() RenderClasses

func (*Text2D) RenderText

func (txt *Text2D) RenderText()

func (*Text2D) SetMat

func (t *Text2D) SetMat(v Material) *Text2D

SetMat sets the [Text2D.Mat]

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() (mat32.Vec2, 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 *mat32.Mat4)

func (*Text2D) Validate

func (txt *Text2D) Validate() error

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

type Texture

type Texture interface {
	// Name returns name of the texture
	Name() string

	// IsTransparent returns true if there is any transparency present in the texture
	// This is not auto-detected but rather must be set manually.
	// It affects the rendering order -- transparent items are rendered last.
	IsTransparent() bool

	// SetTransparent sets the transparency flag for this texture.
	SetTransparent(trans bool)

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

	// SetImage sets image for the texture
	SetImage(img image.Image)
}

Texture is the interface for all textures

type TextureBase

type TextureBase struct {

	// name of the texture -- textures are connected to material by name
	Nm string

	// set to true if texture has transparency
	Trans bool

	// cached image
	Img *image.RGBA
}

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

func (*TextureBase) Image

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

func (*TextureBase) IsTransparent

func (tx *TextureBase) IsTransparent() bool

func (*TextureBase) Name

func (tx *TextureBase) Name() string

func (*TextureBase) SetImage

func (tx *TextureBase) SetImage(img image.Image)

func (*TextureBase) SetTransparent

func (tx *TextureBase) SetTransparent(trans bool)

type TextureFile

type TextureFile struct {
	TextureBase

	// filesystem for embedded etc
	FSys 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 TextureGi2D

type TextureGi2D struct {
	TextureBase
}

TextureGi2D is a dynamic texture material driven by a gi.Viewport2D viewport anything rendered to the viewport will be projected onto the surface of any solid using this texture.

type Tiling

type Tiling struct {

	// how often to repeat the texture in each direction
	Repeat mat32.Vec2

	// offset for when to start the texure in each direction
	Off mat32.Vec2
}

Tiling are the texture tiling parameters

func (*Tiling) Defaults

func (tl *Tiling) Defaults()

Defaults sets default tiling params if not yet initialized

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) Set

func (tr *Torus) Set(sc *Scene, vtxAry, normAry, texAry, clrAry mat32.ArrayF32, idxAry mat32.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) SetColor

func (t *Torus) SetColor(v bool) *Torus

SetColor sets the [Torus.Color]

func (*Torus) SetDynamic

func (t *Torus) SetDynamic(v bool) *Torus

SetDynamic sets the [Torus.Dynamic]

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) SetTrans

func (t *Torus) SetTrans(v bool) *Torus

SetTrans sets the [Torus.Trans]

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)

func (*Torus) Sizes

func (tr *Torus) Sizes() (nVtx, nIdx int, hasColor bool)

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).

Jump to

Keyboard shortcuts

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