Communitygithub.com

Machine Skill

Transformez une simple description (« un turboréacteur », « une montre mécanique », « un cœur artificiel LVAD ») en une simulation 3D interactive, photoréaliste et physique dans un seul fichier HTML, avec un film de 20 à 30 secondes.

Qu'est-ce que Machine Skill ?

Ce skill permet de créer une simulation 3D interactive d'une machine quelconque à partir d'une phrase unique. L'utilisateur décrit la machine (ex: « un turboréacteur », « une montre mécanique », « un cœur artificiel pump ») et le skill génère un fichier HTML complet, autonome, contenant la simulation 3D photoréaliste, basée sur la physique réelle, avec des matériaux PBR (métaux, peintures, polymères, verre), un éclairage de studio, des ombres douces et des pièces en mouvement animées par un solveur qui calcule des valeurs réelles (poussée, couple, tr/min, débit, pression, rendement). En complément, un film de 20 à 30 secondes peut être généré via une commande. Le skill inclut des modes pour exploser la machine, la couper en coupe avec des sections nettes, la radiographier, la ralentir, ajouter des étiquettes et la casser selon des défaillances réelles calculées par le solveur. Il est particulièrement utile pour les développeurs et ingénieurs qui souhaitent visualiser, expliquer ou démontrer le fonctionnement d'un mécanisme complexe de manière interactive, même sans avoir à spécifier explicitement les termes « simulation » ou « three.js ».

Compatible avec✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/WU7475/skill-backup/tree/main/machine

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Compétence Machine

Vous construisez une machine comme un studio de photo présente un objet et un ingénieur l'explique : la vraie chose dans sa vraie taille, avec de vrais matériaux, sur un plateau de studio propre, animée par de vraies équations. Une ligne en entrée, un fichier HTML en sortie, et un film en une commande.

La sortie est toujours :

  1. <nom>.html : une page unique et autonome (three.js 0.170 via jsDelivr, le kit intégré). Elle s'ouvre depuis un disque, un hébergeur statique ou dans une iframe.
  2. Un film : node scripts/record.mjs <nom>.html out/<nom>.mp4 --music freepd:<Catégorie>/<Nom>.

Ouvrez d'abord examples/. Chaque exemple a été créé à partir de la ligne unique en haut de sa page. examples/turbofan.html est la référence : lisez-la entièrement avant d'écrire quoi que ce soit.

La barre

Avant de commencer, imaginez ce que voit le spectateur après trois secondes. Cela doit déjà ressembler à une photo de studio du produit réel : silhouette et proportions correctes, métal qui ressemble à du métal, une ombre douce sur un sol en papier, rien qui flotte, rien qui coupe, rien qui est en placeholder. Ensuite, ça bouge, et chaque nombre à l'écran est calculé.

Un résultat n'est pas terminé tant que l'une des conditions suivantes est vraie :

  • une pièce qu'un mécanicien attendrait est manquante (pas d'injecteurs de carburant dans une chambre de combustion, pas d'échappement dans une montre, pas de soupapes dans un moteur)
  • quelque chose flotte, intersecte ou présente un joint ou un espace visible
  • un matériau ressemble à du plastique alors qu'il devrait être du métal, ou tout est gris
  • un nombre à l'écran est saisi plutôt que calculé par le solveur
  • la coupe montre des coques creuses au lieu de faces de section solides
  • la première image du film n'est pas belle

Flux de travail

1. Recherchez la machine réelle (5 minutes, pas de code)

Notez, dans un commentaire en haut du script, à partir de ce que vous savez (et du web si nécessaire) :

  • Les vraies dimensions en mètres des 5 à 10 pièces qui définissent la silhouette (un turboréacteur : diamètre de la soufflante 2,85 m, longueur 4,9 m, diamètre max de la nacelle 3,44 m).
  • La liste des pièces dans l'ordre d'assemblage, chacune avec son matériau. Visez 15 à 40 pièces nommées ; les pièces répétées (pales, dents, boulons, bobines) comptent individuellement.
  • La physique qui la fait fonctionner, sous la forme de 3 à 6 équations que vous allez réellement calculer, avec des constantes réelles et le point de fonctionnement (un turboréacteur : cycle de Brayton, décollage à N1 100 %, OPR 42, T4 1 750 K, poussée d'environ 330 kN).
  • Le nombre qui intéresse le spectateur : le héros (poussée, couple, battements par heure, débit, puissance). Il reçoit un grand affichage sérifé et une fine barre.
  • L'entrée que le spectateur veut contrôler : un curseur (manette des gaz, vitesse du vent, tr/min, vitesse de pompe, taille de mouture).
  • La rupture : la panne dont un ingénieur se préoccupe, et ce que le solveur dit qu'il se passe (perte d'aube de soufflante et charge de déséquilibre, levée de soupape au-dessus du régime rouge, pompe bloquée, surpression). Cela doit être une conséquence calculée, pas une animation.

