CommunityProgramación y desarrollogithub.com

bugeng777/teardown

Construye un simulador 3D interactivo de una máquina o mecanismo real (motor, tren de aterrizaje, eslabonamiento, bomba, caja de cambios) en una sola página HTML fuera de línea que se puede desmontar, con paneles en vivo impulsados por el mismo modelo que mueve las piezas, un botón para cada subsistema, cortes, vistas de cámara y un recorrido automático que entrega el control al visitante; luego grábala cuadro a cuadro en un video de 60 fps con una banda sonora procedimental sincronizada.

¿Qué es teardown?

Teardown es una habilidad para agentes de IA (como Claude Code, Cursor o Codex) que permite crear simuladores 3D interactivos y videos explicativos de máquinas y mecanismos reales. A partir de referencias visuales y dimensiones reales, genera una página HTML autónoma que muestra la máquina en funcionamiento, con paneles de instrumentos, controles para aislar subsistemas, modos de corte, vistas de cámara y un recorrido automático. Utiliza una única fuente de datos (como el ángulo del cigüeñal o la carrera) para impulsar tanto la animación 3D como los gráficos y la banda sonora, garantizando sincronía perfecta. Además, incluye un sistema de captura cuadro a cuadro para exportar el recorrido como un video de 60 fps con sonido sintetizado, y un conjunto de reglas de revisión para garantizar la calidad visual y mecánica. La habilidad es ideal para responder preguntas sobre cómo funciona una máquina, o para crear 'explicadores visuales', 'simuladores', 'vistas en corte', 'vistas explosionadas' o 'lecciones 3D interactivas'.

Compatible con✓Claude Code~Codex CLI✓Cursor
npx skills add bugeng777/teardown-cursor

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace teardown?

Una máquina, una página. El visitante ve la máquina funcionar, presiona un botón y la pieza que realiza el trabajo se abre mientras los indicadores a su alrededor muestran los números reales. Si se deja solo, la página se recorre a sí misma con un cursor. El mismo código graba una película del recorrido, cuadro por cuadro, con una banda sonora construida sobre la misma línea de tiempo.

SKILL_DIR es la carpeta donde reside este archivo (para una instalación de Cursor, normalmente ~/.cursor/skills/teardown, ~/.agents/skills/teardown o .cursor/skills/teardown dentro de un proyecto). Las compilaciones y renderizaciones se guardan en ./teardown-out de la carpeta desde donde se ejecuta.

Primera ejecución

cd "$SKILL_DIR" && npm install && npx playwright install chromium

Las páginas no necesitan nada más. El video necesita ffmpeg en PATH y la banda sonora necesita Python 3 (solo biblioteca estándar). Configura FFMPEG, PYTHON o CHROMIUM para apuntar a otros binarios.

Los 3 ejemplos

Compila uno, abre el HTML, presiona botones. Copia el más cercano cuando empieces una nueva máquina.

La máquinaQué la impulsaVale la pena robar
v8-*Un V8 de plano cruzado con camisas de vidrio: la carga se quema dentro del cilindro que sigues, las válvulas se levantan sobre sus levas, 8 pistones se mueven desde el mecanismo biela-manivela exacto.Ángulo del cigüeñal. Orden de encendido 1-8-4-3-6-5-7-2, un modelo de presión en la cámara para el diagrama indicador.Modos de corte (vidrio, sección, sólido), el orden de encendido como selector de cilindros, gráficos en vivo sincronizados con el cigüeñal.
cessna-*El tren de aterrizaje principal del Cessna 337 plegándose dentro del fuselaje al despegar y bajando al aterrizar.Carrera 0..1: una cremallera de 201 mm gira un piñón de 32 dientes (módulo 4 mm) exactamente 180°.Un grado de libertad que plantea todo un mecanismo, fases de vuelo como funciones del tiempo, una pista que rueda debajo del modelo.
strandbeest-*El Strandbeest de Theo Jansen, 20 patas en un cigüeñal, caminando de lado sobre la arena.Viento. La velocidad del cigüeñal se integra a partir de él; cada articulación sigue por intersección de círculos a partir de las 11 longitudes de eslabón de Jansen.Un solucionador de eslabonamiento exacto en 67 líneas, tubos instanciados, huellas de patas, un gráfico de contacto de las 20 patas.

