v0.7.1 (build 925)

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.
  • geometry object optional - Vertex and index data.
  • geometry.vertex Array<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.indices number[] optional - 16-bit indices, drawn as triangles.
  • texture string 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 vertex array, it must be a multiple of 9 (x,y,z,r,g,b,a,u,v).
  • Element transform pivot is renderable.origin at 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]
});