Author Topic: [Explications] Décomposition du code .map  (Read 922 times)

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
[Explications] Décomposition du code .map
« on: March 12, 2008, 12:17:37 PM »
Bonjour

Apparemment, cela pourrait servir à d'autres, alors je vais vous exposer ce que je sais des simple path mesh, en matière "map brute".

Si vous avez essayé d'ouvrir votre .map avec le bloc-notes (je ne travaillerai qu'au bloc notes, mais Word Pad est équivalent, et Notepad++ aussi je crois), vous avez du voir qu'elle était "lisible". En tout cas, à l'inverse d'un bsp, votre map ne contient pas un flattera de signes bizarres (essayez d'ouvrir un .bsp au bloc notes!).

Voici la composition globale d'un .map:

Quote
{Accolade d'ouverture du fichier}
"[Mot]" "[Mot]"
===> Plusieurs fois dans certaines map, avec des mots différents
// Brush [Numéro]
{Accolade d'ouverture}
[Vecteur] [Vecteur] [Vecteur] [Mot] [Nb] [Nb] [Nb décimal] [nb] [nb] [nb] [nb] [nb] +[surfaceparm Mot]
===> Plusieurs fois aussi, généralement, on en a 6, mais cela n'est pas obligatoire!
===> Le +[surfaceparm Mot] n'est pas toujours présent
{Accolade de fermeture}
===> Ce pavé est répété de nombreuses fois

// Entity [Numéro]
{Accolade Ouvrante}
"[Mot]" "[Mots(s) / Nb]"
===> Plusieurs fois aussi
}

==> Et ce pavé est aussi présent plusieurs fois

{Accolade fermante}

Je l'accorde, ce n'est pas encore bien clair.
Je n'ai pas réussi à percer le "mystère" des brushs pour le moment, mais le reste est très aisé à comprendre. Comme dans tout système informatique, il faut délimiter les "pavés" de code, c'est le rôle des accolades:

Quote
{ //Ouverture du fichier
"Clef1 du worldspawn" "valeur1"
//Exemple: "suncolor " "75 60 60"
//Plusieurs clefs peuvent etre mises.
//L'encadrement de ces clefs et valeurs par des guillemets explique
//très facilement le fait qu'il est INTERDIT de mettre des guillemets dans
//le nom de la clef, ou dans sa valeur. En effet, si on met des guillemets, on a:
//"Texte" "J'ai dit "Bienvenue", compris?!"
//Or, les guillemets délimitent les mots. Voilà comment le jeu comprendrait la ligne:
//"Texte sera la clef" "J'ai dit  sera la valeur de 'texte'"
//Bienvenue n'est pas une commande connue!!!
//", compris?! est le nom de la clef suivante"
//Or, la ligne suivante sera de la forme: "Texte" "Valeur"...
//Donc "Texte" deviendra la valeur de la clef ", compris?!" précédemment donnée!

//D'où les gros buggs!


//Ensuite, on indique qu'il s'agit du brush numéro "n" (n est un entier positif ou nul).
//Cette ligne étant précédé d'un double-slash, "//", elle ne sera lue que par le logiciel
//Et ne fais donc pas partie intégrante de la carte.

//brush 0
{ //On ouvre le pavé du brush
# Lignes de codes inconnues pour moi
} //On referme


//Certains "brushs" sont des Path, de la forme:


// brush 214
 {
  patchDef2
  {
   Wall/Lycee11
   ( 3 3 0 -2147483648 0  )
(
( ( -5311 736 -240 0.718750 0.199219 ) ( -5315 736 -240 0.718750 0.199219 ) ( -5315 736 -256 0.718750 0.214844 ) )
( ( -5311 1016 -240 0.992188 0.199219 ) ( -5315 1016 -240 0.992188 0.199219 ) ( -5315 1016 -256 0.992188 0.214844 ) )
( ( -5311 1296 -240 1.265625 0.199219 ) ( -5315 1296 -240 1.265625 0.199219 ) ( -5315 1296 -256 1.265625 0.214844 ) )
)
  }
 }


//Décomposons:
//On retrouve le numéro de notre "brush", qui en fait n'est qu'un SPM
//C'est vrai, les programmeurs ont été un peu médiocres sur le fait de mettre
//les brushs "volumétriques" (habituels) avec les SPM sous la même appellation "brush"

// brush 214
 { //On ouvre. L'espace importe peu normalement, il permet juste de mieux voir que c'est un SPM
  patchDef2 //Il se peut qu'il existe PatchDef1, une autre forme de SPM...
//En tout cas, cette ligne indiquera que le pavé suivant est un SPM.
//Plusieurs SPM peuvent donc, apparemment, être "soudés" dans un même brush (intéressant!)
  { //On ouvre le code du SPM même
   Wall/GreyWall //On donne la texture de TOUT ce SPM
   ( 3 3 0 -2147483648 0  ) //Les codes de base:
//En premier, le nb N' de colonnes de verticles (=sommets), IMPAIR!!!
//Ensuite, le nb N de lignes de verticles, IMPAIR aussi (sinon des lignes sont non-finies)
//Ensuite, apparemment, 3 constantes sont là "0",  "-2147483648" et "0"...
//Ces valeurs restent bonnes quelque soit le SPM apparemment, si je les décode
//je vous le dirai!

( //Ensuite, on présente cela comme un tableau!
//D'abord, la colonne 1:
( ( X_ligne1 Y_ligne1 Z_ligne1 S_ligne1 T_ligne1 ) ( X_ligne2 Y_ligne2 Z_ligne2 S_ligne2 T_ligne2 ) ... ( X_ligneN Y_ligneN Z_ligneN S_ligneN T_ligneN ) )
//Ensuite, la colonne 2
( ( X_ligne1 Y_ligne1 Z_ligne1 S_ligne1 T_ligne1 ) ( X_ligne2 Y_ligne2 Z_ligne2 S_ligne2 T_ligne2 ) ... ( X_ligneN Y_ligneN Z_ligneN S_ligneN T_ligneN ) )
//Puis la 3, la 4 etc... et la N' colonne, la dernière
( ( X_ligne1 Y_ligne1 Z_ligne1 S_ligne1 T_ligne1 ) ( X_ligne2 Y_ligne2 Z_ligne2 S_ligne2 T_ligne2 ) ... ( X_ligneN Y_ligneN Z_ligneN S_ligneN T_ligneN ) )
) //On ferme le SPM définit par la texture et le code N' colonnes N lignes
  }//On ferme le SPM définit par "PatchDef2"
 }//On ferme le brush


//Et maintenant, les entités. On donne le numéro de l'entité, comme précédant:

// entity 2325
{ //Ouverture de la définition de cette entité
"Clef" "Valeur"
//Comme pour le worldspawn, on voit que l'ajout de guillemets dans la clef ou la valeur bugg
//'testanim', il me semble, est spécifique à Radiant et peut-etre au compilateur.
//Elle indique le nom de l'animation à utiliser dans l'affichage de MOHRadiant
//Ou lors de la compilation (pour les ombrages probablement)

"angle" "90"
"origin" "1272.00 2234.00 248.00"
"testanim" "idle"
"model" "Static/Table2.tik"
"scale" "1.50"
"classname" "Static_Tables_TableEleve"
}

//On a ouvert une accolade au début, alors, on la referme!
}

Pour le SPM, on a 5 types de valeurs:
X_(colonne A, ligne B)
Y_(colonne A, ligne B)
Z_(colonne A, ligne B)
S_(colonne A, ligne B)
T_(colonne A, ligne B)

Les valeurs X, Y et Z sont les positions des points dans le Repère Orthonormal du jeu (c'est à dire par rapport au (0; 0; 0) habituel, utilisé dans la grille de MOHRadiant et dans la commande "coord" de la console MOHAA).
Les valeurs S et T servent aux textures.
La texture est prise comme étant un carré de coté 1. Exemple:
Si l'image fait 512x1024, les deux cotés seront comptés comme faisant 1 unité de longueur. Le jeu va donc créer un repère orthogonal (et non orthonormal), dont le centre est situé sur l'angle en haut à gauche de l'image, ayant comme vecteur d'abscisse le vecteur "bord haut de l'image, de la gauche vers la droite", et de vecteur d'ordonnée le vecteur "bord gauche de l'image, du haut vers le bas".
La valeur S est donc multiplicative du vecteur d'ordonnées, et la valeur T est multiplicative du vecteur d'abscisses.

Petit schéma:

Voici un SPM déformé volontairement.
En haut à gauche, "posé par dessus", un exemple de texture.



Les valeurs (S,T) ne sont rien si elles sont prises seules. Il faut forcément deux couples (S, T) pour pouvoir palcer notre texture (car un représentant de vecteur possède 2 points).
Grâce à (S, T) et à (S', T') qui sont deux couples de valeurs, on va pouvoir placer notre texture comme on le désire!

Supposons un SPM de N' colonnes et de N lignes. On aura donc N' * N couples (S,T), que l'on nommera:

(S, T)[N', N]

On fera référence à la valeur S du couple (S, T)[N', N] par la notation S[N',N], et de même, la valeur T de (S, T)[N', N] sera T[N', N].
Le verticle de la colonne K' et de la ligne K sera noté v[K', K] (on supposera que, pour un verticle v[A,B], on a A € [1; N'] et B € [A; N])

Entre les verticles v[K', K] et v[K', (K+1)], la répétition horizontale de la texture entre ces sommets sera de:

(S[K', K] - S[K', (K+1)])

Et la répétition verticale de la texture entre les verticles v[K', K] et v[(K'+1), K] sera:

(T[K', K] - T[(K'+1), K])

Mais la texture a, peut-etre, été déjà répétée dans des sommets précédents! il faut donc ajouter, (S,T)[K', K]. Au final, la position de la texture au point v[K'+1, K+1] sera donnée par

(S, T)[K'+1, K+1]


Voici l'exemple du SPM de tout à l'heure. Ici, on a les valeurs:
(S, T)[1, 1] = (0, 0)
(S, T)[1, 2] = (0, 1)
(S, T)[1, 3] = (0, 2)

(S, T)[2, 1] = (0, 1)
(S, T)[2, 2] = (1, 1)
(S, T)[2, 3] = (2, 1)

(S, T)[3, 1] = (2, 0)
(S, T)[3, 2] = (2, 1)
(S, T)[3, 3] = (2, 2)

Résultat:



Des que le système de brush aura été percé, je vous en ferait part.
« Last Edit: March 12, 2008, 01:39:21 PM by snaky »

tourist-tam

  • Tailleur de maps
  • Posts: 420
[Explications] Décomposition du code .map
« Reply #1 on: March 12, 2008, 02:43:24 PM »
Han! 0_0

Merci snaky ^_^

Pour les Brush c'est beaucoup plus simple, d'apres moi. Par exemple un brush comme celui ci-dessous:
Code: [Select]
// brush 1
{
( 128 128 8 ) ( -128 128 8 ) ( -128 128 0 ) common/caulk 0 0 0.00 1 1 0 160 0
( -128 120 8 ) ( 128 120 8 ) ( -128 120 0 ) common/caulk 0 0 0.00 1 1 0 160 0
( 128 -128 0 ) ( -128 128 0 ) ( 0 0 128 ) common/caulk 0 0 0.00 1 1 0 160 0
( 128 128 0 ) ( -128 -128 0 ) ( 0 0 128 ) common/caulk 0 0 0.00 1 1 0 160 0
( -128 128 0 ) ( -128 120 8 ) ( 128.000137 124 4 ) common/caulk 0 0 0.00 1 1 0 160 0
( -128.000137 120 120 ) ( -128.000137 128 128 ) ( 128.000137 124 124 ) common/caulk 0 0 0.00 1 1 0 160 0
}

il faut lire par ligne:
  • (point A(x,y,z))
  • (point B(x,y,z))
  • (point C(x,y,z))
  • Nom de la texture
  • distance X (horizontale) par rapport a l'origine
  • distance Y (verticale) par rapport a l'origine
  • rotation appliquee (en degree)
  • dimension rapportee sur l'axe des X
  • dimension rapportee sur l'axe des Y
Par contre aucune idee pour les 3 derniers elements, mais je pense que ca doit etre lie a la facon dont est appliquee la texture.


Tam
« Last Edit: March 12, 2008, 06:24:02 PM by tourist-tam »

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
[Explications] Décomposition du code .map
« Reply #2 on: March 12, 2008, 03:15:12 PM »
Eheh ^^

Un indice tiens, j'avais aps remarqué, mais:

-2147483648 = - (2^31) = -[ 2^ (2^5 - 1) ]

Une piste peut-etre... ;)

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
[Explications] Décomposition du code .map
« Reply #3 on: June 22, 2008, 04:49:53 PM »
Je reprends ce topic un peu! J'ai besoin de trouver le fonctionnement exact de ces .map et des brushs pour améliorer le compilateur du jeu, et tirer des effets pré-calculés de NormalMap, BumpMap et autres reliefs texturés.

J'ai un soucis: l'idée de tourist-tam sur les brushs était bonne, mais le brush en question est un cube, donc, possède 6 faces carrés. Or je n'ai que 6 triangles définis dans le .map  hummm

Si vous avez des pistes, je prends !

Woozie

  • Tailleur de maps (expérimenté)
  • Posts: 947
    • http://
[Explications] Décomposition du code .map
« Reply #4 on: August 03, 2008, 10:45:31 PM »
Selon le triangle, ça peut former la moitié d'une face du carré, dans ce cas y'as un moyen de dvisier en 2 ou un truc dans le genre?

Bien sur si le troncgle n'est pas rectangle, on pourra pas utiliser l'idée de la division à partir du brush carré.

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
[Explications] Décomposition du code .map
« Reply #5 on: August 04, 2008, 12:26:46 AM »
C'est bon, j'ai décomposé le principe.

Dans le fichier map sont stockées les faces. Une face est inscrite dans un plan (les points d'une face sont coplanaires). De plus, toute face d'un brush est convexe.
MOHAA utilise une ligne de code pour chaque face.
Cette ligne commence par 3 points, ces trois points définissant un plan. L'ordre des points permet de trouver un 4e point, créant ainsi un tétraèdre DIRECT. Ce point peut s'obtenir aussi par le produit vectoriel AB par AC, en supposant que les points sauvés sont A, B et C (dans l'ordre).
Ce 4e point permet ainsi de définir un demi-espace, défini par les 3 points A B et C et par le 4e point.
Le brush est l'ensemble des points situés dans tous les demi-espaces définis par chaque plan.

Ensuite, le nom de la texture est donnée.
Apres, la position horizontale, puis la position verticale
Ensuite, la rotation
Apres, la taille horizontale puis la verticale

Les 3 derniers je ne sais plus  hummm  

Woozie

  • Tailleur de maps (expérimenté)
  • Posts: 947
    • http://
[Explications] Décomposition du code .map
« Reply #6 on: August 04, 2008, 06:20:01 PM »
A ben ça va alors^^. Plus besoin de se compliquer avec mes moitiés de faces de carrés.