Cada uno viene en 3 carpetas: <nombre>-shared/ contiene la máquina, <nombre>-film/ el recorrido grabado, <nombre>-live/ la página que se conduce.

node "$SKILL_DIR/sims/build.mjs" v8-live          # → teardown-out/dist/v8-live.html, fuera de línea, ~800 KB
node "$SKILL_DIR/sims/build.mjs"                  # los 6

Cómo se construye una máquina

Una carpeta por máquina, dividida por trabajo. Los ejemplos siguen esto exactamente:

ArchivoTrabajo
kin.js / gear.js / jansen.jsLas matemáticas. Dimensiones reales en unidades reales, una entrada (ángulo del cigüeñal, carrera, viento) y cada pose y valor mostrado como función de ella. No hay three.js aquí.
engine.js / gear.js / beast.jsLa geometría, construida desde código: piezas torneadas, tubos, eslabones instanciados. update(input) la posiciona.
stage.jsEstudio, luces, sombras, postprocesado (GTAO, bloom). frame(state, cam) dibuja un cuadro.
console.jsLa superposición: diseño CSS fijo de 1600 x 900 con paneles, gráficos, interruptores, llamadas con líneas guía. update(state) lo redibuja desde el estado del cuadro.
film.jsUn SCRIPT de movimientos del operador (vistas, aislar, corte, acelerador) y render(t) como una función pura del tiempo.
live.jsLa misma máquina en tiempo real: botones, deslizadores, órbita, zoom, teclas. Sin entrada, reproduce el SCRIPT de film.js como un recorrido automático con un cursor; cualquier clic, arrastre, rueda o tecla entrega el control, 25 s de inactividad lo devuelven.
score.pyEl sonido en la línea de tiempo de la película.

Para una máquina fuera de SKILL_DIR, crea una carpeta con un main.js e importa el kit por nombre: import {runSim} from 'teardown-kit/runtime.js'. Compílala con node "$SKILL_DIR/sims/build.mjs" ./mi-maquina.

Reglas que deciden si funciona

  1. Empieza desde una referencia, nunca desde la imaginación. Una foto, un dibujo en corte de un manual, un clip de la máquina real. Construye contra ella y compara cuadro por cuadro. Las máquinas inventadas a partir de una oración siempre salen genéricas; el mismo modelo reconstruye una real de cerca cuando tiene algo con qué coincidir.
  2. Números reales, una sola fuente. Obtén las dimensiones reales primero (diámetro, carrera, número de dientes, longitudes de eslabones). Cada indicador, gráfico y etiqueta lee de la misma función que posiciona las piezas, así que nada en pantalla puede discrepar del movimiento. Verifica uno a mano: en el Cessna, 32 dientes × módulo 4 mm es un diámetro primitivo de 128 mm, y la mitad de su circunferencia es la carrera de 201 mm.
  3. Una sola entrada lo impulsa todo. Pose desde el ángulo del cigüeñal, la carrera o el viento. Nada se anima manualmente, por lo que la película, la página en vivo y la banda sonora nunca se desincronizan.
  4. La pieza que realiza el trabajo se abre. Aíslala, córtala, hazla transparente. Una cámara que entra adentro vale más que diez órbitas.
  5. Estudio de luz, un acento. Los fondos pálidos se leen en un feed; los oscuros pierden el primer segundo. El acento marca lo que está cambiando. Observa las piezas casi blancas sobre un fondo pálido: dales un contorno de tinta o un suelo más oscuro.
  6. Elige la cámara para el mecanismo. Un eslabonamiento plano visto de frente se colapsa en un enrejado; una vista en 3/4 a lo largo de la columna mantiene cada pata legible.
  7. Arregla las colisiones con un número. Cuando una pieza atraviesa otra, escálala o muévela en el bloque de parámetros. Nunca la escondas con la cámara.

