Skip to content

Commit cb224d8

Browse files
authored
Merge pull request #1615 from cogentcore/xyzplan
xyzplan: fully support tree Plan logic in xyz
2 parents 93a086e + cedecae commit cb224d8

61 files changed

Lines changed: 1105 additions & 3269 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

core/events.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,11 @@ func (em *Events) startRepeatClickTimer() {
767767
if tree.IsNil(em.repeatClick) || !em.repeatClick.AsWidget().IsVisible() {
768768
return
769769
}
770-
em.repeatClick.AsWidget().Send(events.Click)
770+
// note: we are not in event loop here anymore!
771+
rw := em.repeatClick.AsWidget()
772+
rw.AsyncLock()
773+
rw.Send(events.Click)
774+
rw.AsyncUnlock()
771775
em.startRepeatClickTimer()
772776
})
773777
}

core/scene.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ func (sc *Scene) resize(geom math32.Geom2DInt) bool {
309309
sc.renderer.SetSize(units.UnitDot, sz)
310310
sc.SceneGeom.Size = geom.Size // make sure
311311

312-
sc.updateScene()
312+
// sc.updateScene() // note: doing this every resize can be very expensive, and is unnec in general. really you just need a layout.
313313
sc.applyStyleScene()
314314
// restart the multi-render updating after resize, to get windows to update correctly while
315315
// resizing on Windows (OS) and Linux (see https://github.com/cogentcore/core/issues/584),

docs/content/gpu.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ Name = "GPU"
33
Categories = ["Architecture"]
44
+++
55

6-
The [[doc:gpu]] package provides a higher-level interface to [WebGPU](https://www.w3.org/TR/webgpu/), which provides GPU (_graphical processing unit_) hardware-accelerated graphics and compute processing on both desktop and web platforms, using the same unified api.
6+
The [[doc:gpu]] package provides a higher-level interface to [WebGPU](https://www.w3.org/TR/webgpu/), which is available on all non-web platforms and is gaining wider browser support: [WebGPU](https://caniuse.com/webgpu).
7+
8+
The GPU (_graphical processing unit_) is a hardware-accelerated graphics and compute processor.
79

810
The `gpu` package manages all the details of WebGPU to provide a higher-level interface where you can specify the data variables and values, shader pipelines, and other parameters that tell the GPU what to do, without having to worry about all the lower-level implementational details. It maps directly onto the underlying WebGPU structure, and does not decrease performance in any way. It supports both graphics and compute functionality.
911

docs/content/xyz.md

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,147 @@
11
+++
22
Name = "XYZ"
3-
Categories = ["Widgets"]
3+
Categories = ["Architecture"]
44
+++
55

6-
**XYZ** is a [[widget]] for interactive 3D viewing and editing. 3D support is currently present on all platforms (with the exception of web browsers that do not support [WebGPU](https://caniuse.com/webgpu)), but the API is subject to change. More documentation will be written for xyz once the API is cleaned up. For now, you can see the API documentation for [[doc:xyz]], and the [xyz example](https://github.com/cogentcore/core/tree/main/examples/xyz).
6+
**xyz** is a package that supports interactive 3D viewing and editing, building on the [[GPU]] framework, which in turn is based on [WebGPU](https://www.w3.org/TR/webgpu/), which is available on all non-web platforms and is gaining wider browser support: [WebGPU](https://caniuse.com/webgpu). The full API documentation is at [[doc:xyz]], and the [xyz example](https://github.com/cogentcore/core/tree/main/examples/xyz) provides a good working example to start from.
77

88
Here is a screenshot of the xyz example:
99

1010
![Screenshot of the xyz example](media/xyz.jpg)
11+
12+
## Elements
13+
14+
### Solid
15+
16+
The [[doc:xyz.Solid]] type is the main 3D object that renders a visible shape. Its shape comes from a [[doc:xyz.Mesh]], which is a potentially shared element stored in a library and accessed by unique names. The other visible properties (e.g., `Color`, how `Shiny` or `Reflective` it is, etc) are defined by the [[doc:xyz.Material]] properties. It can also have a [[doc:xyz.Texture]] (also referenced by unique name from a shared library) that is an image providing a richer more realistic appearance.
17+
18+
The [[doc:xyz.Pose]] values on a Solid (and all other `xyz` nodes) specify the 3D position and orientation of the object.
19+
20+
### Scene
21+
22+
The 3D scenegraph and the shared `Mesh` and `Texture` libraries are managed by the [[doc:xyz.Scene]] node, along with the `Lights`, `Camera` and a `Library` of loaded 3D objects that can be referenced by name. The scene of objects is rooted in the `Children` of the Scene.
23+
24+
`Mesh` and `Texture` elements use the "Set / Reset" approach, where `Set` does add or update, based on unique name id, and if there are large changes and unused elements, a `Reset` can be used to start over. After the GPU is up and running (e.g., after the main app window is opened), changes take effect immediately, but everything can be configured prior to that, and they will all be applied when the GPU is activated.
25+
26+
### Group
27+
28+
The [[doc:xyz.Group]] is a container of other elements, and typically visible objects are actually Groups with multiple different subgroups and finally Solid elements. Groups are also used for optimizing the rendering, such that any Group that is fully out of view will be skipped over entirely: therefore, it is a good idea to create spatially-organized groups at different scales, depending on the overall scene size and complexity.
29+
30+
### Resources
31+
32+
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), e.g.,:
33+
34+
```go
35+
sphere := xyz.NewSphere(sc, "sphere", .75, 32)
36+
tree.AddChild(sc, func(n *xyz.Solid) {
37+
n.SetMesh(sphere).SetColor(colors.Orange).SetPos(0, -2, 0)
38+
})
39+
```
40+
41+
`Texture`s are loaded from Go image files, e.g.,:
42+
43+
```go
44+
grtx := xyz.NewTextureFileFS(assets.Content, sc, "ground", "ground.png")
45+
floorp := xyz.NewPlane(sc, "floor-plane", 100, 100)
46+
tree.AddChild(sc, func(n *xyz.Solid) {
47+
n.SetMesh(floorp).SetTexture(grtx).SetPos(0, -5, 0)
48+
n.Material.Tiling.Repeat.Set(40, 40)
49+
})
50+
```
51+
52+
The Scene also contains a `Library` of uniquely named "objects" (Groups) which can be loaded from 3D object files in the [Wavefront .obj format](https://en.wikipedia.org/wiki/Wavefront_.obj_file), and then added into the scenegraph as needed, e.g.:
53+
54+
```go
55+
lgo := errors.Log1(sc.OpenToLibraryFS(assets.Content, "gopher.obj", ""))
56+
tree.Add(p, func(n *xyz.Object) {
57+
n.SetObjectName("gopher").SetScale(.5, .5, .5).SetPos(1.4, -2.5, 0)
58+
n.SetAxisRotation(0, 1, 0, -60)
59+
})
60+
```
61+
62+
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.
63+
64+
## Lights
65+
66+
At least one light must be added to make everything in the scene visible. Four different types are supported.
67+
68+
The lights use [standard light types](http://planetpixelemporium.com/tutorialpages/light.html) via the [[doc:xyz.LightColors]] to specify the light color, e.g., `xyz.DirectSun` is the brightest pure white color.
69+
70+
The [[doc:xyz.Ambient]] light is the simplest, providing a diffuse uniform light that doesn't come from any given direction:
71+
72+
```go
73+
xyz.NewAmbient(sc, "ambient", 0.3, xyz.DirectSun)
74+
```
75+
76+
The [[doc:xyz.Directional]] light shines toward the origin (position 0,0,0) from wherever it is placed, and only the vector from this position to the origin matters: distance is not a factor:
77+
78+
```go
79+
xyz.NewDirectional(sc, "directional", 1, xyz.DirectSun).Pos.Set(0, 2, 1)
80+
```
81+
82+
The [[doc:xyz.Point]] light is like `Directional` except that it has decay factors as a function of distance:
83+
84+
```go
85+
xyz.NewPoint(sc, "point", 1, xyz.DirectSun).Pos.Set(-5, 0, 2)
86+
```
87+
88+
The [[doc:xyz.Spot]] light is the most complex, with an angular decay and a angular cutoff, light a classic desk lamp.
89+
90+
```go
91+
xyz.NewSpot(sc, "spot", 1, xyz.DirectSun).Pos.Set(-5, 0, 2)
92+
```
93+
94+
If you want a visible representation of the light in the Scene, you can add that using whatever Solid you want.
95+
96+
## Camera
97+
98+
The [[doc:xyz.Camera]] determines what view into the 3D scene is rendered, via its Pose parameters, e.g.,:
99+
100+
```go
101+
sc.Camera.Pose.Pos.Set(0, 2, 10)
102+
sc.Camera.LookAt(math32.Vector3{}, math32.Vec3(0, 1, 0)) // look at origin
103+
```
104+
105+
## xyzcore
106+
107+
The [[doc:xyz/xyzcore]] package provides two `core.Widget` wrappers around the `xyz.Scene`:
108+
109+
* [[doc:xyz/xyzcore.SceneEditor]] provides full object selection and manipulation functionality, and a toolbar of controls.
110+
111+
* [[doc:xyz/xyzcore.Scene]] just displays the scene, and supports mouse-based zooming and panning of the camera.
112+
113+
### Events
114+
115+
The GUI interactions are managed by functions such as [[doc:xyz.Scene.MouseScrollEvent]], [[doc:xyz.Scene.SlideMoveEvent]], and [[doc:xyz.Scene.NavKeyEvent]], which are connected to the core event management system in `xyzcore.Scene`.
116+
117+
There are also other helper functions in `xyz/events.go`.
118+
119+
## Updating, Making, Rendering, etc
120+
121+
xyz is based on the [[doc:tree]] infrastructure, documented in [[Plan]], for flexible ways of building and updating 3D scenes.
122+
123+
The `Update()` method on `Scene` (or any node) will update everything based on Maker and Updater functions that have been installed.
124+
125+
The `Render()` method on the Scene will render to a [[doc:gpu.RenderTexture]] that is an offscreen rendering target. Use `RenderGrabImage()` to get the resulting image as a Go image. The `xyzcore.Scene` automatically manages the updating and rendering consistent with the [[core]] standard mechanisms, using an optimized direct rendering logic so the resulting rendered image stays on the GPU and is used directly.
126+
127+
## Lines, arrows, etc
128+
129+
There are handy functions in `xyz/lines.go` for creating complex line-based shapes, including those with arrow heads. These include `Mesh` functions for making the meshes, and `Init` functions that initialize a `Group` or `Solid` with line shapes.
130+
131+
To make a set of lines:
132+
133+
```go
134+
lines := NewLines(sc, "Lines", []math32.Vector3{{-3, -1, 0}, {-2, 1, 0}, {2, 1, 0}, {3, -1, 0}}, math32.Vec2(.2, .1), CloseLines)
135+
tree.AddChild(sc, func(n *Solid) {
136+
n.SetMesh(lines).SetColor(color.RGBA{255, 255, 0, 128}).SetPos(0, 0, 1)
137+
})
138+
```
139+
140+
To make a line with arrow heads:
141+
142+
```go
143+
tree.AddChild(sc, func(g *xyz.Group) {
144+
InitArrow(g, math32.Vec3(-1.5, -.5, .5), math32.Vec3(2, 1, 1), .05, colors.Cyan, StartArrow, EndArrow, 4, .5, 8)
145+
})
146+
```
147+

enums/enumgen/testdata/enumgen.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)