Aller au contenu principal

Session 105 — Cube fermé pour les portes (top + bottom caps)

Suggestion utilisateur

Après les fixes session 103-104, les portes ont une épaisseur (2 faces
verticales séparées de 0.16 JME) et tous les pans sont synchronisés. Le
panneau ressemble déjà à un bloc 3D, mais les bords du « cube » en haut
et en bas restent ouverts. L’utilisateur a proposé :
– Plafond du panneau = top fixe à yTop
– Sol du panneau = bottom mobile qui suit l’animation (curYBot)
– Texture du plafond du couloir pour les caps (simple)

Fix : 2 caps horizontaux par pan

Dans LevelSceneBuilder.buildScene (création des Geometries de porte) :

Top cap — quad horizontal fixe à groupYTop, normale +Y, matériau du
plafond du couloir (fm[floorIdx(ceilTile)]).

Bottom cap — quad horizontal initialement à groupYBot, normale -Y,
même matériau, mobile : DoorControl le translate au runtime via
setLocalTranslation(0, effectiveRise, 0) pour qu’il suive curYBot.

Les 4 corners de chaque cap = 2 corners du front (anchor[0..3]) + 2
corners du back (anchor – 2*ofs). Pas besoin de back face explicite : le
front du couloir voisin sert naturellement de back vu d’ici.

Pourquoi setLocalTranslation plutôt que vertex update

Un quad horizontal qui monte = translation pure en Y, pas de déformation.
setLocalTranslation sur un Geometry est plus simple et plus rapide qu’une
réécriture du buffer Position à chaque frame :
– Mesh static (pas de buffer dynamique)
– 1 seule opération JME au lieu de 12 floats réécrits
– Le delta transform est automatiquement appliqué par JME au rendu

Modifications

LevelSceneBuilder.java :
addSeg accepte maintenant un param ceilTile (slot 11 du seg array)
– L’appel à addSeg passe z.ceilTile() (= ceilTile de la zone-couloir
courante)
– Après dn.attachChild(sg) (front face), création de 2 caps :
seg_{i}_top avec faceType="top"
seg_{i}_bot avec faceType="bottom"
– Nouveau helper makeCapGeo(...) : quad horizontal 4-vertices, UV
type sol/plafond (coords XZ scaled), normale up ou down

DoorControl.javaupdateMeshes :

String faceType = geo.getUserData("faceType");
if ("top".equals(faceType)) continue;        // fixe
if ("bottom".equals(faceType)) {              // mobile
    float eR = Math.min(maxPanelHeight * state, panelHeight);
    geo.setLocalTranslation(0f, eR, 0f);
    continue;
}
// faces verticales : logique existante

Les faces verticales (front, ou null par défaut) suivent la logique de
session 104 (vertex update avec effectiveRise).

Pour tester

./gradlew buildScenes run

(Rebuild nécessaire — changement de géométrie au build).

Observations attendues :
– Quand on regarde une porte fermée par-dessous (en s’approchant et en
levant la tête), on voit le bottom cap avec la texture du plafond
– En s’éloignant et en regardant de loin, le panneau a une silhouette
3D
correcte (plus de « feuille de papier » même avec un angle de vue
rasant)
– Pendant l’ouverture, le bottom cap monte avec le panneau (visible si
le joueur passe en dessous)
– Quand la porte est complètement ouverte, tout le doorNode est cullé
(CullHint.Always quand state >= 0.999), caps inclus

Limites connues

  • Pas de left/right caps (épaisseur 5cm = 2*0.08 JME, peu visible).
    Peut être ajouté plus tard si on remarque un « bord ouvert » sous certains
    angles
  • Z-fighting possible entre les 2 caps top/bottom des 2 fronts d’un même
    edge (couloir A et B). Comme les positions XZ sont identiques, en pratique
    pas de flickering visible (les depths matchent exactement)
  • La texture du plafond peut différer entre les 2 couloirs (zone A vs zone
    B). Chaque seg utilise le ceilTile de SA zone-couloir, donc on peut avoir
    un mix visuel sur les caps. Acceptable comme première passe.

Fichiers modifiés

  • tools/LevelSceneBuilder.java : addSeg + ceilTile, cap creation,
    makeCapGeo helper
  • world/DoorControl.java : updateMeshes branchement faceType

Laisser un commentaire

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