Aller au contenu principal

Session 66 — Animations vectobj + fix UV residuels

Animations multi-frame

Les vectobj Amiga ont un champ numFrames indiquant le nombre de poses
d’animation (ex: passkey=13 frames rotation, Mantis=20 frames marche).
Jusqu’a session 65 on ne generait que la frame 0 (statique).

Implementation session 66 :

  1. VectObjFrameAnimControl (NOUVEAU) : Control JME qui cycle les
    positions du Mesh a chaque frame.

ARCHITECTURE IMPORTANTE : Le Control n’est PAS stocke dans le
j3o. A la place, les frames d’animation sont stockees en UserData
sur la Geometry (types primitifs natifs JME, serialisation sure).
Le Control est attache au RUNTIME via :
java
Spatial model = assetManager.loadModel("Scenes/vectobj/passkey.j3o");
VectObjFrameAnimControl.attachIfAnimated(model);

Pourquoi ? Un Control custom stocke dans un j3o necessite d’etre
enregistre dans SavableClassUtil et pose probleme dans l’editeur SDK
JME (erreur « obj parameter cannot be null » lors de l’ouverture du j3o).

UserData attendues sur une Geometry animee :
"vectobj.frames" : float[] aplati (numFrames * numVerts * 3)
"vectobj.numFrames" : int
"vectobj.fps" : float (optionnel, defaut 10)

Fonctionnalites : FPS configurable, boucle infinie par defaut,
setPlaying(false) pour stopper, freeze de la pose quand la part
est OFF dans une frame (pas de disparition brutale).

  1. VectObjConverter.convert() refactore :
    – Lit les positions de TOUTES les frames (pas seulement frame 0)
    – Pour chaque part visible a frame 0, genere la geometry avec positions
    de frame 0, puis stocke les frames en UserData via
    VectObjFrameAnimControl.storeFrames().
    – Detection « toutes frames identiques » : pas de UserData stockees si
    l’objet est statique (optimisation).

  2. Refactoring interne :
    – Nouveau record TriangleIdx (indices de points au lieu de positions)
    – Nouvelle methode buildGeometryIdx() qui utilise les indices
    – Nouvelle methode buildFramePositions() qui construit le tableau
    de positions par frame.

Fix UV residuels (sans toucher a l’atlas)

Certains polygones avaient des textures mal positionnees. Correction :
wrap modulo 64 / 256 sur rowFinal et colFinal. En theorie le
comportement ASM fait un modulo implicite via le byte overflow, donc
un polygone qui demande un U > 63-rowStart cycle sur les premieres
rows. Cette correction evite aussi les UVs qui debordent sur la tuile
d’atlas suivante (qui contient un slot different).

Pipeline

./gradlew convertVectObj   # regenere les .j3o avec frames en UserData + UV fixes
./gradlew run              # pour l'animation runtime, appeler
                           # VectObjFrameAnimControl.attachIfAnimated(model)
                           # apres chargement du j3o

Fix en cours de session : float[] non serialisable

JME UserData n’accepte PAS les float[] bruts (erreur « Unsupported type: [F »
durant la conversion). Seuls Integer, Float, String, Savable, List, Map sont
autorises. Solution : encoder les positions en String base64.

  • Key vectobj.framesB64 contient une String base64 des positions en
    IEEE754 little-endian
  • Taille : ~5.5 chars par float (vs 4 bytes natifs), acceptable
  • Decodage via Base64.getDecoder() + ByteBuffer au runtime

Les anciens j3o generes avant ce fix peuvent contenir des UserData cassees.
Il faut supprimer assets/Scenes/vectobj/*.j3o et relancer
./gradlew convertVectObj pour les regenerer proprement.

Verification attendue

  • Les j3o s’ouvrent SANS erreur dans l’editeur SDK JME
  • Lors du runtime, apres attachIfAnimated(), les modeles bougent :
    passkey tourne, Mantis marche, ventfan tourne, wasp bat des ailes
  • Certains polygones auparavant mal textures sont correctement mappes
    grace au wrap modulo

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *