Skip to content

Blend Camera Demo

App: apps/blend_camera_demo/

A camera authored in Blender driving the rig system (engine ADR 0106). The demo loads a .blend that carries a camera + geometry, instantiates both, then hands the camera’s scene node to Cam.fromNode(scene, node) — which builds a static director rig pinned to the camera’s authored world pose and adopts its lens (blend focal length → FOV, near, far). scene.draw() then renders from exactly the pose the artist framed in Blender, through the same CameraDirector every code-created rig uses — no manual view/projection wrangling.

Before this, a .blend camera could only be driven by hand-rolled view-matrix code (see apps/audio_player_3d’s FPSCamera wrapper). Now it is a first-class rig: it can be the active camera, or you can Cam.blendTo between it and a gameplay rig.

Terminal window
% ./plume3d blend_camera_demo

Self-screenshots blend_camera (after the director pushes its first frame — the model from the elevated 3/4 angle authored in the .blend), then exits.

Load the .blend, instantiate the geometry and the camera object, find the passive Scene.Camera the loader created for that camera, and bind its node as a static rig — all in init:

import "engine" for Engine, Logger, Graphics, Scene, Cam, Resource
class Game {
construct new() {}
init() {
_scene = Scene.new()
_shader = Graphics.loadShader("shaders/default")
Graphics.useShader(_shader)
_blend = Resource.loadBlend("Models/Radio_V3.blend")
_blend.instantiate("Radio", _scene) // the geometry the camera frames
_blend.instantiate("GameCamera", _scene) // the authored camera object
// Find the .blend camera (the loader tags it by object/id name) and drive it through the rig system.
var blendCam = _scene.findCameraByTag("camera")
if (blendCam && blendCam.node) {
_rig = Cam.fromNode(_scene, blendCam.node) // static rig: authored pose + lens
Cam.setActive(_rig) // make it the live view
}
}
draw() {
_scene.draw() // the active static rig (the .blend camera) drives view/projection via the director
}
}
  • A .blend camera is a rig, not a special case. Cam.fromNode builds a rigStatic rig (hard-locked body + a “same as follow” aim); the director feeds the target node’s world rotation so the static aim reproduces the authored facing, and the rig adopts the node’s Scene.Camera lens when present. The result is an ordinary CameraRig — Cam.setActive it, or Cam.blendTo between it and a gameplay rig.
  • Data-authored twin: the same binding is available with no Wren code — cameras.toml type = "static" pins a rig to its target node’s pose and adopts a .blend camera’s lens the same way.