Probleme
Depuis session 75, le modele vectobj de l’arme etait charge correctement (logs de
bbox OK, 4-8 animations detectees) mais rien ne s’affichait a l’ecran. Cube de
debug invisible aussi.
Diagnostic (via cubes colores)
Apres avoir isole le probleme avec plusieurs cubes de test :
– ✅ Cube vert statique au monde : visible
– ✅ Cube jaune statique attache dans WeaponViewAppState.initialize() : visible
– ❌ Cube magenta dont la position est update chaque frame depuis la camera : invisible
Les logs ont revele que le cube magenta etait dans la mauvaise direction :
dir=(0.48, -0.41, 0.77) delta=(-0.71, 0.79, -3.02) <- Z OPPOSE
La camera regardait vers +Z (dir.z > 0) mais l’arme etait calculee avec un
delta.z < 0, donc derriere la camera.
Cause racine
cam.getRotation() en JME a une convention inversee par rapport a
cam.getDirection(). Si on fait :
Vector3f offset = new Vector3f(0, 0, -1); // -Z local = devant
Vector3f worldOffset = cam.getRotation().mult(offset);
on obtient un vecteur qui ne correspond pas a cam.getDirection(). La rotation
quaternion de la camera caracterise la camera-as-spatial (sa position dans la
scene), pas sa direction de vue.
Solution
Utiliser les vecteurs de la camera directement :
Vector3f forward = cam.getDirection(); // vers l'avant, coherent
Vector3f left = cam.getLeft();
Vector3f up = cam.getUp();
// Composer la position manuellement
Vector3f pos = cam.getLocation().clone();
pos.addLocal(left.mult(-offsetX)); // X positif = a droite
pos.addLocal(up.mult(offsetY)); // Y positif = en haut
pos.addLocal(forward.mult(-offsetZ)); // Z negatif = devant
Et pour que JME ne cull pas l’arme a tort :
weaponRoot.setCullHint(Spatial.CullHint.Never);
Architecture finale simplifiee
Au lieu de la chaine cameraFollower > weaponHolder > weaponCentering > modelWrapper
on a une seule hierarchie :
rootNode
└─ weaponRoot (CullHint.Never, position+rotation update chaque frame)
└─ model (pre-normalise : centre sur origine + scale uniforme)
Valeurs finales
WEAPON_OFFSET = (0.25, -0.25, -0.8): droite, bas, devant en unites JMEWEAPON_ROTATION = rotY(PI): 180deg pour orienter le canon vers l’avantTARGET_WEAPON_SIZE = 0.5: diagonale max de la bbox apres normalisation- Near plane camera : 0.05 (deja OK dans GameAppState)
Fichiers modifies
src/main/java/com/ab3d2/weapon/WeaponViewAppState.java— reecriture complete
avec pattern simple + documentation detaillee du bug de convention camera
Lecon pour l’avenir
Ne jamais utiliser cam.getRotation().mult(offset) pour calculer une position
relative a la camera en coord monde. Toujours utiliser getDirection()/getLeft()/
getUp() explicitement. Ce piege peut potentiellement re-surgir pour d’autres
objets « screen overlay » (HUD 3D, crosshair, particules en vue FPS, etc.).
TODO session 77 (prochaine etape : tir)
- Clic gauche = tir, avec cadence specifique par arme (ShootT_Delay_w)
- Spawn de projectile visible (modele 3D ou sprite billboard)
- Collision projectile contre murs/portes/ennemis
- Son de tir (samples extraits session 67)
- Animation de tir declenchee via
playFireAnimation()(deja en place) - Muzzle flash (particule ponctuelle a la sortie du canon)