Reglas de la página en vivo

  • Prueba en una GPU integrada. Una página que corre a 60 fps en una tarjeta de escritorio puede caer a 15 fps en la integrada de un portátil. Los ejemplos llevan niveles de calidad (TIERS en live.js): sin AO, menor relación de píxeles, mapas de sombra más pequeños, paneles redibujados cada dos cuadros. Encuentra primero el shader costoso: un desplazamiento calculado 5 veces por vértice cuesta más que todos los niveles juntos.
  • Calienta los shaders. kit/warm.js compila todos los programas en paralelo antes del primer cuadro, para que la página nunca se congele al dibujar por primera vez.
  • Mantén la página por debajo de 1 MB. Los rastreadores de enlaces (X, Slack) leen la tarjeta de compartir del HTML y se rinden con una página de 15 MB. Los modelos grandes se envían como archivos junto a la página: build.json → {"external": {"heavy.glb": "light.glb"}}.

Contrato de render(t)

import {runSim} from '../kit/runtime.js';

const DEFAULTS = {duration: 20, fps: 60, hud: {enabled: false}, director: {enabled: false}};

runSim(DEFAULTS, async ({cfg, canvas, capture}) => {
  // construye la escena, precalcula cualquier cosa con estado
  return {render(t) { /* dibuja el cuadro t desde cero */ return {}; }, resize() {}};
});
  • render(t) es pura: sin Math.random (usa rng(seed) de kit/util.js en la configuración), sin Date, sin estado entre cuadros. La captura lo llama en momentos arbitrarios.
  • Cualquier cosa que se mueva por sus propias reglas (agentes, partículas) se simula una vez al cargar en arrays tipificados; render solo los lee. Una cantidad integrada en el tiempo (el cigüeñal del Strandbeest bajo un viento cambiante) se integra en forma cerrada o se tabula al cargar.
  • Cada tiempo va a <nombre>-film/timeline.json en segundos. La banda sonora lee el mismo archivo.
  • El cuadro 0 es la miniatura. Ya debe mostrar la máquina.

Comandos

node "$SKILL_DIR/sims/build.mjs" v8-film
node "$SKILL_DIR/sims/capture.mjs" v8-film --size 1600x900 --dpr 1.2 --stills beats --cols 4 --out teardown-out/v8-beats.png
node "$SKILL_DIR/sims/capture.mjs" v8-film --size 1600x900 --dpr 1.2 --still 12.5 --out teardown-out/v8-12.5.png
node "$SKILL_DIR/sims/capture.mjs" v8-film --size 1600x900 --dpr 1.2 --out teardown-out/v8-silent.mp4
python "$SKILL_DIR/run_sfx.py" "$SKILL_DIR/sims/v8-shared/score.py"
ffmpeg -y -i teardown-out/v8-silent.mp4 -i teardown-out/v8-score.wav -map 0:v -map 1:a -c:v copy -c:a aac -b:a 256k -shortest -movflags +faststart teardown-out/v8.mp4
node "$SKILL_DIR/wave.mjs" teardown-out/v8.mp4 --timeline "$SKILL_DIR/sims/v8-film/timeline.json"

--size es el diseño CSS y --dpr lo multiplica: 1600 x 900 a 1.2 da 1920 x 1080. La captura imprime la GPU que obtuvo; un renderizador por software significa que las banderas de GPU en paths.mjs no funcionaron.

Bucle de revisión

