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 :
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).
-
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). -
Refactoring interne :
– Nouveau recordTriangleIdx(indices de points au lieu de positions)
– Nouvelle methodebuildGeometryIdx()qui utilise les indices
– Nouvelle methodebuildFramePositions()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.framesB64contient une String base64 des positions en
IEEE754 little-endian - Taille : ~5.5 chars par float (vs 4 bytes natifs), acceptable
- Decodage via
Base64.getDecoder()+ByteBufferau 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