Aller au contenu principal

Session 134quater — Animation par visibilite des parts (fix passkey-style diaporama)

Resume

Fix architectural du systeme d’animation des vectobj pour supporter les
objets de type « diaporama » (passkey, et potentiellement d’autres) ou chaque
frame n’active qu’une seule part parmi N, donnant l’illusion d’un objet
qui change de face / d’icone en tournant.

Avant ce fix, le converter ne creait QUE les parts visibles a la frame 0,
perdant les autres parts utilisees dans les frames 1+. Le passkey (13 frames,
1 part visible/frame) n’affichait donc QUE la part 0 (le chiffre « 1 ») alors
qu’il aurait du cycler entre les 13 icones (chiffres 1-6, indicateurs de
couleur, symbole (!), rond bleu, etc.).

Cause racine

L’investigation a montre que le passkey.vec a la structure suivante :

  • 13 frames, chacune avec un onOffMask qui n’active QU’UNE part precise
  • Frame 0 onOff = 0x001fe001 -> seul bit 0 ON (part 0 visible = chiffre « 1 »)
  • Frame 1 onOff = 0x001fe002 -> seul bit 1 ON (part 1 visible = chiffre « 2 »)
  • Frame 11 onOff = 0x001fe800 -> seul bit 11 ON (part 11 = symbole (!))
  • Frame 12 onOff = 0x001ff000 -> seul bit 12 ON (part 12 = rond bleu)

(Les bits 13..20 sont du padding, ignores par l’ASM qui s’arrete au sortKey
negatif dans la liste des parts.)

L’ASM rendait l’animation correctement via la boucle putinunsorted dans
objdrawhires.s qui consomme un bit de draw_ObjectOnOff_l par part lue
dans LinesPtr (instruction lsr.l #1, d5; bcs.s .yeson).

Cote Java, le converter testait (onOffMask & (1L << pi)) != 0 UNIQUEMENT
pour la frame 0, et skippait les parts non-visibles a frame 0. D’ou la perte
des 12 autres icones.

Fix

Fichier 1 : VectObjConverter.java

  • Calcul de l’union des onOff masks sur toutes les frames
    (unionVisibilityMask).
  • Boucle sur toutes les parts dans cette union (= parts visibles dans au
    moins une frame), pas seulement celles visibles a frame 0.
  • Pour chaque part conservee, calcul d’un perPartVisibilityMask (bit f = 1
    ssi la part est visible a la frame f).
  • Selection d’une frame de reference appropriee pour les positions :
    frame 0 si la part y est visible, sinon premiere frame ou elle est
    visible (firstSetBit).
  • Stockage du perPartVisibilityMask dans le j3o via le nouveau UserData
    vectobj.visibilityMask (Integer JME, suffisant pour <= 32 frames).
  • Cas « vis-only » : si la visibilite varie mais que les positions sont
    identiques entre frames, on duplique la pose de reference dans
    framePositions[f] pour toutes les frames afin que le Control puisse
    cycler la visibilite (buildSingleFramePositions).
  • Pre-application : si la part n’est pas visible a frame 0, on lui met
    CullHint.Always initialement (le Control reactivera le bon hint a la
    premiere update).

Fichier 2 : VectObjFrameAnimControl.java

  • Nouveau UserData KEY_VISIBILITY_MASK = "vectobj.visibilityMask".
  • Nouveau champ long visibilityMask = -1L (= toujours visible, compat
    ascendante).
  • tryAttach() lit le mask depuis les UserData s’il est present.
  • Surcharge storeFrames(geo, frames, fps, visibilityMask) qui stocke le
    mask si different de -1L.
  • Nouvelle methode applyVisibility(frameIdx) qui ajuste le CullHint de
    la Geometry (Inherit si bit a 1, Always si bit a 0). Appelee a chaque
    update via controlUpdate et a chaque manipulation manuelle via
    applyCurrentFrameToMesh.
  • cloneForSpatial() propage le visibilityMask.

Compatibilite

  • Ascendante : les vectobj sans changement de visibilite (= la majorite,
    comme glarebox, mantis, blaster) ne stockent PAS le UserData
    vectobj.visibilityMask. Le Control le lit comme -1L = toujours visible
    et l’applyVisibility est un no-op. Aucune regression possible sur ces
    objets.
  • Nouveaux vectobj diaporama : passkey est le premier identifie. Sa
    geometry passe de 1 part (« 1 ») a 13 parts dont 12 sont initialement
    cachees (CullHint.Always) et seulement reveillees par le Control selon
    la frame courante.

Pour tester

Rebuild necessaire : ./gradlew clean buildScenes (les anciens scene_X.j3o
ne contiennent pas les parts 1-12 du passkey).

Logs attendus dans le build pour passkey :

[passkey]
  ... part[0] anim: 13 frames stockees (vis-only), visMask=0x1
  ... part[1] anim: 13 frames stockees (vis-only), visMask=0x2
  ...
  ... part[12] anim: 13 frames stockees (vis-only), visMask=0x1000
  13 triangles dans 13 parts

En jeu (zone 108 de LEVEL_A) : le passkey doit maintenant cycler a 10 FPS
entre 13 icones (chiffres 1-6, couleurs, (!), rond) au lieu d’afficher
statiquement le chiffre « 1 ».

Laisser un commentaire

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