No puedes ver el video; puedes mirar cuadros. Nunca reportes una máquina como terminada sin leer hojas del renderizado actual.

  1. --stills beats: un mosaico por tiempo de la línea de tiempo, 0.3 s después, cada uno etiquetado con t=.
  2. Lee cada mosaico contra la lista de verificación a continuación.
  3. Acerca: --stills every:0.2 --from A --to B para una transición, --still T para un cuadro completo.
  4. Arregla, recompila, vuelve al paso 1. Detente cuando una pasada completa no encuentre nada.
  5. Final: node "$SKILL_DIR/sheet.mjs" --video <final.mp4> --timeline <timeline.json> y léelo también: muestra lo que escribió el codificador.

Lista de verificación:

  • El mecanismo. Cada pieza que debe tocar toca; nada atraviesa nada; los números en los paneles coinciden con la pose.
  • Composición. Un punto focal por cuadro. Nada importante a menos de 60 px de un borde. Las etiquetas nunca cubren la pieza que nombran.
  • Tipografía. Nada recortado. La lectura clave se lee a lo ancho de un teléfono.
  • 3D. El bloom se come los detalles: mantén las capas emisivas por debajo de 1.0. Las superficies casi blancas se sobreexponen. El metal brillante con poca luz se raya: rugosidad ≥ 0.45 y envMapIntensity ≈ 0.5 en superficies grandes.
  • Tiempo. Cada estado se mantiene el tiempo suficiente para leer: 1 s para una frase corta más 0.25 s por palabra más allá de tres.

Trampas de three.js que los ejemplos ya encontraron

  • smoothstep(a, b, x) con a > b devuelve 0 en Windows (ANGLE/D3D). Escribe 1.0 - smoothstep(b, a, x).
  • Un ShadowMaterial o un decal de una fracción de milímetro sobre el suelo pierde la prueba de profundidad dentro de un render target de postprocesado. Dale polygonOffset.
  • Un cuadrilátero colocado en el suelo con un mapeo reflejado se descarta como una cara trasera. Usa DoubleSide.
  • Un píxel NaN oscurece todo el cuadro a través del bloom. Aplica un límite a cada base de pow() en un shader.
  • El GTAO en un modelo recortado (corte) necesita los mismos planos de recorte en gtao.normalMaterial, o la mitad cortada regresa como un fantasma pálido.

Sonido

sfx/ sintetiza cada sonido en Python puro (48 kHz, reproducible) y lee la línea de tiempo de la película, por lo que el sonido no puede desincronizarse. python "$SKILL_DIR/run_sfx.py" --list muestra los generadores. sample() agrega los sonidos CC0 grabados en sfx/samples/. sfx/score_kit.py tiene las capas de fondo y acentos que usan las 3 bandas sonoras: un acorde de fondo, un golpe suave por carrera de potencia, un motor, aire bajo resistencia.

  • Cada tiempo proviene de la línea de tiempo, nunca un número escrito.
  • La masterización es automática: −14 LUFS, pico verdadero ≤ −2 dBFS.
  • Acento, nunca narración: el movimiento continuo permanece en silencio. Un sonido clave para cada sonido tonal.

Buen gusto, con números

  • Suavizado: entradas cubic-bezier(0.16, 1, 0.3, 1), salidas cubic-bezier(0.6, 0, 0.9, 0.35) a la mitad de la duración de la entrada, estado a estado cubic-bezier(0.65, 0, 0.35, 1). Lineal solo para movimiento continuo.
  • La máquina llena el 60-70% de su viewport. Las etiquetas nunca por debajo de 34 px en un lienzo de 1080.
  • Un acento, y significa algo: la pieza que está trabajando ahora.
  • Nada completamente estático: un elemento siempre vivo.

Créditos

Puerto de Cursor por bugeng777/teardown-cursor de elvarofficial/teardown (MIT). El kit, la captura de cuadros, el motor de efectos de sonido y las reglas de revisión provienen de whaleyxbt/claude-motion (MIT). Las muestras grabadas son CC0 de Freesound, recortadas por Barty-Bart/motion-graphics (MIT); fuentes en sfx/samples/SOURCES.md.

Skills relacionados