{
  "schemaVersion": 1,
  "id": "gyroscope",
  "version": "1.0.0",
  "status": "published",
  "kind": "object",
  "title": "Gyroscope",
  "summary": "A heavy rotor spinning in three nested gimbal rings on a post, tumbling through every orientation. Loops perfectly.",
  "description": "A gyroscope in its gimbals: a heavy brass rotor spinning on its axle inside an inner ring, hung in a middle ring, hung in an outer ring that stands on a post. Each ring pivots about a different axis, so the rotor tumbles through every orientation while it spins. Choose the metal of the rings (steel, brass, copper or chrome), how fast the rotor spins, how far the rings tumble (a high setting sends the outer rings round whole turns), the backdrop colour and whether the camera sways.",
  "role": "Object (3D, three.js): a classic mechanical showpiece for engineering, navigation and science content.",
  "collections": [
    "satisfying",
    "chrome-glass",
    "hypnotic-loops"
  ],
  "tags": [
    "gyroscope",
    "gimbal",
    "rotor",
    "rings",
    "mechanism",
    "physics",
    "brass",
    "steel",
    "studio",
    "loop",
    "3d"
  ],
  "synonyms": [
    "gimbal",
    "gyro",
    "gyroscope rings",
    "spinning rotor",
    "inertial navigation",
    "tumbling gyro"
  ],
  "useCases": [
    "An engineering or physics explainer",
    "A navigation, aerospace or instrument brand scene",
    "A hypnotic mechanical loop"
  ],
  "featured": null,
  "publishedAt": "2026-10-06",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/gyroscope.js",
    "exports": [
      {
        "name": "createGyroscope",
        "signature": "createGyroscope({ metal?, spin?, tumble? }) => { group, setProgress(progress), dispose() }",
        "description": "The gyroscope on a post as a group about 7 across, base on y = 0; needs an environment map."
      },
      {
        "name": "METALS",
        "signature": "METALS: { steel, brass, copper, chrome }",
        "description": "Ring finishes with colour and roughness."
      }
    ],
    "reusable": [
      "src/gyroscope.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Renderer, geometry and shader materials."
    },
    {
      "id": "chrome-material",
      "version": "1.1.0",
      "scope": "demo",
      "reason": "Studio environment light, backdrop and contact shadow."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "metal",
      "label": "Rings",
      "type": "select",
      "default": "steel",
      "options": [
        {
          "value": "steel",
          "label": "Steel"
        },
        {
          "value": "brass",
          "label": "Brass"
        },
        {
          "value": "copper",
          "label": "Copper"
        },
        {
          "value": "chrome",
          "label": "Chrome"
        }
      ]
    },
    {
      "key": "spin",
      "label": "Rotor spin",
      "help": "Turns of the rotor per loop.",
      "type": "integer",
      "min": 4,
      "max": 24,
      "step": 1,
      "default": 12
    },
    {
      "key": "tumble",
      "label": "Tumble",
      "help": "How far the rings swing; 1.5 and above also sends the outer rings round.",
      "type": "number",
      "min": 0,
      "max": 2,
      "step": 0.25,
      "default": 1
    },
    {
      "key": "background",
      "label": "Backdrop",
      "type": "color",
      "default": "#161c28"
    },
    {
      "key": "orbit",
      "label": "Camera sway",
      "type": "boolean",
      "default": true
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Steel, gentle tumble",
      "params": {}
    },
    {
      "id": "brass",
      "label": "Brass, warm",
      "params": {
        "metal": "brass",
        "background": "#241a12"
      }
    },
    {
      "id": "wild",
      "label": "Chrome, full tumble",
      "params": {
        "metal": "chrome",
        "tumble": 2,
        "spin": 20,
        "background": "#10141c"
      }
    },
    {
      "id": "still",
      "label": "Copper, rotor only",
      "params": {
        "metal": "copper",
        "tumble": 0,
        "spin": 8,
        "background": "#1c1210"
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 16,
    "posterSeconds": 3,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 16,
      "method": "The rotor turns a whole number of times per loop, the rings swing in sines of whole cycles (or turn whole circles at high tumble) and the camera sway is a sine of the loop, so the last frame meets the first."
    },
    "seed": null
  },
  "composition": {
    "inputs": "Time within the loop; the metal, rotor spin, tumble, backdrop and camera sway.",
    "outputs": "A full frame rendered in 3D with a studio environment.",
    "coordinates": "The post stands on y = 0; the gimbal centre is at y ≈ 4.5 with outer ring radius 3.2, middle 2.6, inner 2.0; ring axes are y (outer), x (middle), z (inner) and the rotor spins about y in the inner frame.",
    "lighting": "A warm key light with a shadow map and the studio environment.",
    "timing": "setProgress(progress) sets every angle in closed form; frames render in any order.",
    "compatibleWith": [
      "chrome-material",
      "orbit-camera",
      "kinetic-title",
      "number-reveal"
    ],
    "notes": [
      "The rotor rim carries a red marker so the spin reads at any speed."
    ]
  },
  "reuse": [
    "Explainer: Steel, gentle tumble.",
    "Vintage instrument: Brass, warm.",
    "Energetic: Chrome, full tumble."
  ],
  "integration": {
    "newProject": "Create a WebGLRenderer with a studio environment and a shadow-casting light, add createGyroscope().group and call gyro.setProgress(progress) each frame.",
    "existingProject": "Copy src/gyroscope.js; add the group to your scene with an environment map."
  },
  "performance": {
    "notes": "A few thousand triangles and a shadow map: about a millisecond a frame on an integrated Intel GPU.",
    "limits": "Software WebGL renders in about a second a frame."
  },
  "limitations": [
    "Angles follow a formula rather than rigid-body physics, so the rotor does not precess as a real gyroscope would.",
    "At very high tumble the rings may pass through the post's top pin."
  ],
  "license": {
    "spdx": "MIT",
    "notice": "Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.",
    "thirdParty": []
  },
  "provenance": "Adapted from the owner's threejs-sketches/objects-scenes/gyroscope (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original studio object: three nested gimbal rings on different axes with a spoked brass rotor, all angles closed-form on an exact loop.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-05",
      "notes": "Initial release."
    }
  ]
}
