UI/Renderable: Mesh
Generic mesh renderable that draws user-provided vertices and indices with optional texture/shader.
What this page covers #
mesh draws arbitrary triangle geometry you provide at runtime. It is useful for procedural shapes and pre-tessellated content.
By task #
- Define mesh geometry shape/options: see Definition
- Update mesh vertices/indices at runtime: see Runtime API
- Start from a working snippet: see Example
Generic renderable that draws arbitrary triangles you provide at runtime. Useful for procedurally generated shapes, icons, and SVG tessellation results.
Import #
import * as Compositor from 'Koya/Compositor';
import * as UI from 'Helix/UserInterface';Definition #
Renderable options object passed to UI.createElement(..., { renderable: { ... } }):
MeshRenderable
Generic mesh renderable that draws user-provided vertices and indices.
type'mesh' - Renderable type identifier.geometryobject optional - Vertex and index data.geometry.vertexArray<VertexObject> | number[] optional - Array of vertex objects, or flat numeric array with groups of 9: x,y,z,r,g,b,a,u,v.geometry.indicesnumber[] optional - 16-bit indices, drawn as triangles.texturestring optional - Optional texture path.shader{ vert: string, frag: string } optional - Optional SPIR-V shader override.shaderParams{ v0?: [x,y,z,w], v1?: [x,y,z,w] } optional - Optional per-element shader push constants.
VertexObject
Individual vertex definition. Shorthand keys (
x, y, z, r, g, b, a, u, v) are also accepted.pos[x, y, z?] optional - Position. Defaults z to 0.color[r, g, b, a?] optional - Vertex colour. Defaults[1,1,1,1].uv[u, v] optional - Texture coordinates. Defaults[0,0].
Notes #
- The mesh's local bounds (AABB) are computed automatically from vertex positions during
prepare(); measurement APIs (UI.getRenderableBounds,UI.getRenderableSize) reflect the current geometry. - Updating geometry at runtime sets the model dirty and triggers re-upload on size change.
- If you pass a flat numeric
vertexarray, it must be a multiple of 9 (x,y,z,r,g,b,a,u,v). - Element transform pivot is
renderable.originat creation (runtime:UI.setOrigin).
Runtime API #
UI.setGeometry
Update mesh geometry in place. Accepts either vertex objects or flat numeric arrays.
UI.setGeometry(windowId, elementId, { vertex, indices })Object form:
UI.setGeometry(windowId, elementId, {
vertex: [
{ pos:[0,0,0], color:[1,0,0,1], uv:[0,0] },
{ pos:[64,0,0], color:[0,1,0,1], uv:[1,0] },
{ pos:[64,64,0], color:[0,0,1,1], uv:[1,1] },
{ pos:[0,64,0], color:[1,1,1,1], uv:[0,1] }
],
indices: [0,1,2, 2,3,0]
});Flat numeric form:
UI.setGeometry(windowId, elementId, {
vertex: [
0, 0, 0, 1,0,0,1, 0,0,
64, 0, 0, 0,1,0,1, 1,0,
64,64, 0, 0,0,1,1, 1,1,
0,64, 0, 1,1,1,1, 0,1
],
indices: [0,1,2, 2,3,0]
});Example #
Creates a coloured quad from four vertices, attaches it with a vertex-colour shader, then replaces the geometry at runtime with a diamond shape. Shows how to bootstrap a mesh and hot-swap its geometry without recreating the element.
import * as Compositor from 'Koya/Compositor';
import * as UI from 'Helix/UserInterface';
const win = await Compositor.createWindow({
role: 'overlay',
anchor: 'top-left',
size: { x: 240, y: 160 },
offset: { x: 80, y: 80 }
});
const id = await UI.createElement(win, {
renderable: {
type: 'mesh',
shader: {
vert: '/rom/shaders/vertex_color.vert.spv',
frag: '/rom/shaders/vertex_color.frag.spv'
},
position: { x: 20, y: 20 },
geometry: {
vertex: [
{ pos:[0,0,0], color:[1,0,0,1], uv:[0,0] },
{ pos:[96,0,0], color:[0,1,0,1], uv:[1,0] },
{ pos:[96,64,0], color:[0,0,1,1], uv:[1,1] },
{ pos:[0,64,0], color:[1,1,1,1], uv:[0,1] }
],
indices: [0,1,2, 2,3,0]
}
}
});
await UI.attachRoot(win, id);
await UI.setGeometry(win, id, {
vertex: [
{ pos:[48,0,0] },
{ pos:[96,48,0] },
{ pos:[48,96,0] },
{ pos:[0,48,0] }
],
indices: [0,1,2, 2,3,0]
});