mcpbeat

Xb Modelviewer

google/xb-modelviewer

>- Load and display 3D models in an XR Blocks app with `xb.ModelViewer` — GLTF/GLB models (static or animated), Gaussian-splat (.spz) models, or your own `THREE.Object3D` — wrapped with an optional draggable platform, bounding box, and raycast cylinder so users can grab and reposition them in XR. Use when spawning, scaling, or placing 3D objects/assets in the scene, putting a model inside a UI panel, or auto-placing a model on a real-world horizontal surface. Covers `loadGLTFModel`, `loadSplatModel`, `setupPlatform`, and `world.placeOnHorizontalSurface`.

675 tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
455
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/google/xrblocks --skill xb-modelviewer

The instruction itself

6 sections, as written by the author

xb-modelviewer: load & display 3D models

xb.ModelViewer is a THREE.Object3D that holds a model plus optional affordances (platform,

bounding box, raycast cylinder) for grab-and-move interaction. See samples/modelviewer.

From a GLTF/GLB

class Scene extends xb.Script {
  async init() {
    this.add(new THREE.HemisphereLight(0xbbbbbb, 0x888888, 3));
    const model = new xb.ModelViewer({});
    this.add(model);
    await model.loadGLTFModel({
      data: {
        path: 'https://cdn.jsdelivr.net/gh/xrblocks/assets@main/',
        model: 'models/Cat/cat.gltf',
        scale: {x: 1, y: 1, z: 1},
        rotation: {x: 0, y: 180, z: 0}, // degrees, optional
      },
      renderer: xb.core.renderer,
    });
    model.position.set(0, 0.7, -1.2);
  }
}

From a Gaussian splat (.spz)

const model = new xb.ModelViewer({castShadow: false, receiveShadow: false});
this.add(model);
await model.loadSplatModel({
  data: {
    model: BASE_URL + 'lego/lego.spz',
    scale: {x: 0.6, y: 0.6, z: 0.6},
    rotation: {x: 0, y: 180, z: 0},
  },
});

Wrap your own geometry (with a draggable platform)

const model = new xb.ModelViewer({});
model.add(new THREE.Mesh(geometry, material));
model.setupBoundingBox();
model.setupRaycastCylinder();
model.setupPlatform(); // draggable base so users can move it in XR
model.position.set(-0.6, 0.5, -1.5);
this.add(model);

Place on a real surface

Defer placement until the session starts, then drop the model onto a detected horizontal

surface:

onXRSessionStarted() { this.place(model); }
onSimulatorStarted() { this.onXRSessionStarted(); }
place(model) {
  return xb.world.placeOnHorizontalSurface(model, /*timeout*/ {seconds: 30});
}

Notes

  • Pass {setupPlatform: false} to loadGLTFModel to embed a model inside a UI panel

(panel.add(model)); use model.bbox.getSize(v) to normalize scale.

  • GLTF loads need renderer: xb.core.renderer. Splats require the Spark dependency in your

importmap.

  • Add THREE lights — ModelViewer does not add lighting for you.

How to use it

Copy the folder

Take google/xb-modelviewer from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.