2. Construisez la page à partir du modèle

Copiez kit/template.html vers <nom>.html. Il contient la carte d'import ([email protected] fixé), les polices, un bloc marqué où le kit est intégré, et les quatre sections que vous remplissez :

const { THREE, Lab, MAT, GEO, heatGlow, clamp, lerp, approach, fmt } = window.LabKit
const lab = new Lab({ prompt, no, title, sub, size, view, cut })   // 1. le lab
// 2. les pièces      lab.mesh(GEO..., MAT..., { name, pos, explode, xray, count })
// 3. le solveur     lab.hero(...); lab.slider(...); lab.onTick((dt, lab) => { ... lab.setHero(...) })
// 4. rupture, explication, film      lab.breakIt(...); lab.how(...); lab.autoFilm(...); lab.start()

Juste après avoir copié, exécutez node <répertoire skill>/scripts/inline.mjs <nom>.html : cela colle le kit dans le bloc marqué afin que la page soit un fichier unique et autonome où qu'il se trouve (le src="../kit/lab-kit.js" du modèle ne fonctionne que dans ce dépôt). Ensuite, écrivez votre machine dans le second bloc de script.

3. Géométrie : des solides réels à la vraie taille

Travaillez en mètres dans le repère de la machine, Y vers le haut, le sol à y = 0 sauf si vous définissez ground. Définissez size sur la plus grande dimension réelle ; le kit redimensionne l'affichage pour que chaque machine soit assise de la même manière sur le plateau, et la barre d'échelle montre la taille réelle.

  • Pièces rondes (arbres, disques, carters, buses, cônes, spinners, pistons, lunettes) : GEO.lathe([[r, y], ...]) avec un profil Fermé. Parois : GEO.shell(profil, épaisseur), tubes : GEO.tube(Rext, Rint, h), disques chanfreinés : GEO.disc(r, h). Les coins restent nets et les courbes sont lissées automatiquement.
  • Aubes et ailettes : GEO.rotor({ count, axis, r0, r1, chord, thick, camber, twist, pitch, sweep }) construit des profils aérodynamiques réels cambrés et vrillés (épaisseur NACA) sous forme de solides fermés et les dispose en anneau. Utilisez des tableaux [root, tip] pour chord, thick et camber.
  • Engrenages : GEO.gear({ teeth, module, width, bore, helix, spokes, rim }). Mailliez deux engrenages à la distance entre centres (z1 + z2) * module / 2 et faites-les tourner au rapport de dents inverse, décalés d'une demi-dent.
  • Tuyaux, durites, câbles : GEO.pipe(points, r) (fermé, capoté). Acheminez-les le long de la structure d'un port à l'autre, jamais à travers une pièce.
  • Fixations : GEO.bolts(n, R, size, h) sur chaque bride. Ressorts : GEO.spring(R, wire, turns, len). Boîtes : GEO.rbox(w, h, d, r) (toujours arrondies, jamais anguleuses). Plates avec trous : GEO.extrude(shape, depth).
  • Les masses et les inerties proviennent de la géométrie : GEO.volume(geo) donne le volume et le centre de gravité, multipliez par la densité réelle.

Règles pour garder une géométrie propre :

  • Chaque pièce est un solide fermé (profils de tournage fermés, coques avec épaisseur, tuyaux capotés). C'est ce qui permet à la coupe de dessiner des faces de section solides. Les surfaces ouvertes apparaissent creuses lors de la coupe.
  • Rien n'intersecte visiblement et rien ne flotte. Chaque pièce touche ce qui la maintient (une bride repose sur une face, un arbre tourne dans un palier, un poteau atteint le sol). Vérifiez les joints en gros plan.
  • Détail là où l'œil se pose : cercles de boulons sur les brides, chanfreins, un lèvre, une plaque signalétique, les conduites de carburant, un harnais. Les grandes surfaces planes reçoivent une couture, une ligne de panneau ou une finition de texture.
  • Donnez une base à la machine : un support, un berceau, un socle, un établi ou un montage avec des pieds au sol. Les machines flottent rarement dans la réalité.
  • Budget : jusqu'à environ 700 000 triangles et 200 maillages. Fusionnez les pièces statiques répétées avec GEO.merge / GEO.ring ; gardez les groupes mobiles séparés.

4. Matériaux : jamais un seul gris

