Aller au contenu principal

Session 70 — Fix portes : detection par edgeId, priorite vue interieure

Symptomes apres session 69

Malgre les corrections de la session 69 (vitesses + donnees texture par pan),
deux bugs visuels persistaient :

  1. Pans de porte mal textures (image utilisateur) : la porte jaune-noire
    de la zone 30 (level A, 6 pans) avait 2 pans affichant le motif
    chevrondoor correct mais 4 pans apparaissaient noirs/lisses,
    comme si la texture etait absente ou fortement distordue.

  2. Portes non detectees comme animees : la porte rouge du niveau A
    (zones 48, 52, 54, 57, 68, 74 avec bottom=-256) apparaissait comme
    un mur statique geant rouge qui occupait toute la piece, et
    ne bougeait pas du tout. Aucune animation d’ouverture.

Diagnostic

Bug #1 – Textures incorrectes : chaque pan de porte est present DEUX FOIS
dans le graphe du niveau :
– Une fois du cote zone-porte (vue interieure, texture de porte correcte)
– Une fois du cote zone voisine (vue exterieure, texture du couloir)

La de-duplication geometrique dans DoorAccum.addSeg gardait la PREMIERE
entree rencontree, peu importe qu’elle soit la vue interieure ou exterieure.
Selon l’ordre de traversal de la Map zones, certains pans recevaient la
bonne texture (vue interieure) et d’autres la mauvaise (vue exterieure).

Bug #2 – Portes non detectees : le code utilisait un filtre heuristique
Math.abs(botH) <= DOOR_FLOOR_THRESH (=8) pour decider si un mur est un
pan de porte. Ce filtre eliminait toutes les portes qui ne commencent
pas au sol
(zones 48, 52, 54 avec bottom=-256). Ces portes etaient
alors traitees comme murs statiques avec des hauteurs enormes.

Or, l’original (zone_liftable_pvs.c) n’utilise AUCUN critere de hauteur :
un mur est un pan de porte ssi son edgeId est reference dans la liste
des ZDoorWall d’une porte.

Fix

LevelSceneBuilder.java :

  • Detection par edgeId (et non par hauteur) : pour chaque mur adjacent
    a une zone-porte (otherZone != 0 && doorZoneDefs.containsKey(zid|oz)),
    on retrouve son edgeId via findEdgeIdForSegment() puis on teste
    doorEdgeGfx.containsKey(eid). C’est le critere exact de l’original.

  • Priorite vue interieure : DoorAccum.addSeg() accepte un nouveau
    parametre booleen isInsideView. Quand la vue interieure arrive alors
    que la vue exterieure est deja en place pour la meme geometrie, les
    donnees texture (texIdx, fromTile, yOffset) sont ecrasees par
    les bonnes valeurs (interieures). Le segment devient
    [x0, z0, x1, z1, texIdx, fromTile, yOffset, isInsideView] (8 floats
    au lieu de 7).

  • Suppression des heuristiques de hauteur : les constantes
    DOOR_FLOOR_THRESH=8 et DOOR_HEIGHT_MIN=64 ne sont plus consultees
    (elles restent declarees pour reference). Le fallback pour « portes
    non-repertoriees » est egalement supprime puisqu’il n’a plus lieu
    d’etre : un mur est une porte ssi son edgeId est dans doorEdgeGfx.

Verification

Apres rebuild (./gradlew buildScenes), tester sur level A :
– Porte zone 30 (6 pans, hazard stripes jaune/noir) : tous les pans doivent
afficher la meme texture correcte
– Portes rouges zones 48/52/54/57/68/74 (bottom=-256, en hauteur dans les
couloirs) : doivent s’animer normalement au passage du joueur
– Autres portes (5, 11, 96, 132) : continuent de fonctionner normalement

Code en reference

  • zone_liftable_pvs.c : Zone_InitDoorList et le parcours des ZDoorWall
    utilisant uniquement zdw_EdgeID pour le match
  • Pas d’utilisation de hauteur minimale / maximale pour la detection de porte

Laisser un commentaire

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