Aller au contenu principal

Session 103 — Épaisseur des portes + animation fluide porte 132

Symptômes (après session 102)

  • Porte 132 (rouge) : s’ouvre par à-coups, animation saccadée au lieu
    d’être fluide.
  • Toutes les portes : textures correctes, glissement uniforme, mais
    le panneau n’a « pas de fond » : c’est un quad mince, on perçoit l’absence
    d’épaisseur quand on regarde sous un angle ou qu’on s’approche près.

Fix à-coups (DoorControl.java)

Le seuil de redessin du mesh était trop élevé pour les portes lentes :

if (Math.abs(state - prev) > 0.002f) updateMeshes(doorNode);

Pour la porte 132 (openSpeed=4 Amiga, hEditor=704), state croît de
0.142/sec, soit ~0.0024 par frame à 60 FPS — juste au-dessus de
l’ancien seuil. La moindre variance de tpf faisait sauter des updates et
rendait l’animation saccadée.

if (Math.abs(state - prev) > 0.0001f) updateMeshes(doorNode);

Le coût d’un updateMeshes est négligeable (4 vertex + 4 UV par seg), donc
un seuil très bas est OK.

Fix épaisseur (LevelSceneBuilder.java)

Problème structurel : un panneau de porte était UN seul quad. Même avec
FaceCullMode.Off, c’est un plan sans épaisseur — le rendu trahissait
l’absence de volume.

Observation clé : pour chaque porte, il y a 2 ZDoorWalls par edge (un
rendu depuis chaque couloir voisin), avec des normales opposées car
le wall est partagé entre 2 zones d’orientation CCW inversée. Ces 2 segs
étaient précédemment superposés exactement (même XZ).

Fix : décaler chaque ZDoorWall de ε le long de sa propre normale
intérieure
:

float dxN = x1 - x0, dzN = z1 - z0;
float Ln = sqrt(dxN*dxN + dzN*dzN);
float ox = -dzN / Ln * 0.08f;  // ε = 0.08 JME = 2.5 unités Amiga
float oz =  dxN / Ln * 0.08f;
.addSeg(x0 + ox, z0 + oz, x1 + ox, z1 + oz, ...);

Comme les 2 ZDoorWalls ont des normales opposées (-dzA, dxA vs
-dzB, dxB = dzA, -dxA), après décalage ils sont séparés de 2ε ≈ 0.16
JME ≈ 5cm
. La porte a maintenant une vraie épaisseur visible.

Le joueur passe toujours à travers car la course d’animation reste large
(riseAmount = panelHeight * state avec panelHeight = yR - yF = hauteur
couloir complète) : quand state → 1, les deux faces sont totalement
remontées.

Pour tester

./gradlew buildScenes run
  • Toutes les portes : panneau visible avec une vraie épaisseur quand on
    s’en approche (plus l’effet « feuille de papier »)
  • Porte 132 (rouge) : ouverture lente mais continue, plus de saccades
  • L’effet « bloc plein qui glisse vers le haut » reste préservé

Fichiers modifiés

  • tools/LevelSceneBuilder.java : décalage des ZDoorWalls le long de
    leur normale intérieure (DOOR_OFFSET = 0.08f)
  • world/DoorControl.java : seuil updateMeshes abaissé de 0.002 à
    0.0001

Laisser un commentaire

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