Skip to content

Geptyro/mesh-x

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mesh-x

Write JSX in code, get procedural 3D meshes as GLB.

mesh-x is a small library for building 3D geometry programmatically and exporting it to glTF/GLB. You describe a scene with JSX (or a plain builder API), and it emits a standard .glb you can drop into Three.js, Blender, or any glTF viewer.

It covers primitives, boolean CSG, extrude/profile sweeps, a skeleton + skinning system, and procedural animations — enough to build characters, weapons, vehicles, and props entirely from code.

import { Scene, Box, Cylinder, writeGlb } from 'mesh-x'

function turret() {
  return (
    <Scene name="Turret">
      <Cylinder radius={0.8} halfHeight={0.3} />
      <Box position={[0, 0, 0.5]} hx={0.15} hy={0.6} hz={0.1} />
    </Scene>
  )
}

writeGlb(turret(), 'turret.glb')

Features

  • JSX authoring<Scene>, <Box>, <Cylinder>, <Sphere>, <Extrude>, <Group>, <Empty>, etc. via the h factory (configure your JSX runtime with jsxFactory: 'h').
  • Primitivesbox, hollowBox, cylinder, zCylinder, sphere, frame, extrude, vent, plus profile sweeps (projectProfile).
  • CSG — boolean subtract(a, b) (BSP-tree based) for cutting shapes.
  • SkinningSkin + Bone hierarchy with per-vertex joint weights for rigged, animatable characters.
  • AnimationsTranslationAnimation, RotationAnimation, MorphAnimation, plus a frame-based rig/FK/IK toolkit (buildRig, FKChain, AnimationFrame).
  • Geometry utilitiesGeometryBuilder (low-level), mirror, auto-smooth normals, winding verification, UV projectors (point/box/cylinder/sphere).
  • Z-up authoring — build in Blender-style Z-up; export converts to glTF Y-up.

Install

npm install mesh-x

The JSX build pipeline uses esbuild, and the optional texture-atlas tooling uses sharp — both are installed as optional dependencies.

Usage

Direct API

import { Scene, box, GeometryBuilder, Mesh, writeGlb } from 'mesh-x'

const geo = new GeometryBuilder()
box(geo, { hx: 1, hy: 1, hz: 1 })

const scene = new Scene({ name: 'Cube' })
scene.add(new Mesh({ name: 'Cube', geometry: geo }))

writeGlb(scene, 'cube.glb')

JSX

Author components as .jsx and transform them with the included loader hooks (esbuild, jsxFactory: 'h'). A build pipeline is provided so consumer projects ship a thin shim:

// build.js in your asset project
import { register } from 'node:module'
register('mesh-x/pipeline/jsx-hooks.js', import.meta.url)

import runBuild from 'mesh-x/pipeline/build.js'
import { join, dirname } from 'path'
import { fileURLToPath } from 'url'

const __dirname = dirname(fileURLToPath(import.meta.url))
await runBuild({
  srcDir: join(__dirname, 'src'),
  command: process.argv[2] || 'all',
})

Then node build.js <assetName> discovers {Name}.meshx.json + {Name}.jsx pairs and emits a .glb per asset.

Materials — two tiers

mesh-x has two ways to give a mesh its surface, and you pick per project:

1. Color materials (default, no setup). Give a mesh a material — a color or a PBR object — and export with no atlas. writeGlb emits one glTF material per distinct material. Meshes sharing a material are merged, so N colors → N draw calls (standard glTF behavior).

import { Scene, Mesh, GeometryBuilder, box, writeGlb } from 'mesh-x'

const geo = new GeometryBuilder()
box(geo, { hx: 0.5, hy: 0.5, hz: 0.5 })

const scene = new Scene({ name: 'Box' })
scene.add(new Mesh({ name: 'Box', geometry: geo, material: '#ff8800' }))
// or: material: { color: '#ff8800', metalness: 0.6, roughness: 0.3, emissive: '#330000' }

writeGlb(scene, 'box.glb')   // no atlasDir → color mode

2. Texture atlas (the optimization). For a game with a fixed palette, give each mesh a swatch (a cell in a shared atlas) and pass atlasDir. Then every mesh shares ONE texture and ONE material, so the whole model is a single draw call regardless of color count.

scene.add(new Mesh({ name: 'A', geometry: geo, swatch: 'Body_Metal' }))
writeGlb(scene, 'out.glb', { atlasDir })   // atlas mode

Use color materials to get going; reach for the atlas when you want the single-draw-call win and have a palette. (A project generates its atlas — the baseColor/orm/emission PNGs + atlas_palette.json — from its swatch list.)

Examples

Runnable scripts in examples/:

node examples/01-hello-box.js      # simplest color export
node examples/02-colored-robot.js  # multiple PBR materials, color mode
node examples/03-atlas-mode.js     # shared-atlas single-draw-call mode

Coordinate system

Author in Z-up, -Y = forward (Blender convention). writeGlb converts to glTF Y-up on export ((x, y, z) → (x, z, -y)), preserving winding.

Development

npm test

Status

Extracted from a game asset pipeline and generalized for standalone use. Both material tiers (color + atlas) work; APIs may still shift before a 1.0.

License

MIT © Geptyro

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors