{
  "name": "windmill",
  "title": "Windmill",
  "type": "registry:component",
  "description": "A tapered tower with a conical cap and four sails that turn each frame; tower collider, seeded blade phase.",
  "dependencies": [
    "@react-three/fiber@^9.6.1",
    "@react-three/rapier@^2.2.0",
    "@runek/core@^0.12.0",
    "three@^0.184.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "Windmill.tsx",
      "content": "import { useFrame } from '@react-three/fiber'\nimport { CylinderCollider, RigidBody } from '@react-three/rapier'\nimport { rng, useWorld, type WorldComponentProps } from '@runek/core'\nimport { useMemo, useRef } from 'react'\nimport type { Group } from 'three'\n\nexport interface WindmillProps extends WorldComponentProps {\n  /** Tower height, in units. */\n  height?: number\n  /** Tower base radius, in units. */\n  radius?: number\n  /** Sail (blade) length, in units. */\n  sailLength?: number\n  /** Sail rotation speed, in radians per second. */\n  sailSpeed?: number\n  /** Tower color (defaults to the world palette's `wall`). */\n  color?: string\n  /** Cap, door, and sail-frame color (defaults to the world palette's `wood`). */\n  trimColor?: string\n}\n\nconst BLADES = [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2]\n\n/** A tower windmill with four slowly turning sails. The tower carries a single cylinder\n *  collider; the cap, axle, and sails are decorative. Seeded only for a small starting-phase\n *  offset so a row of windmills doesn't turn in lockstep. */\nexport function Windmill({\n  position = [0, 0, 0],\n  rotation = [0, 0, 0],\n  seed = 1,\n  height = 7,\n  radius = 2,\n  sailLength = 4.5,\n  sailSpeed = 0.4,\n  color,\n  trimColor,\n}: WindmillProps) {\n  const { unit, palette } = useWorld()\n  const wall = color ?? palette.wall\n  const wood = trimColor ?? palette.wood\n  const roof = palette.roof\n  const sails = useRef<Group>(null)\n\n  const H = height * unit\n  const R = radius * unit\n  const topR = R * 0.66\n  const capH = R * 0.9\n  const sailL = sailLength * unit\n  const sailY = H + capH * 0.3\n  const axleZ = topR * 1.1 + 0.4 * unit\n\n  const phase = useMemo(() => rng(seed)() * Math.PI * 2, [seed])\n\n  useFrame((_, delta) => {\n    if (sails.current) sails.current.rotation.z += sailSpeed * delta\n  })\n\n  return (\n    <RigidBody type=\"fixed\" colliders={false} position={position} rotation={rotation}>\n      <CylinderCollider args={[H / 2, R]} position={[0, H / 2, 0]} />\n\n      {/* tapered tower */}\n      <mesh position={[0, H / 2, 0]} castShadow receiveShadow>\n        <cylinderGeometry args={[topR, R, H, 16]} />\n        <meshStandardMaterial color={wall} flatShading />\n      </mesh>\n\n      {/* conical cap */}\n      <mesh position={[0, H + capH / 2, 0]} castShadow>\n        <coneGeometry args={[topR * 1.15, capH, 16]} />\n        <meshStandardMaterial color={roof} flatShading />\n      </mesh>\n\n      {/* door on the front */}\n      <mesh position={[0, 1 * unit, R * 0.98]} castShadow>\n        <boxGeometry args={[0.9 * unit, 1.8 * unit, 0.12 * unit]} />\n        <meshStandardMaterial color={wood} />\n      </mesh>\n\n      {/* axle from the cap front out to the sails */}\n      <mesh position={[0, sailY, axleZ / 2]} rotation={[Math.PI / 2, 0, 0]} castShadow>\n        <cylinderGeometry args={[0.15 * unit, 0.15 * unit, axleZ, 8]} />\n        <meshStandardMaterial color={wood} />\n      </mesh>\n\n      {/* four turning sails */}\n      <group ref={sails} position={[0, sailY, axleZ]} rotation={[0, 0, phase]}>\n        {BLADES.map((a) => (\n          <group key={a} rotation={[0, 0, a]}>\n            {/* spar */}\n            <mesh position={[0, sailL / 2, 0]} castShadow>\n              <boxGeometry args={[0.14 * unit, sailL, 0.14 * unit]} />\n              <meshStandardMaterial color={wood} />\n            </mesh>\n            {/* canvas, offset to one side of the spar */}\n            <mesh position={[0.5 * unit, sailL * 0.52, 0]} castShadow>\n              <boxGeometry args={[0.8 * unit, sailL * 0.82, 0.05 * unit]} />\n              <meshStandardMaterial color={wall} />\n            </mesh>\n          </group>\n        ))}\n      </group>\n    </RigidBody>\n  )\n}\n",
      "type": "registry:component"
    }
  ]
}