Utilisez les préréglages MAT.* ; ils portent des réflectances mesurées pour que l'acier, le titane, l'aluminium, le laiton et le cuivre aient un aspect différent côte à côte. Chaque préréglage accepte des surcharges (color, roughness, clearcoat, tout champ MeshPhysicalMaterial) et une finish (texture de micro-rugosité : turned anneaux sur les pièces de tour, brushed stries, cast taches, smudge, knurl).

UtilisationPréréglage
arbres, disques, pièces usinéesMAT.steel, MAT.stainless, MAT.chrome
boîtiers, pièces mouléesMAT.aluminium, MAT.castIron, MAT.steelDark
aubes, aérospatialMAT.titanium, MAT.inconel (+ heatGlow)
raccords, câblageMAT.brass, MAT.copper, MAT.gold
carrosseries peintesMAT.paint({ color }), MAT.satin, MAT.anodised({ color })
polymèresMAT.plastic, MAT.rubber, MAT.carbon
vitres, cristauxMAT.glass, MAT.sapphire, MAT.ruby, MAT.enamel
lumière, flamme, gaz chaudMAT.glow, heatGlow(material, kelvin)

Choisissez une palette comme un designer industriel : principalement des métaux et une ou deux couleurs peintes, un accent au maximum. Les pièces chaudes brillent à partir de la température du solveur (material.userData.heat.value = T).

5. Le solveur : des nombres réels ou rien

Écrivez une petite fonction pure depuis l'entrée et l'état vers chaque nombre que vous affichez, avec des unités réelles et des constantes réelles. Intégrez la dynamique avec approach (retard du premier ordre : montée en régime, masse thermique) ou rk4 (ressorts, échappements, pendules). Ensuite, pilotez le mouvement à partir de celle-ci : un tr/min du solveur fait tourner l'arbre, un débit du solveur déplace les particules, une température chauffe le métal.

  • Un héros : lab.hero({ label, unit, max }) puis lab.setHero(value, { state, sub, bad }) à chaque tick. state est deux ou trois mots (en régime, décollage, écoulement obstrué). sub est une ligne avec 2 ou 3 nombres supplémentaires.
  • Un curseur : lab.slider({ id, label, min, max, value, unit, ends }). Un second seulement si la machine en a vraiment besoin.
  • Les étiquettes sont accrochées à des pièces statiques à des points sur les plans de coupe : lab.label(obj, 'HP turbine', { at: [x, y, z], value: () => '12 979 tr/min' }).
  • lab.how(mots, équations) remplit "Comment c'est calculé" : le modèle en mots simples et les équations telles qu'écrites dans le code. Dites ce qui est simplifié.
  • Si un mouvement est trop rapide pour être vu (une soufflante à 2 700 tr/min), montrez-le ralenti et dites-le dans how ("rotation affichée au 1:60"). Ne ralentissez jamais les nombres.
  • Vérifiez le point de fonctionnement par rapport à la valeur publique que vous avez notée à l'étape 1. Si vous êtes à plus de 20 % d'écart, corrigez le modèle, pas le nombre.

6. Flux, chaleur et effets

  • lab.flow({ paths, count, length, color, parent }) : des traînées qui parcourent les chemins que vous construisez à partir du flux réel (air dans un conduit, sang dans une pompe, eau dans un disque). Définissez .speed à partir du solveur et .opacity à partir de lab.state.cut pour qu'elles apparaissent à l'intérieur de la coupe. Colorez par une quantité calculée (température, pression).
  • lab.plume({ radius, length, dir, color: 'rocket' | 'jet', shocks }) : un échappement avec des diamants de Mach ; définissez .power à partir du solveur.
  • lab.sparks.emit(posMonde, n, vitesse) et lab.shed(maillage, v, w) pour les ruptures : des étincelles tombent avec la gravité et rebondissent ; une pièce détachée devient un corps rigide qui atterrit sur le sol.

7. Modes (le kit les fait ; vous les configurez)

  • Exploser : chaque lab.add/lab.mesh prend explode: [dx, dy, dz] dans le repère du parent (en mètres). Déplacez les pièces le long de leur axe d'assemblage, les coques extérieures les plus loin, et gardez le noyau en place. Rien ne doit se croiser en sortant.
  • Coupe : cut: { a, b, center, reach } sur le Lab. a et b sont les directions de la région enlevée : a = [0,0,1], b = [0,1,0] enlève le quart vers le spectateur et vers le haut (idéal pour les choses avec un axe) ; b = a enlève une moitié. Les faces de section sont dessinées automatiquement pour chaque solide fermé, avec un hachurage léger.
  • Radiographie : xray: 'shell' sur les carters extérieurs les transforme en verre avec des arêtes fines, de sorte que le cœur apparaisse pendant le fonctionnement.
  • Ralenti, étiquettes, pause sont offerts gratuitement (touches S, L, Espace). Les parties interactives sont l'orbite de la souris, le curseur et les boutons.
  • Casser : lab.breakIt({ label, run(lab), reset(lab) }). run modifie l'état du solveur (une pale libérée, une soupape bloquée, un joint rompu) et le solveur calcule la conséquence. Montrez-le dans le héros (bad: true) et avec des étincelles, des débris ou des secousses.

