Aller au contenu principal

Session 100 — Fix effet « rideau » portes + cabine lift solidaire

Symptômes rapportés

  • Les portes (toutes, y compris zone 132 rouge) donnaient l’impression d’un
    « rideau qui s’enroule » plutôt que d’un bloc de porte qui remonte.
  • Le lift de level A (zone 104) présentait le même symptôme : le sol
    remontait tout seul, les parois latérales restaient en place.

Diagnostic

Relecture complète du DoorRoutine et LiftRoutine dans newanims.s pour
comprendre la mécanique ASM exacte (cf. analyse session) :

  • Côté ASM : move.l d3,24(a1) (porte) et move.l d3,20(a1) (lift) patchent
    un mot de la structure du mur avec position * 256. Tous les ZDoorWalls
    d’une porte partagent la même valeur absolue de Bottom -> certains murs
    plus courts disparaissent avant les plus hauts. Sur le moteur Amiga 2.5D
    ce « froissement » est masqué par la rastérisation perspective-correct, mais
    en 3D JME ça donne un effet visuel inacceptable.

  • Côté Java (avant fix) :

  • DoorControl.updateMeshes calculait riseAmount = min(animDist*state, panelHeight).
    Comme animDist est commun mais panelHeight varie par seg, et comme
    computeMaxState() plafonnait à min(panelHeight/animDist), la porte
    arrêtait son anim quand le PLUS PETIT seg était replié, laissant les
    plus grands segs partiellement visibles
    -> effet rideau.
  • LiftControl.updateFloorMesh faisait geo.setLocalTranslation(...) sur
    le seul lift_floor_*. Or setLocalTranslation sur un enfant ne se
    propage pas aux frères -> les lift_side_* restaient statiques
    pendant que le sol montait.

Fix porte (DoorControl.java)

Animation par-segment au lieu de par animDist global :

// Avant
float riseAmount = Math.min(dist * state, panelHeight);

// Après
float riseAmount = panelHeight * state;

Chaque segment monte de SA propre panelHeight quand state passe de 0 à 1.
Tous les segs d’un même groupe atteignent le repli complet simultanément,
ce qui donne un effet de « bloc de porte » uniforme.

computeMaxState() simplifié à return 1f puisque la limite est maintenant
intrinsèque à chaque seg.

La durée d’ouverture (contrôlée par openSpeed calculé depuis
zl_OpeningSpeed * 25 / |zl_Top - zl_Bottom|) reste inchangée -> même temps
d’ouverture que dans l’original.

Note ASM-fidélité : ce fix dévie volontairement de l’ASM brut sur ce
point précis. Le moteur 2.5D Amiga produisait le même « froissement » mais ne
le rendait pas perceptible. En 3D JME on choisit la cohérence visuelle.

Vérification UV (texture reste fixée dans le monde)

Le vShift = (riseAmount * 32) / tileH continue de garantir que la texture
est perspective-correct fixée dans l’espace monde :
– À state=0 : vShift=0, texture pleine
– À state=s : V au bas de la portion visible = vOffset + s * vM =
exactement la même V qui était à cette hauteur monde dans la position fermée
– À state=1 : vShift=vM, V_bot = V_top, texture collapsée à une ligne ✓

Fix lift (LiftControl.java)

Translation au niveau du Node parent au lieu du seul Geometry du sol :

// Avant
for (Spatial child : liftNode.getChildren()) {
    if (!(child instanceof Geometry geo)) continue;
    if (!geo.getName().startsWith("lift_floor_")) continue;
    geo.setLocalTranslation(0f, deltaY, 0f);
}

// Après
liftNode.setLocalTranslation(0f, deltaY, 0f);

Tous les enfants (sol + 4 cotés lift_side_*) montent ensemble -> cabine
d’ascenseur cohérente.

Fichiers modifiés

  • world/DoorControl.java : updateMeshes (riseAmount par-seg) +
    computeMaxState (simplifié)
  • world/LiftControl.java : updateFloorMesh (translation Node parent)
  • tools/LevelSceneBuilder.java : ajout méthode parseLiftWallEdges(json)
    qui parcourt lifts[].walls[].edgeId du JSON. La méthode était appelée
    ligne 154 mais jamais définie (vestige de la session 99) -> erreur de
    compilation. Ajoutée pour usage futur (skip rendu statique des walls
    d’entrée/sortie de lift) avec TODO clair côté call site.

À vérifier après build

  • ./gradlew run (pas besoin de buildScenes – changements purement runtime)
  • Porte zone 5 (level A entrée) : panneau chevron jaune/noir qui se replie
    vers le plafond comme un bloc uniforme
  • Porte zone 132 (rouge, large) : même effet, plus de panneaux à hauteurs
    désynchronisées
  • Lift zone 104 (level A) : sol + parois montent ensemble
  • Toutes les autres portes du level A (11, 30, 48, 52, 54, 57, 68, 74, 96)

Laisser un commentaire

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