b3d-star-system

Renders an individual star system with a procedural star and its planets. Given a StarData object (from generateGalaxy) or a galaxy seed + star index, it creates b3d-star and b3d-planet child components with deterministic seeds.

Planets orbit at scaled distances and can optionally animate.

Demo

import { b3d, b3dLight, b3dSun, b3dSkybox, b3dStarSystem, generateGalaxy, label3d, slider3d, toggle3d } from 'tosijs-3d'
import { tosi, elements } from 'tosijs'
const { div, p, pre } = elements

const galaxy = generateGalaxy(1234, 1000)

const { demo } = tosi({
  demo: {
    starIndex: 130,
    scale: 5,
    orbitScale: 3,
    animate: true,
    showOrbits: true,
  },
})

const starSystem = b3dStarSystem({
  galaxySeed: 1234,
  starCount: 1000,
  starIndex: demo.starIndex,
  scale: demo.scale,
  orbitScale: demo.orbitScale,
  animate: demo.animate,
  showOrbits: demo.showOrbits,
})

const scene = b3d(
  {
    frameRate: 60,
    clearColor: '#000011',
    scenePanel: () => [
      label3d({ text: 'Star system' }),
      slider3d({ label: 'star index', value: demo.starIndex, min: 0, max: 999, step: 1 }),
      slider3d({ label: 'scale', value: demo.scale, min: 1, max: 20, step: 0.5 }),
      slider3d({ label: 'orbit scale', value: demo.orbitScale, min: 1, max: 10, step: 0.5 }),
      toggle3d({ label: 'animate', value: demo.animate }),
      toggle3d({ label: 'show orbits', value: demo.showOrbits }),
    ],
    sceneCreated(el, BABYLON) {
      const camera = new BABYLON.ArcRotateCamera(
        'orbit-cam',
        -Math.PI / 2,
        Math.PI / 3,
        100,
        BABYLON.Vector3.Zero(),
        el.scene
      )
      camera.lowerRadiusLimit = 10
      camera.upperRadiusLimit = 500
      camera.minZ = 0.1
      camera.maxZ = 2000
      camera.attachControl(el.querySelector('canvas'), true)
      el.setActiveCamera(camera)
    },
  },
  b3dLight({ intensity: 0.2 }),
  starSystem,
)

const infoEl = pre({ style: 'margin:0; font-size:10px; max-height:120px; overflow-y:auto' })

preview.append(
  scene,
  div(
    { class: 'debug-panel' },
    p('Scroll to zoom, drag to orbit'),
    infoEl,
  )
)
function updateInfo() {
  const sys = starSystem.getSystemData()
  if (!sys) { infoEl.textContent = ''; return }
  const lines = [sys.star.name + ' (' + sys.star.spectralType + ') HI:' + sys.star.bestHI]
  sys.planets.forEach(p => {
    let info = p.name + ' ' + p.classification + ' HI:' + p.HI
    if (p.rings > 0) info += ' rings:' + p.rings.toFixed(2)
    if (p.HI <= 2) info += ' ' + p.atmosphere
    lines.push('  ' + info)
  })
  infoEl.textContent = lines.join('\n')
}

for (const key of ['starIndex', 'scale', 'orbitScale']) {
  demo[key].observe(() => {
    starSystem.regenerate()
    updateInfo()
  })
}
for (const key of ['animate', 'showOrbits']) {
  demo[key].observe(() => {
    starSystem.updateOptions()
  })
}
updateInfo()
tosi-b3d {
  width: 100%;
  height: 100%;
}
.debug-panel {
  position: absolute;
  top: 8px;
  right: 8px;
  background: rgba(0,0,0,0.6);
  color: white;
  padding: 8px 12px;
  border-radius: 6px;
  font: 12px monospace;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

Attributes

Attribute Default Description
galaxySeed 1234 Galaxy seed for deterministic generation
starCount 10000 Number of stars in galaxy (needed to regenerate same galaxy)
starIndex 0 Which star in the galaxy to render
scale 5 Visual scale factor for star/planet sizes
orbitScale 3 Multiplier for orbital distances
animate true Animate planet orbital motion
showOrbits true Show orbital path lines