8. Regardez-le comme un critique (obligatoire)

Rendu et LISEZ chaque image que vous créez. Utilisez les scripts :

node scripts/shot.mjs <nom>.html out/review.png                               # le premier aperçu
node scripts/shot.mjs <nom>.html out/cut.png --js "lab.toggle('cut', true); lab.toggle('labels', true)"
node scripts/shot.mjs <nom>.html out/near.png --js "lab.setView({ az: 70, el: 8, dist: 0.8, target: [x, y, z] })"
node scripts/shot.mjs <nom>.html out/film --film 1,4,8,12,17,22,26                 # images du film

Faites au moins quatre séries de révision. Dans chaque : vue d'ensemble, coupe avec étiquettes, explosée, deux gros plans de joints, et les images du film. Comparez avec de vraies photos produit de la machine dans votre mémoire : proportions, nombre de pièces, matériaux, comment la lumière tombe sur elle. Listez ce qui ne va pas, corrigez-le, refaites le rendu. Arrêtez seulement lorsque la liste est vide. Le script de prise de vue imprime les fps, le nombre de pièces et de triangles ; maintenez les fréquences d'images interactives au-dessus de 30.

9. Le film

lab.autoFilm({ runBeat, runSub, breakBeat, breakSub, sliderTo }) écrit l'histoire standard de 28 secondes à partir de votre machine, en séquences numérotées avec les légendes éditoriales :

  1. Une phrase est l'ensemble du brief (la barre de prompt se tape toute seule).
  2. Claude construit la machine (les pièces volent dans l'ordre d'assemblage pendant que le compteur monte : "84 des 3 597 pièces").
  3. Elle fonctionne (un curseur fait glisser le curseur ; le nombre héros monte à partir du solveur).
  4. Ouvrez-la en coupe (capots de section, étiquettes avec valeurs en direct).
  5. Démontez-la (explosez).
  6. Cassez-la (le curseur clique sur le bouton de rupture ; le solveur décide ce qui échoue).

Elle boucle : la dernière clé de caméra revient à la première. Pour un film personnalisé, utilisez lab.film('nom', { len, assemble, shots, events }) : les plans sont des clés de caméra { t, az, el, dist, target, fov }, les événements sont { t, beat: ['07', 'Phrase en gras.', 'Phrase grise.'], set: { cut: 1 }, slider: { id, to, dur }, cursor: { to: 'slider:id:0.8' | 'button:break' | [x, y], click: true }, do(lab) {} }.

Enregistrement (nécessite Node 18+, Playwright avec Chromium, ffmpeg) :

node scripts/record.mjs <nom>.html out/<nom>.mp4 --music freepd:Classical/Easy_Lemon
node scripts/record.mjs <nom>.html out/<nom>-portrait.mp4 --w 1080 --h 1350

La page fonctionne en mode film (?film=1) : son horloge n'avance que lorsque l'enregistreur la fait avancer, donc chaque image est complète et le film est identique à chaque prise. L'enregistreur protège chaque capture d'écran contre les trames magenta qu'un GPU sans tête bloqué peut renvoyer, et analyse le film fini ; il se termine avec un code d'erreur non nul si une image est rose. La musique de FreePD est CC0 ; créditez le morceau quand même.

Écriture à l'écran

La page est éditoriale, pas un tableau de bord : une barre de prompt, un titre sérifé avec un sous-titre en italique, un énorme nombre avec des unités en italique et une fine barre, une ligne de nombres de support, un curseur. Écrivez comme une bonne légende : court, concret, sans fioritures, unités réelles avec un espace (338 kN, 1 750 K, 4,2 L/min), milliers séparés. Les légendes des séquences sont une phrase en gras et une phrase en gris.

Ce qu'il faut dire en remettant le résultat

Donnez le chemin du fichier HTML, la commande du film, le point de fonctionnement que le solveur atteint par rapport à la valeur publique, et tout ce que vous avez simplifié. Proposez la machine suivante.

Skills associés