Author Topic: Faire Sa Carte à Partir D'un Bitmap  (Read 1584 times)

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« on: September 23, 2008, 10:42:16 PM »
Bonsoir à tous!

Je sais que plus beaucoup de joueurs et encore moins de mappeurs s'interressent à MOHAA (peut-etre cela changera-t-il un jour), mais je viens de terminer un petit programme qui pourrait etre tres sympatique pour les réticents du mapping !

Il permet de passer d'une image bitmap 2D à une carte 3D, en quelques clics et quelques touches!
Premièrement, il vous faut une image 2D au format bitmap (=paint 24 bits), avec seulement des pixels blancs pour le fond, et noir pour les murs.
En voici un exemple:

L'image tirée du net:


Image modifiée pour le programme (pixels gris supprimés, noir & blanc uniquement:)


Ensuite, vous avez juste à la copier dans le dossier où se trouve le programme, puis à lancer ce dernier. Le fichier image est détecté automatiquement (enfait, le programme prend par défaut le fichier .bmp dont le nom est le premier dans l'ordre alphabétique). Si ce n'est pas le bon fichier, il vous suffit de changer le nom inscrit dans la boite de dialogue par le nom de votre fichier. Validez, le programme cogite !

Voici le résultat:



Améliorations prévues:
- Régler le problème qui survient lorsque 4 pixels ou plus sont accolés (le carré est transformé en 2 bandes de 2 pixels horizontales et 1 verticale)
- Ajouter le toit et le plafond à la carte compilée, qui doivent suivre les contours des murs externes!
- Ajouter la possibilité d'indiquer la texture à employer pour chaque face de mur
- Faire l'ajustement automatique des angles de 2 murs ou plus


Le programme ne reconnait pas les diagonales! Il les transformera en une succession de murs formant un "crénelage". Ce programme est donc surtout destiné à faire la base d'une maison, d'un immeuble ou de tout autre habitation du genre. Il ne sera que peu utile pour une map extérieur (car il ne fait pas les dénivelés de terrain).

NINJAHN62

  • Tailleur de maps (expérimenté)
  • Posts: 556
    • http://
Faire Sa Carte à Partir D'un Bitmap
« Reply #1 on: September 23, 2008, 10:50:08 PM »
Excellent Snaky , reste a mettre les "portals" :paie  et prevoir un GPS  !!  hummm
   NinjaHN62
Jusque là ça vas ....Jusque là ça vas ....Jusque là ça vas ...

Dedoum

  • Legomaniaque
  • Posts: 1477
    • http://www.lord-of-death.com
Faire Sa Carte à Partir D'un Bitmap
« Reply #2 on: September 23, 2008, 11:19:29 PM »
Finalement, avec ca, tu créé ta map en .bmp et tu l'exporte en .map  :wacko:  ?

Si c'est bien ca, c'est excellement excellent !
S'il n'y a pas de solution, c'est qu'il n'y a pas de problème ! (Proverbe Shadok)

tourist-tam

  • Tailleur de maps
  • Posts: 420
Faire Sa Carte à Partir D'un Bitmap
« Reply #3 on: September 24, 2008, 01:09:12 AM »
sympa ^_^

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #4 on: September 24, 2008, 06:55:50 PM »
Quote
Finalement, avec ca, tu créé ta map en .bmp et tu l'exporte en .map  :wacko:  ?
Exact Dedoum ! Mais la carte ainsi exportée demande encore des retouches souvent (pour ajouter des paths, des LODS, des models et un player_start par exemple).
« Last Edit: September 24, 2008, 06:56:00 PM by snaky »

Dedoum

  • Legomaniaque
  • Posts: 1477
    • http://www.lord-of-death.com
Faire Sa Carte à Partir D'un Bitmap
« Reply #5 on: September 24, 2008, 10:53:24 PM »
J'ai bien comprit, mais ce que je veux dire, c'est qu'il est capable de te gérer une structure de map (et c'est déjà excellent)!

Sinon, comment gère t'on l'espace et les coodronnées entre le bmp et le .map ?
Plus précisement, une map qui fait 512x512x512, le bmp doit faire 512x512 ?
Et la hauteur des brushs ? elle se définit ou c'est un format automatique de 82 ou 120 par exemple ?
« Last Edit: September 24, 2008, 10:54:00 PM by Dedoum »
S'il n'y a pas de solution, c'est qu'il n'y a pas de problème ! (Proverbe Shadok)

Tropheus

  • Legomaniaque
  • Posts: 1432
    • http://tropheus.tropheus.free.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #6 on: September 25, 2008, 12:56:58 AM »
voila bien longtemps que j'avais pas trainer par ici

mais géniale ton invention "petit scarabée".

++

Troph




tourist-tam

  • Tailleur de maps
  • Posts: 420
Faire Sa Carte à Partir D'un Bitmap
« Reply #7 on: September 25, 2008, 03:11:19 PM »
Il y aurait moyen de generer ca pour d'autre format de fichier map (ceux dans la serie des CoD)?

D'ailleurs tu codes ca en quel language? :)

Tam

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #8 on: September 25, 2008, 03:27:50 PM »
VBS, c'est le plus souple, ca se transpose sous Linux facilement (d'apres un ami), et ca laisse le code en open-source sans devoir télécharger ces sources à part. En plus, ca permet parfois de corriger soi-même un petit soucis s'il y en a ;)

Les murs sont réglés à une hauteur par défaut de 96. Je rajoutes une boite de dialogue pour permettre de changer cette valeur.

Un pixel du bitmap sera rendu en un mur de 8x8 unités de large, mais cette autre valeur peut se modifier aussi (seconde boite de dialogue? à ce compte-là, un fichier texte de configuration devrait etre mieux ^^).

Je crois que les codes des maps de COD sont identiques à ceux de MOHAA (pour les brushs en tous cas).

Tu peux toujours essayer ;)
N'ayant rien pour uploader, voici le code:

Code: [Select]
'On Error Resume Next
'Passe d'un bitmap à un .map de MOH/QuakeLike

Const C_BfType = 19778

'------------------------------------------------------------------------'
Const UnitPerPix = 8 'echelle
Const WallHeight = 96 'Hauteur des murs (unites)
Const TexVal = "caulk 0 0 0.00 1 1 0 0 0 "
'------------------------------------------------------------------------'

dim WSS, FSO, lfold, pic, Matrix
set WSS = WScript.CreateObject("WScript.Shell")
set FSO = CreateObject("Scripting.FileSystemObject")
lfold = FSO.GetParentFolderName(WScript.ScriptFullName) & "/"
echo "Dossier actuel: " & lfold
set Matrix = CreateObject("Scripting.Dictionary")

set pic = FSO.OpenTextFile(lfold & "image.bmp", 1)

bfType = Read_IntSig(pic, 16)
if not bfType = C_BfType Then bugg "Le fichier n'est pas un bitmap valide!" & chr(10) & "Le code d'en-tête (bfType) " & bfType & " ne correspond pas au bfType attendu " & C_bfType, "700A001"
pic.Read(8)
bfOffBits = Read_IntUns(pic, 32)
BiSize = Read_IntUns(pic, 32)
BiWidth = Read_IntUns(pic, 32)
BiHeight = Read_IntUns(pic, 32)
BiPlanes = Read_IntUns(pic, 16)
BiBitCount = Read_IntUns(pic, 16)
if not BiBitCount = 24 Then bugg "Le fichier bitmap doit etre en 24bits par pixel, et non pas en " & BiBitCount & " bits par pixels. Veuillez l'ouvrir dans un logiciel graphique (p.e. MSPaint) puis le sauvegarder en 24 bits", "700A002"
BiOctCount = Int(BiBitCount/8.0)
BiOctCols = BiOctCount*BiWidth

while BiOctCols > 4
BiOctCols = BiOctCols-4
WEnd
BiOctCols = 4-BiOctCols

echo "Type: " & BfType
echo "OffBits: " & BfOffBits
echo "Size: " & BiSize
echo "Width: " & BiWidth
echo "Height: " & BiHeight
echo "BitCount: " & BiBitCount
echo "Octets de complétion de ligne: " & BiOctCols

pic.Read(BiSize-16)
echo "Initialisation OK..."

for l=1 To BiHeight
Matrix.Add l, CreateObject("Scripting.Dictionary")
for c=1 To BiWidth
  Matrix.Item(l).Add c, CreateObject("Scripting.Dictionary")
  tp2 = 0
  for b=1 To BiOctCount
   Matrix.Item(l).Item©.Add b, Read_IntUns(pic, 8)
   tp2 = tp2+Matrix.Item(l).Item©.Item(B)
  next
  Matrix.Item(l).Item©.Add BiOctCount+1, tp2
Next
if not BiOctCols = 0 Then pic.Read(BiOctCols)
Next
echo "Récupération des données du bitmap OK..."

pic.close
set pic = FSO.OpenTextFile(lfold & "image.bmp", 1)
set dest = FSO.CreateTextFile(lfold & "image_s.bmp", TRUE)
set Colorized = CreateObject("Scripting.Dictionary")
dest.write pic.Read(2+8+4+4+4+4+2+2+BiSize-16)
pic.close

for l=1 To BiHeight
Colorized.Add l, CreateObject("Scripting.Dictionary")
for c=1 To Biwidth
  if Matrix.Item(l).Item©.Item(4) = 0 Then
   A = Array(Matrix.Item(l).Item(c+1).Item(4), Matrix.Item(l+1).Item©.Item(4), Matrix.Item(l).Item(c-1).Item(4), Matrix.Item(l-1).Item©.Item(4))
   if A(0)=0 Then B="1" Else B="0"
   if A(1)=0 Then B=B&"1" Else B=B&"0"
   if A(2)=0 Then B=B&"1" Else B=B&"0"
   if A(3)=0 Then B=B&"1" Else B=B&"0"

   Colorized.Item(l).Add c, Split(B, "", -1, 1)

   if B="0000" Then
    dest.write chr(000) & chr(0) & chr(0)
   elseif B="0001" Then
    dest.write chr(255) & chr(0) & chr(0)
   elseif B="0010" Then
    dest.write chr(000) & chr(0) & chr(255)
   elseif B="0011" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="0100" Then
    dest.write chr(255) & chr(0) & chr(0)
   elseif B="0101" Then
    dest.write chr(255) & chr(0) & chr(0)
   elseif B="0110" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="0111" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1000" Then
    dest.write chr(000) & chr(0) & chr(255)
   elseif B="1001" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1010" Then
    dest.write chr(000) & chr(0) & chr(255)
   elseif B="1011" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1100" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1101" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1110" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1111" Then
    dest.write chr(255) & chr(0) & chr(255)
   else
    bugg "Impossible de reconnaitre le code " & B & ". Il se peut que votre fichier script soit corrompu. Veuillez le télécharger de nouveau, sur le site officiel de préférence.", "700A003"
   end if
  else
   dest.write chr(255) & chr(255) & chr(255)
   Colorized.Item(l).Add c, Array(0, 0, 0, 0)
  End If
next
next
echo "Compilation des données OK..."
echo "Echelle: " & UnitPerPix & " unites radiant par pixel"
echo "Hauteur des murs: " & WallHeight

set mapf = FSO.CreateTextFile(lfold & "carte.map", TRUE)
mapf.Writeline "{"
mapf.writeline chr(34) & "classname" & chr(34) & " " & chr(34) & "worldspawn" & chr(34)
For l=1 To BiHeight
For r=1 To BIWidth
  
  if Matrix.Item(l).Item®.Item(4) = 0 Then
   rMin = r
   lMin = l
   if l+1 <= BiHeight Then ln = l+1 else ln = -1
   lp = l-1

   Do while r <= BiWidth
    if r = BiWidth Then
     rMax = r
     Exit Do
    elseif (Matrix.Item(l).Item(r+1).Item(4) = 0) Then
     If ((not ln = -1 and Matrix.Item(ln).Item(r+1).Item(4)=0) or (not lp = -1 and Matrix.Item(lp).Item(r+1).Item(4)=0)) Then
      rMax = r+1
      exit Do
     Else
      r = r + 1
     end if
    else
     rMax = r
     exit Do
    end if
   Loop

   Rows = rMax-rMin+1
   if Rows = 1 Then

    if r+1 <= BiWidth Then rn = r+1 else rn = -1
    rp = r-1
    lp = l

    Do while lp <= BiHeight
     if r = BiHeight Then
      lMax = lp
      Exit Do
     elseif (Matrix.Item(lp+1).Item®.Item(4) = 0) Then
      If ((not rn = -1 and Matrix.Item(lp+1).Item(rn).Item(4)=0) or (not rp = -1 and Matrix.Item(lp+1).Item(rp).Item(4)=0)) Then
       lMax = lp+1
       exit Do
      Else
       Matrix.Item(lp+1).Item®.Item(4) = 1 'Le pixel n'a pas de pixel en ligne, et est déjà validé en colone, donc, inutile de recalculer!
       lp = lp + 1
      end if
     else
      lMax = lp
      exit Do
     end if
    Loop
    Lines = lMax-lMin+1

   Else
    Lines = 1
   End If

   P = UnitPerPix
   W = WallHeight

   X = (rMin-1)*P
   Y = (lMin-1)*P
   U = Rows*P
   V = Lines*P

   A = "( " & X+0 & " " & Y+0 & " " & 0 & " ) "
   B = "( " & X+U & " " & Y+0 & " " & 0 & " ) "
   C = "( " & X+0 & " " & Y+V & " " & 0 & " ) "
   D = "( " & X+U & " " & Y+V & " " & 0 & " ) "
   E = "( " & X+0 & " " & Y+0 & " " & W & " ) "
   F = "( " & X+U & " " & Y+0 & " " & W & " ) "
   G = "( " & X+0 & " " & Y+V & " " & W & " ) "
   H = "( " & X+U & " " & Y+V & " " & W & " ) "

   mapf.writeline "//brush " & ((l+1)*(r-1))
   mapf.writeline "{"
   mapf.writeline A & B & C & TexVal
   mapf.writeline A & E & B & TexVal
   mapf.writeline A & C & E & TexVal
   mapf.writeline H & F & G & TexVal
   mapf.writeline H & D & F & TexVal
   mapf.writeline H & G & D & TexVal
   mapf.writeline "}"
  End If
  
Next
Next
mapf.writeline "}"
msgbox "ok"


Function Read_IntUns(file, bits)
t = 0
ri = 0
octs = Int(bits/8.0)
for i = 1 To octs
  tp = Asc(file.Read(1))
  for k=2 To i
   tp = tp*256
  next
  ri = ri+tp
next
Read_IntUns = ri
End Function

Function Read_IntSig(file, bits)
if bits = 32 Then
  ri = Array(Asc(file.Read(1)), Asc(file.Read(1)), Asc(file.Read(1)), Asc(file.Read(1)))
  if ri(3) >= 128 Then
   ri(3)=ri(3)-128
   Read_IntSig = -2147483648+(ri(0)+ri(1)*256+ri(2)*65536+ri(3)*16777216)
  else
   Read_IntSig = ri(0)+ri(1)*256+ri(2)*65536+ri(3)*16777216
  end if
elseif bits = 16 Then
  ri = Array(Asc(file.Read(1)), Asc(file.Read(1)))
  if ri(1) >= 128 Then
   ri(1)=ri(1)-128
   Read_IntSig = -32768+(ri(0)+ri(1)*256)
  else
   Read_IntSig = ri(0)+ri(1)*256
  end if
elseif bits = 8 Then
  ri = Asc(file.Read(1))
  if ri >= 128 Then
   ri=ri-128
   Read_IntSig = -128+ri
  else
   Read_IntSig = ri
  end if
else
  msgbox "Impossible de lire un integer signé (arithmétique) de " & bits & " bits. Seuls les 32bits, 16bits et 8bits sont autorisés.", 16, bits & "bits integer signed"
  Read_IntSig = 0
end if
End Function

Function bugg(erreur, errN)
msgbox erreur, 16, "Erreur " & errN
wscript.quit
end function

Function echo(msg)
wscript.echo msg
end function

Comme vous le voyez, les trois lignes qui ressortent au début peuvent etre changées par les votres:

Code: [Select]
Const UnitPerPix = 8 'echelleRemplacez le 8 par une autre valeur entière pour modifier la largeur des murs.
Un pixel est carré, donc, un mur est représenté sous la forme de pavés dont la face du haut est un carré. Cette valeur est en unités du jeu.

Code: [Select]
Const WallHeight = 96 'Hauteur des murs (unites)Cette valeur définit la hauteur des murs. Remplacez le 96 par la hauteur désirée. Utilisez un entie positif. l'utilisation d'un entier négatif posera problème: en effet, les triangles définissant les faces ne seront plus directs, et les faces seront alors inversée. Le résultat sera que le brush ne pourra pas etre dessiné (brush erroné).

Code: [Select]
Const TexVal = "caulk 0 0 0.00 1 1 0 0 0 "Définissez la texture apr défaut pour les murs. La première valeur est le nom de texture. Les deux suivantes sont la position horizontale et verticale. La suivante donne normalement l'angle de rotation de la texture. Les deux d'apres (ici 1 et 1) donne l'étirement de la texture horizontalement et verticalement. Les trois dernières sont des paramètres dont je ne connait aps la signification.

Pour mettre TOUS les brushs en "détail", utilisez:
"+surfaceparm detail"
à la fin de la valeur entrée. Par exemple:

Code: [Select]
Const TexVal = "nodraw 0 0 90.00 2 2 0 0 0 +surfaceparm detail "Vos brushs seront en "nodraw", la texture sera tournée de 90° et sera étirée à taille double de la normale. Les brushs seront normalement en mode "détail".

Pour obtenir le programme, copiez le texte dans le grand "code", et collez-le dans un fichier texte nouveau. Renommez-le en .vbs: l'icone doit se changer en une sorte de parchemin vert. Double-cliquez dessus.

Il se peut que votre anti-virus s'affole: dites-lui que ce programme n'est pas méchant. En réalité un "script", donc il vous faudra peut-etre désactiver le blocage des scripts pour l'utiliser.

Ce code n'inclut pas encore les boites de dialogue pour le nom du bitmap. Donc, vous devez nommer votre image bitmap en "image.bmp", et la placer dans le même dossier que votre programme copié-collé.
Vous devriez avoir, apres lancement du programme, un fichier "carte.map" nouvellement créé dans le dossier où se situe le programme. Ouvrez-le avec Radiant pour voir votre carte!

En cas de problème, prévenez-moi!
N'oubliez pas l'auteur, merci ^^

note pour les possibles programmeurs VBS ou autre langage "basique":
Comme vous le constatez peut-etre, ce programme permet de lire les données d'un fichier à peu pres de la même façon qu'un langage évolué genre C, C# ou Cpp. En effet, vous avez deux fonctions de la forme:

Read_IntUns <File> <Bits>
Read_IntSig <File> <Bits>

Vous êtes parfaitement autorisés à les réemployer dans vos propres codes, à condition de mentionner, en commentaire du code au minimum, la provenance de ces fonction, c'est à dire d'indiquer qu'elles ont été tirées du code du programme de convertion BMP_Vers_MAP. Mentionnez aussi l'auteur comme Snaky, et poussez la gentillesse jusqu'à rajouter l'adresse de Caskami ;)

Read_IntUns permet de lire un integer non-signé de n'importe quel fichier déjà ouvert sous la forme d'un TextStream (FileSystemObject.OpenTextFile). <Bits> permet d'indiquer le nombre de bits de l'integer à lire. les valeurs reconnues étant tous les multiples de 8 pour le non-signé.
Read_IntSig permet de lire un integer signé. Le nombre de bits valide est de 8, 16 ou 32 (pas de 24 ni de 64!).

Integer désigne un nombre entier, signé indique qu'il est lu par rapport à 0 (on peut avoir -10 ou 10), et non-signé signifie qu'il est en valeur absolue (10 uniquement). Un integer non-signé peut donc etre plus grand qu'un integer signé, avec la même mémoire demandée (un signé demandant un bit de plus pour le signe).
« Last Edit: September 25, 2008, 04:19:53 PM by snaky »

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #9 on: September 25, 2008, 09:33:20 PM »
Double-post, mais le contenu est totalement différent du précédent... Donc j'me suis permis... Je ne sais pas si j'ai eu raison ^^

Maintenant, le convertisseur est capable d'ajuster lui-même tous les angles de la carte !

Voyez plutot:



Voici l'image de base correspondante:



Et le code incluant les angles ajustés (je compte sur la date de post de ce topic, Jeudi 25 Septembre 2008 21.30 à Paris pour éviter les petits voleurs qui voudraient se l'approprier! Le code est déjà déposé sur C&C...)

Code: [Select]
'On Error Resume Next

Const C_BfType = 19778
Const UnitPerPix = 8 'echelle
Const WallHeight = 96 'Hauteur des murs (unites)
Const TexVal = "caulk 0 0 0.00 1 1 0 0 0 "

dim WSS, FSO, lfold, pic, Matrix
set WSS = WScript.CreateObject("WScript.Shell")
set FSO = CreateObject("Scripting.FileSystemObject")
lfold = FSO.GetParentFolderName(WScript.ScriptFullName) & "/"
echo "Dossier actuel: " & lfold
set Matrix = CreateObject("Scripting.Dictionary")

set pic = FSO.OpenTextFile(lfold & "image.bmp", 1)

bfType = Read_IntSig(pic, 16)
if not bfType = C_BfType Then bugg "Le fichier n'est pas un bitmap valide!" & chr(10) & "Le code d'en-tête (bfType) " & bfType & " ne correspond pas au bfType attendu " & C_bfType, "700A001"
pic.Read(8)
bfOffBits = Read_IntUns(pic, 32)
BiSize = Read_IntUns(pic, 32)
BiWidth = Read_IntUns(pic, 32)
BiHeight = Read_IntUns(pic, 32)
BiPlanes = Read_IntUns(pic, 16)
BiBitCount = Read_IntUns(pic, 16)
if not BiBitCount = 24 Then bugg "Le fichier bitmap doit etre en 24bits par pixel, et non pas en " & BiBitCount & " bits par pixels. Veuillez l'ouvrir dans un logiciel graphique (p.e. MSPaint) puis le sauvegarder en 24 bits", "700A002"
BiOctCount = Int(BiBitCount/8.0)
BiOctCols = BiOctCount*BiWidth

while BiOctCols > 4
BiOctCols = BiOctCols-4
WEnd
BiOctCols = 4-BiOctCols

echo "Type: " & BfType
echo "OffBits: " & BfOffBits
echo "Size: " & BiSize
echo "Width: " & BiWidth
echo "Height: " & BiHeight
echo "BitCount: " & BiBitCount
echo "Octets de complétion de ligne: " & BiOctCols

pic.Read(BiSize-16)
echo "Initialisation OK..."

for l=1 To BiHeight
Matrix.Add l, CreateObject("Scripting.Dictionary")
for c=1 To BiWidth
  Matrix.Item(l).Add c, CreateObject("Scripting.Dictionary")
  tp2 = 0
  for b=1 To BiOctCount
   Matrix.Item(l).Item(c).Add b, Read_IntUns(pic, 8)
   tp2 = tp2+Matrix.Item(l).Item(c).Item(b)
  next
  Matrix.Item(l).Item(c).Add BiOctCount+1, tp2
Next
if not BiOctCols = 0 Then pic.Read(BiOctCols)
Next
echo "Récupération des données du bitmap OK..."

pic.close
set pic = FSO.OpenTextFile(lfold & "image.bmp", 1)
set dest = FSO.CreateTextFile(lfold & "image_s.bmp", TRUE)
set Colorized = CreateObject("Scripting.Dictionary")
dest.write pic.Read(2+8+4+4+4+4+2+2+BiSize-16)
pic.close

for l=1 To BiHeight
Colorized.Add l, CreateObject("Scripting.Dictionary")
for c=1 To Biwidth
  if Matrix.Item(l).Item(c).Item(4) = 0 Then
   A = Array(Matrix.Item(l).Item(c+1).Item(4), Matrix.Item(l+1).Item(c).Item(4), Matrix.Item(l).Item(c-1).Item(4), Matrix.Item(l-1).Item(c).Item(4))
   if A(0)=0 Then B="1" Else B="0"
   if A(1)=0 Then B=B&"1" Else B=B&"0"
   if A(2)=0 Then B=B&"1" Else B=B&"0"
   if A(3)=0 Then B=B&"1" Else B=B&"0"

   Colorized.Item(l).Add c, Split(B, "", -1, 1)

   if B="0000" Then
    dest.write chr(000) & chr(0) & chr(0)
   elseif B="0001" Then
    dest.write chr(255) & chr(0) & chr(0)
   elseif B="0010" Then
    dest.write chr(000) & chr(0) & chr(255)
   elseif B="0011" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="0100" Then
    dest.write chr(255) & chr(0) & chr(0)
   elseif B="0101" Then
    dest.write chr(255) & chr(0) & chr(0)
   elseif B="0110" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="0111" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1000" Then
    dest.write chr(000) & chr(0) & chr(255)
   elseif B="1001" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1010" Then
    dest.write chr(000) & chr(0) & chr(255)
   elseif B="1011" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1100" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1101" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1110" Then
    dest.write chr(255) & chr(0) & chr(255)
   elseif B="1111" Then
    dest.write chr(255) & chr(0) & chr(255)
   else
    bugg "Impossible de reconnaitre le code " & B & ". Il se peut que votre fichier script soit corrompu. Veuillez le télécharger de nouveau, sur le site officiel de préférence.", "700A003"
   end if
  else
   dest.write chr(255) & chr(255) & chr(255)
   Colorized.Item(l).Add c, Array(0, 0, 0, 0)
  End If
next
next
echo "Compilation des données OK..."
echo "Echelle: " & UnitPerPix & " unites radiant par pixel"
echo "Hauteur des murs: " & WallHeight

set mapf = FSO.CreateTextFile(lfold & "carte.map", TRUE)
mapf.Writeline "{"
mapf.writeline chr(34) & "classname" & chr(34) & " " & chr(34) & "worldspawn" & chr(34)
For l=1 To BiHeight
For r=1 To BiWidth

  if Matrix.Item(l).Item(r).Item(4) = 0 and Matrix.Item(l).Item(r).Exists(5) <> TRUE Then
   rMin = r
   lMin = l

   lp = l-1
   if l+1 <= BiHeight Then ln = l+1 else ln = -1

   Do while r < BiWidth
    if (Matrix.Item(l).Item(r+1).Item(4) = 0) Then
     If (not ln = -1 and Matrix.Item(ln).Item(r+1).Item(4)=0) or (not lp = 0 and Matrix.Item(lp).Item(r+1).Item(4)=0) Then
      rMax = r+1
      exit Do
     Else
      r = r + 1
      if r = BiWidth Then
       rMax = r
       exit Do
      end if
     end if
    else
     rMax = r
     exit Do
    end if
   Loop

   Rows = rMax-rMin+1

   if (rMax+1 > BiWidth or not Matrix.Item(l).Item(rMax+1).Item(4) = 0) and (l+1 > BiHeight or not Matrix.Item(l+1).Item(rMax).Item(4) = 0) Then NextR = rMax+1 else NextR = r+1
   r = rMin

   if r+1 <= BiWidth Then rn = r+1 else rn = -1
   rp = r-1
   lp = l

   Do while lp < BiHeight
    if (Matrix.Item(lp+1).Item(r).Item(4) = 0) Then
     If ((not rn = -1 and Matrix.Item(lp+1).Item(rn).Item(4)=0) or (not rp = 0 and Matrix.Item(lp+1).Item(rp).Item(4)=0)) Then
      lMax = lp+1
      exit Do
     Else
      Matrix.Item(lp+1).Item(r).Item(5) = 1 'Le pixel n'a pas de pixel en ligne, et est déjà validé en colone, donc, inutile de recalculer!
      lp = lp + 1
      if lp = BiHeight Then
       lMax = lp
       exit Do
      End If
     end if
    else
     lMax = lp
     exit Do
    end if
   Loop

   Lines = lMax-lMin+1
  
   if Rows = 1 Then
    SaveBrush 1, Lines
   elseif not Rows = 1 and Lines = 1 Then
    SaveBrush Rows, 1
   else
    SaveBrush Rows, 1
    SaveBrush 1, Lines
   end if
   r = NextR-1
  End If
  
Next
Next
mapf.writeline "}"
msgbox "ok"

Function SaveBrush(NTRows, NTLines)
P = UnitPerPix
Q = P/2.0
W = WallHeight

X = rMin*P
Y = lMin*P
U = NTRows*P
V = NTLines*P

A = "( " & X+0 & " " & Y+0 & " " & 0 & " ) "
B = "( " & X+U & " " & Y+0 & " " & 0 & " ) "
C = "( " & X+0 & " " & Y+V & " " & 0 & " ) "
D = "( " & X+U & " " & Y+V & " " & 0 & " ) "
E = "( " & X+0 & " " & Y+0 & " " & W & " ) "
F = "( " & X+U & " " & Y+0 & " " & W & " ) "
G = "( " & X+0 & " " & Y+V & " " & W & " ) "
H = "( " & X+U & " " & Y+V & " " & W & " ) "

mapf.writeline "//brush " & l & ";" & r
mapf.writeline "{"
mapf.writeline A & B & C & TexVal
mapf.writeline A & E & B & TexVal
mapf.writeline A & C & E & TexVal
mapf.writeline H & F & G & TexVal
mapf.writeline H & D & F & TexVal
mapf.writeline H & G & D & TexVal

AA = "( " & X+U-Q & " " & Y+U+0 & " " & W & " ) "
AB = "( " & X+U-Q & " " & Y+U+0 & " " & 0 & " ) "
AC = "( " & X+U-Q & " " & Y+U-Q & " " & W & " ) "

BA = "( " & X+0+Q & " " & Y+0+0 & " " & 0 & " ) "
BB = "( " & X+0+Q & " " & Y+0+Q & " " & W & " ) "
BC = "( " & X+0+Q & " " & Y+0+0 & " " & W & " ) "

CA = "( " & X+0+0 & " " & Y+V-Q & " " & W & " ) "
CB = "( " & X+0+0 & " " & Y+V-Q & " " & 0 & " ) "
CC = "( " & X+0+P & " " & Y+V-Q & " " & W & " ) "

DA = "( " & X+0+0 & " " & Y+0+Q & " " & 0 & " ) "
DB = "( " & X+0+0 & " " & Y+0+Q & " " & W & " ) "
DC = "( " & X+0+P & " " & Y+0+Q & " " & W & " ) "

FA = "( " & X+U+0 & " " & Y+0+0 & " " & 0 & " ) "
FB = "( " & X+U+0 & " " & Y+0+0 & " " & W & " ) "
FC = "( " & X+U-P & " " & Y+0+P & " " & W & " ) "

GA = "( " & X+U-P & " " & Y+0+0 & " " & 0 & " ) "
GB = "( " & X+U-P & " " & Y+0+0 & " " & W & " ) "
GC = "( " & X+U+0 & " " & Y+0+P & " " & W & " ) "

HA = "( " & X+0+0 & " " & Y+0+0 & " " & 0 & " ) "
HB = "( " & X+0+P & " " & Y+0+P & " " & W & " ) "
HC = "( " & X+0+0 & " " & Y+0+0 & " " & W & " ) "

IA = "( " & X+0+0 & " " & Y+0+P & " " & 0 & " ) "
IB = "( " & X+0+0 & " " & Y+0+P & " " & W & " ) "
IC = "( " & X+0+P & " " & Y+0+0 & " " & W & " ) "

JA = "( " & X+0+0 & " " & Y+V+0 & " " & W & " ) "
JB = "( " & X+0+0 & " " & Y+V+0 & " " & 0 & " ) "
JC = "( " & X+0+P & " " & Y+V-P & " " & W & " ) "

KA = "( " & X+0+0 & " " & Y+V-P & " " & W & " ) "
KB = "( " & X+0+0 & " " & Y+V-P & " " & 0 & " ) "
KC = "( " & X+0+P & " " & Y+V+0 & " " & W & " ) "

LA = "( " & X+0+0 & " " & Y+0+0 & " " & W & " ) "
LB = "( " & X+0+P & " " & Y+0+P & " " & W & " ) "
LC = "( " & X+0+0 & " " & Y+0+0 & " " & 0 & " ) "

MA = "( " & X+0+P & " " & Y+0+0 & " " & W & " ) "
MB = "( " & X+0+P & " " & Y+0+0 & " " & 0 & " ) "
MC = "( " & X+0+0 & " " & Y+0+P & " " & 0 & " ) "

EA = NTRows+rMin
EB = NTLines+lMin
LN = lMin+1
LP = lMin-1
RN = rMin+1
RP = rMin-1
if not NTLines = 1 or not NTRows = 1 Then
  if NTLines = 1 and EA <= BiWidth and Matrix.Item(lMin).Item(EA).Item(4) = 0 Then mapf.Writeline AA & AB & AC & TexVal
  if NTLines = 1 and rMin > 1 and Matrix.Item(lMin).Item(rMin-1).Item(4) = 0 Then mapf.Writeline BA & BB & BC & TexVal
  if NTLines = 1 and LN <= BiHeight and Matrix.Item(LN).Item(EA-1).Item(4) = 0 Then mapf.Writeline FA & FB & FC & TexVal
  if NTLines = 1 and LP >= 1 and Matrix.Item(LP).Item(EA-1).Item(4) = 0 Then mapf.Writeline GA & GB & GC & TexVal
  if NTLines = 1 and LN <= BiHeight and Matrix.Item(LN).Item(rMin).Item(4) = 0 Then mapf.Writeline HA & HB & HC & TexVal
  if NTLines = 1 and LP >= 1 and Matrix.Item(LP).Item(rMin).Item(4) = 0 Then mapf.Writeline IA & IB & IC & TexVal

  if NTRows = 1 and EB <= BiHeight and Matrix.Item(EB).Item(rMin).Item(4) = 0 Then mapf.Writeline CA & CB & CC & TexVal
  if NTRows = 1 and lMin > 1 and Matrix.Item(lMin-1).Item(rMin).Item(4) = 0 Then mapf.Writeline DA & DB & DC & TexVal
  if NTRows = 1 and RN <= BiWidth and Matrix.Item(EB-1).Item(RN).Item(4) = 0 Then mapf.Writeline JA & JB & JC & TexVal
  if NTRows = 1 and RP >= 1 and Matrix.Item(EB-1).Item(RP).Item(4) = 0 Then mapf.Writeline KA & KB & KC & TexVal
  if NTRows = 1 and RN <= BiWidth and Matrix.Item(lMin).Item(RN).Item(4) = 0 Then mapf.Writeline LA & LB & LC & TexVal
  if NTRows = 1 and RP >= 1 and Matrix.Item(lMin).Item(RP).Item(4) = 0 Then mapf.Writeline MA & MB & MC & TexVal
end if

mapf.writeline "}"
end function

Function Read_IntUns(file, bits)
t = 0
ri = 0
octs = Int(bits/8.0)
for i = 1 To octs
  tp = Asc(file.Read(1))
  for k=2 To i
   tp = tp*256
  next
  ri = ri+tp
next
Read_IntUns = ri
End Function

Function Read_IntSig(file, bits)
if bits = 32 Then
  ri = Array(Asc(file.Read(1)), Asc(file.Read(1)), Asc(file.Read(1)), Asc(file.Read(1)))
  if ri(3) >= 128 Then
   ri(3)=ri(3)-128
   Read_IntSig = -2147483648+(ri(0)+ri(1)*256+ri(2)*65536+ri(3)*16777216)
  else
   Read_IntSig = ri(0)+ri(1)*256+ri(2)*65536+ri(3)*16777216
  end if
elseif bits = 16 Then
  ri = Array(Asc(file.Read(1)), Asc(file.Read(1)))
  if ri(1) >= 128 Then
   ri(1)=ri(1)-128
   Read_IntSig = -32768+(ri(0)+ri(1)*256)
  else
   Read_IntSig = ri(0)+ri(1)*256
  end if
elseif bits = 8 Then
  ri = Asc(file.Read(1))
  if ri >= 128 Then
   ri=ri-128
   Read_IntSig = -128+ri
  else
   Read_IntSig = ri
  end if
else
  msgbox "Impossible de lire un integer signé (arithmétique) de " & bits & " bits. Seuls les 32bits, 16bits et 8bits sont autorisés.", 16, bits & "bits integer signed"
  Read_IntSig = 0
end if
End Function

Function bugg(erreur, errN)
msgbox erreur, 16, "Erreur " & errN
wscript.quit
end function

Function echo(msg)
wscript.echo msg
end function

En tête de code source, vous retrouvez les 3 valeurs (largeur de mur, hauteur et texture).

Dedoum

  • Legomaniaque
  • Posts: 1477
    • http://www.lord-of-death.com
Faire Sa Carte à Partir D'un Bitmap
« Reply #10 on: September 25, 2008, 10:22:55 PM »
Alors je dis GG, avec un G majuscule !  B)

Tous mes fils d'installation  
« Last Edit: September 25, 2008, 10:23:07 PM by Dedoum »
S'il n'y a pas de solution, c'est qu'il n'y a pas de problème ! (Proverbe Shadok)

Jed

  • Tailleur de maps (expérimenté)
  • Posts: 727
    • http://www.hudescharfe.com
Faire Sa Carte à Partir D'un Bitmap
« Reply #11 on: September 26, 2008, 06:04:33 PM »
Quote
VBS, c'est le plus souple, ca se transpose sous Linux facilement (d'apres un ami)
 :blink: Tu as des amis curieux... VBS c'est le langage de script propriétaire à MS, et pas du tout portable sous Linux... Si tu veux du portable prends du Java!

Sinon bravo pur l'idée!

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #12 on: September 26, 2008, 06:09:14 PM »
Apparemment, il se transforme facilement en Pearl ou en un autre langage (je l'ai oublié), qui est parfaitement utilisable sous Linux. J'ai pas dit qu'un C/C suffisait pour Linux xD

Jed

  • Tailleur de maps (expérimenté)
  • Posts: 727
    • http://www.hudescharfe.com
Faire Sa Carte à Partir D'un Bitmap
« Reply #13 on: September 26, 2008, 06:10:41 PM »
Si tu veux faire ça en Perl, pas de soucis sous Linux. Mais je n'appelle plus ça de la portablilité, tu vas devoir tout réécrire!

tourist-tam

  • Tailleur de maps
  • Posts: 420
Faire Sa Carte à Partir D'un Bitmap
« Reply #14 on: September 26, 2008, 11:28:22 PM »
Excellent. :)

Pour le port sous Java ca me tenterais bien. :)

<edit>il me manque des connaissances en VBS par contre pour porter</edit> :P

<edit2>Ca me fait penser: il exist un utilitaire pour Quake du meme genre code en C. bmp2map je crois. Je joins l'entete du programme:
Quote
  bmp2map  - A conversion utility to quickly convert 256 color .BMPs
   v.06      into Quake .MAPs complete with texturing and entities.
             Originally written to convert 2D floor/street plans
             into 3D maps.

    Author - Jack Perdue (aka Silicon Slick) - si_slick@cy-net.net
      Date - May 10th, 1997 v.01
             June 13th, 1997 v.02
             July 5th, 1997 v.03
             July 11th, 1997 v.04
             July 22nd, 1997 v.05
             August 23rd, 1997 v.06
  Compiler - Borland TurboC 2.0 for MS-DOS
</edit2>

<edit3>
Quote
Apparemment, il se transforme facilement en Pearl ou en un autre langage (je l'ai oublié), ...

Ruby/Python/Groovy ???
</edit3>
Tam
« Last Edit: September 27, 2008, 02:25:23 AM by tourist-tam »

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #15 on: September 27, 2008, 11:48:30 AM »
Ca devrait etre du Python ^^

S'il me manque quelques explications, demandes-les ;)

Pour le bmp2map de quake, je ne connaissais pas :s

Quelqu'un a essayé d'ouvrir une carte convertie dans le mappeur d'un des COD?
« Last Edit: September 27, 2008, 11:48:50 AM by snaky »

Dedoum

  • Legomaniaque
  • Posts: 1477
    • http://www.lord-of-death.com
Faire Sa Carte à Partir D'un Bitmap
« Reply #16 on: September 27, 2008, 11:57:17 AM »
Je l'ai fait pour mohdm6 et une autre map perso, il faut utiliser un petit prog sur ce forum en .exe pour renommer toutes les textures en caulk ou nodraw, et il recréé un worldspawn compatible. (test fait pour cod4).
S'il n'y a pas de solution, c'est qu'il n'y a pas de problème ! (Proverbe Shadok)

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #17 on: September 27, 2008, 02:16:23 PM »
Donc, mis à par les textures, le format est constant?

Bon, ben ca signifie que le convertisseur marche aussi pour la série des Call Of Duty ^^ Amusez-vous bien ;)

tourist-tam

  • Tailleur de maps
  • Posts: 420
Faire Sa Carte à Partir D'un Bitmap
« Reply #18 on: September 27, 2008, 06:21:10 PM »
Pas tres descriptifs les noms de tes variables :S

Tam

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #19 on: September 27, 2008, 06:46:48 PM »
Navré, c'est plutot fait pour etre lancé que exploré ^^

tourist-tam

  • Tailleur de maps
  • Posts: 420
Faire Sa Carte à Partir D'un Bitmap
« Reply #20 on: September 27, 2008, 07:16:01 PM »
Hehe, j'ai vu ca. ^_^

Ca fait pas mal de lignes de code. :P

Par contre tu recuperes le fichier image (source) en binaire, c'est bien ca?

mmm ... Ta matrice c'est pour stocker les pixels du fichier image, j'imagine?!

Tam
« Last Edit: September 27, 2008, 08:34:08 PM by tourist-tam »

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #21 on: September 27, 2008, 09:06:09 PM »
Exact, sous la forme Matrix[Colonne][Ligne][Couleur]

tourist-tam

  • Tailleur de maps
  • Posts: 420
Faire Sa Carte à Partir D'un Bitmap
« Reply #22 on: September 27, 2008, 09:46:17 PM »
Oulala faut pas depasser les 1px pour la largeur du mur. :P

Tam

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #23 on: September 27, 2008, 11:09:04 PM »
Exact, sinon, il ajuste les murs entre eux xD

snaky

  • Squatteur de forum
  • ****
  • Posts: 3332
    • http://profparty.forumpro.fr
Faire Sa Carte à Partir D'un Bitmap
« Reply #24 on: October 01, 2008, 02:50:11 PM »
Merci à Luluthefirst pour avoir relevé que le programme monte à 1.500.000Ko de mémoire pour une image 640x480 !

Voici le code optimisé. Pour une image 1160x806 (2.5Mo), il monte à 58Mo environ, donc l'image risque de prendre 20x plus de mémoire vive qu'elle ne prend de place sur votre disque dur (c'est déjà mieux qu'avant où on avait un rapport de 1.700x !)

Code: [Select]
'On Error Resume Next

Const C_BfType = 19778
Const UnitPerPix = 8 'echelle
Const WallHeight = 160 'Hauteur des murs (unites)
Const TexVal = "caulk 0 0 0.00 1 1 0 0 0 "


dim WSS, FSO, lfold, pic, Matrix
set WSS = WScript.CreateObject("WScript.Shell")
set FSO = CreateObject("Scripting.FileSystemObject")
lfold = FSO.GetParentFolderName(WScript.ScriptFullName) & "/"
echo "Dossier actuel: " & lfold
set Matrix = CreateObject("Scripting.Dictionary")

set pic = FSO.OpenTextFile(lfold & "image.bmp", 1)

bfType = Read_IntSig(pic, 16)
if not bfType = C_BfType Then bugg "Le fichier n'est pas un bitmap valide!" & chr(10) & "Le code d'en-tête (bfType) " & bfType & " ne correspond pas au bfType attendu " & C_bfType, "700A001"
pic.Read(8)
bfOffBits = Read_IntUns(pic, 32)
BiSize = Read_IntUns(pic, 32)
BiWidth = Read_IntUns(pic, 32)
BiHeight = Read_IntUns(pic, 32)
BiPlanes = Read_IntUns(pic, 16)
BiBitCount = Read_IntUns(pic, 16)
if not BiBitCount = 24 Then bugg "Le fichier bitmap doit etre en 24bits par pixel, et non pas en " & BiBitCount & " bits par pixels. Veuillez l'ouvrir dans un logiciel graphique (p.e. MSPaint) puis le sauvegarder en 24 bits", "700A002"
BiOctCount = Int(BiBitCount/8.0)
BiOctCols = BiOctCount*BiWidth

while BiOctCols > 4
BiOctCols = BiOctCols-4
WEnd
BiOctCols = 4-BiOctCols

' Décalage des brushs pour centrer (à peu pres à cause du Int) la map
' L'utilisation du Int permet d'arrondir à l'unité la valeur de décalage
' Cela économise ainsi la sauvegarde des virgules: on gagne beaucoup de mémoire pour le .map (+léger)
' Sans pour autant perdre beaucoup d'informations
DecalX = Int(BiWidth*UnitPerPix/2.0)
DecalY = Int(BiHeight*UnitPerPix/2.0)

echo "Type: " & BfType
echo "OffBits: " & BfOffBits
echo "Size: " & BiSize
echo "Width: " & BiWidth
echo "Height: " & BiHeight
echo "BitCount: " & BiBitCount
echo "Octets de complétion de ligne: " & BiOctCols
echo "Décalage X: " & DecalX
echo "Décalage Y: " & DecalY

pic.Read(BiSize-16)
echo "Initialisation OK..."

for l=1 To BiHeight
Matrix.Add l, CreateObject("Scripting.Dictionary")
for c=1 To BiWidth
  Matrix.Item(l).Add c, Read_IntUns(pic, 8)+Read_IntUns(pic, 8)+Read_IntUns(pic, 8)
Next
if not BiOctCols = 0 Then pic.Read(BiOctCols)
Next
echo "Récupération des données du bitmap OK..."

pic.close
set pic = FSO.OpenTextFile(lfold & "image.bmp", 1)
set dest = FSO.CreateTextFile(lfold & "image_s.bmp", TRUE)
set Colorized = CreateObject("Scripting.Dictionary")
dest.write pic.Read(2+8+4+4+4+4+2+2+BiSize-16)
pic.close

echo "Compilation des données OK..."
echo "Echelle: " & UnitPerPix & " unites radiant par pixel"
echo "Hauteur des murs: " & WallHeight

set mapf = FSO.CreateTextFile(lfold & "carte.map", TRUE)
mapf.Writeline "{"
mapf.writeline chr(34) & "classname" & chr(34) & " " & chr(34) & "worldspawn" & chr(34)
For l=1 To BiHeight
For r=1 To BiWidth

  if Matrix.Item(l).Item(r) = 0 Then
   rMin = r
   lMin = l

   if l-1 <= 0 Then lp = -1 else lp = l-1
   if l+1 <= BiHeight Then ln = l+1 else ln = -1

   Do while r < BiWidth
    if (Matrix.Item(l).Item(r+1) = 0) Then
     r=r+1
     If r=BiWidth or (not ln = -1 and Matrix.Item(ln).Item(r)=0) or (not lp = -1 and Matrix.Item(lp).Item(r)<=0) Then exit Do
    else
     exit Do
    end if
   Loop
   rMax = r
   Rows = rMax-rMin+1

   if (rMax >= BiWidth) Then
    NextR = BiWidth+1
   elseif (Matrix.Item(l).item(rMax+1) = 0) Then
    NextR = rMax
   elseif (not ln = -1 and Matrix.Item(ln).Item(rMax)=0) Then
    if Rows = 1 Then
     NextR = rMax+1
    else
     NextR = rMax
    end if
   else
    NextR = rMax+1
   end if

   r = rMin

   if r+1 <= BiWidth Then rn = r+1 else rn = -1
   rp = r-1
   lp = l

   Do while lp < BiHeight
    if (Matrix.Item(lp+1).Item(r) = 0) Then
     If ((not rn = -1 and Matrix.Item(lp+1).Item(rn)=0) or (not rp = 0 and Matrix.Item(lp+1).Item(rp)=0)) Then
      lMax = lp+1
      exit Do
     Else
      Matrix.Item(lp+1).Item(r) = -1 'Le pixel n'a pas de pixel en ligne, et est déjà validé en colone, donc, inutile de recalculer!
      lp = lp + 1
      if lp = BiHeight Then
       lMax = lp
       exit Do
      End If
     end if
    else
     lMax = lp
     exit Do
    end if
   Loop

   Lines = lMax-lMin+1
  
   if Rows = 1 Then
    SaveBrush 1, Lines
   elseif not Rows = 1 and Lines = 1 Then
    SaveBrush Rows, 1
   else
    SaveBrush Rows, 1
    SaveBrush 1, Lines
   end if

   r = NextR-1
  End If
  
Next
Next
mapf.writeline "}"
echo "Vidage de la mémoire matricielle..."
set Matrix = Nothing
echo "Vidage effectué! Fin du programme"
msgbox "ok"

Function SaveBrush(NTRows, NTLines)
' Les variables et constantes globales sont stockées pour faciliter l'écriture dans les lignes qui suivent
P = UnitPerPix
Q = P/2.0
W = WallHeight

X = rMin*P-DecalX
Y = lMin*P-DecalY
U = NTRows*P
V = NTLines*P

A = "( " & X+0 & " " & Y+0 & " " & 0 & " ) "
B = "( " & X+U & " " & Y+0 & " " & 0 & " ) "
C = "( " & X+0 & " " & Y+V & " " & 0 & " ) "
D = "( " & X+U & " " & Y+V & " " & 0 & " ) "
E = "( " & X+0 & " " & Y+0 & " " & W & " ) "
F = "( " & X+U & " " & Y+0 & " " & W & " ) "
G = "( " & X+0 & " " & Y+V & " " & W & " ) "
H = "( " & X+U & " " & Y+V & " " & W & " ) "

mapf.writeline "//brush " & l & ";" & r
mapf.writeline "{"
mapf.writeline A & B & C & TexVal
mapf.writeline A & E & B & TexVal
mapf.writeline A & C & E & TexVal
mapf.writeline H & F & G & TexVal
mapf.writeline H & D & F & TexVal
mapf.writeline H & G & D & TexVal

AA = "( " & X+U-Q & " " & Y+U+0 & " " & W & " ) "
AB = "( " & X+U-Q & " " & Y+U+0 & " " & 0 & " ) "
AC = "( " & X+U-Q & " " & Y+U-Q & " " & W & " ) "

BA = "( " & X+0+Q & " " & Y+0+0 & " " & 0 & " ) "
BB = "( " & X+0+Q & " " & Y+0+Q & " " & W & " ) "
BC = "( " & X+0+Q & " " & Y+0+0 & " " & W & " ) "

CA = "( " & X+0+0 & " " & Y+V-Q & " " & W & " ) "
CB = "( " & X+0+0 & " " & Y+V-Q & " " & 0 & " ) "
CC = "( " & X+0+P & " " & Y+V-Q & " " & W & " ) "

DA = "( " & X+0+0 & " " & Y+0+Q & " " & 0 & " ) "
DB = "( " & X+0+0 & " " & Y+0+Q & " " & W & " ) "
DC = "( " & X+0+P & " " & Y+0+Q & " " & W & " ) "

FA = "( " & X+U+0 & " " & Y+0+0 & " " & 0 & " ) "
FB = "( " & X+U+0 & " " & Y+0+0 & " " & W & " ) "
FC = "( " & X+U-P & " " & Y+0+P & " " & W & " ) "

GA = "( " & X+U-P & " " & Y+0+0 & " " & 0 & " ) "
GB = "( " & X+U-P & " " & Y+0+0 & " " & W & " ) "
GC = "( " & X+U+0 & " " & Y+0+P & " " & W & " ) "

HA = "( " & X+0+0 & " " & Y+0+0 & " " & 0 & " ) "
HB = "( " & X+0+P & " " & Y+0+P & " " & W & " ) "
HC = "( " & X+0+0 & " " & Y+0+0 & " " & W & " ) "

IA = "( " & X+0+0 & " " & Y+0+P & " " & 0 & " ) "
IB = "( " & X+0+0 & " " & Y+0+P & " " & W & " ) "
IC = "( " & X+0+P & " " & Y+0+0 & " " & W & " ) "

JA = "( " & X+0+0 & " " & Y+V+0 & " " & W & " ) "
JB = "( " & X+0+0 & " " & Y+V+0 & " " & 0 & " ) "
JC = "( " & X+0+P & " " & Y+V-P & " " & W & " ) "

KA = "( " & X+0+0 & " " & Y+V-P & " " & W & " ) "
KB = "( " & X+0+0 & " " & Y+V-P & " " & 0 & " ) "
KC = "( " & X+0+P & " " & Y+V+0 & " " & W & " ) "

LA = "( " & X+0+0 & " " & Y+0+0 & " " & W & " ) "
LB = "( " & X+0+P & " " & Y+0+P & " " & W & " ) "
LC = "( " & X+0+0 & " " & Y+0+0 & " " & 0 & " ) "

MA = "( " & X+0+P & " " & Y+0+0 & " " & W & " ) "
MB = "( " & X+0+P & " " & Y+0+0 & " " & 0 & " ) "
MC = "( " & X+0+0 & " " & Y+0+P & " " & 0 & " ) "

EA = NTRows+rMin
EB = NTLines+lMin
LN = lMin+1
LP = lMin-1
RN = rMin+1
RP = rMin-1
if not NTLines = 1 or not NTRows = 1 Then
  if NTLines = 1 and EA <= BiWidth and Matrix.Item(lMin).Item(EA) <= 0 Then mapf.Writeline AA & AB & AC & TexVal
  if NTLines = 1 and rMin > 1 and Matrix.Item(lMin).Item(rMin-1) <= 0 Then mapf.Writeline BA & BB & BC & TexVal
  if NTLines = 1 and LN <= BiHeight and Matrix.Item(LN).Item(EA-1) <= 0 Then mapf.Writeline FA & FB & FC & TexVal
  if NTLines = 1 and LP >= 1 and Matrix.Item(LP).Item(EA-1) <= 0 Then mapf.Writeline GA & GB & GC & TexVal
  if NTLines = 1 and LN <= BiHeight and Matrix.Item(LN).Item(rMin) <= 0 Then mapf.Writeline HA & HB & HC & TexVal
  if NTLines = 1 and LP >= 1 and Matrix.Item(LP).Item(rMin) <= 0 Then mapf.Writeline IA & IB & IC & TexVal

  if NTRows = 1 and EB <= BiHeight and Matrix.Item(EB).Item(rMin) <= 0 Then mapf.Writeline CA & CB & CC & TexVal
  if NTRows = 1 and lMin > 1 and Matrix.Item(lMin-1).Item(rMin) <= 0 Then mapf.Writeline DA & DB & DC & TexVal
  if NTRows = 1 and RN <= BiWidth and Matrix.Item(EB-1).Item(RN) <= 0 Then mapf.Writeline JA & JB & JC & TexVal
  if NTRows = 1 and RP >= 1 and Matrix.Item(EB-1).Item(RP) <= 0 Then mapf.Writeline KA & KB & KC & TexVal
  if NTRows = 1 and RN <= BiWidth and Matrix.Item(lMin).Item(RN) <= 0 Then mapf.Writeline LA & LB & LC & TexVal
  if NTRows = 1 and RP >= 1 and Matrix.Item(lMin).Item(RP) <= 0 Then mapf.Writeline MA & MB & MC & TexVal
end if

mapf.writeline "}"
end function

Function Read_IntUns(file, bits)
t = 0
ri = 0
octs = Int(bits/8.0)
for i = 1 To octs
  tp = Asc(file.Read(1))
  for k=2 To i
   tp = tp*256
  next
  ri = ri+tp
next
Read_IntUns = ri
End Function

Function Read_IntSig(file, bits)
if bits = 32 Then
  ri = Array(Asc(file.Read(1)), Asc(file.Read(1)), Asc(file.Read(1)), Asc(file.Read(1)))
  if ri(3) >= 128 Then
   ri(3)=ri(3)-128
   Read_IntSig = -2147483648+(ri(0)+ri(1)*256+ri(2)*65536+ri(3)*16777216)
  else
   Read_IntSig = ri(0)+ri(1)*256+ri(2)*65536+ri(3)*16777216
  end if
elseif bits = 16 Then
  ri = Array(Asc(file.Read(1)), Asc(file.Read(1)))
  if ri(1) >= 128 Then
   ri(1)=ri(1)-128
   Read_IntSig = -32768+(ri(0)+ri(1)*256)
  else
   Read_IntSig = ri(0)+ri(1)*256
  end if
elseif bits = 8 Then
  ri = Asc(file.Read(1))
  if ri >= 128 Then
   ri=ri-128
   Read_IntSig = -128+ri
  else
   Read_IntSig = ri
  end if
else
  msgbox "Impossible de lire un integer signé (arithmétique) de " & bits & " bits. Seuls les 32bits, 16bits et 8bits sont autorisés.", 16, bits & "bits integer signed"
  Read_IntSig = 0
end if
End Function

Function bugg(erreur, errN)
msgbox erreur, 16, "Erreur " & errN
wscript.quit
end function

Function echo(msg)
if inStr(1, WScript.FullName, "cscript", 1) > 0 Then wscript.echo msg

end function

Les modifications sont:
- Optimisation de la matrice de pixels. L'ancienne matrice était:
Ma(x)(y)© avec x€[1,l] et y€[1;r] et c€[1;5] où l et r sont respectivement le nombre de pixels en largeur et en hauteur et c donnait l'indice de l'information du pixel (<Rouge>, <Vert>, <Bleu>, <Somme RVB>, <Déjà calculé>), soit un total de
l*r*5 données, pour l*r objets
La nouvelle matrice est juste:
Mn(x)(y), avec x et y qui ne changent pas par rapport à avant, et Mn(x)(y) qui stocke seulement la valeur de l'ancienne Matrice Ma(x)(y)(4), donc, M(x)(y) stocke la somme des composantes Rouge Verte et Bleue du pixel de la ligne x, colonne y. Donc:
l*r données, l objets


- Edition de la fonction "echo", qui ne devrait rien renvoyer si vous n'etes pas en mode "console".


Donc une image large prendra moins de mémoire qu'une image haute. Une image 640x32 prendra plus de mémoire qu'une 32x640 (avec en premier la hauteur et en second la largeur), car on aura 640x32 ou 32x640 (c'est égal!) données dans les deux cas, mais dans le premier, on aura 60 objets, dans le second, que 32 ! Mais la différence ne casse pas des briques (une 800x80 prend 1.4x plus de mémoire qu'une 80x800, mais les temps de conversion son à peu pres égaux).

Le programme s'est bien terminé s'il vous affiche un "OK" dans une boite de dialogue à la fin de la conversion.
Bonne utilisation !

EDITION
Certains morceaux de code ont été oubliés. Le code actuel est maintenant opérationnel (le précédent oubliait quelques angles et les bords bas & gauches des brushs étaient mal faits). Maintenant, le code devrait etre bien plus rapide, bien plus léger, et sans bugg.
Deplus, la carte est maintenant centrée dans la grille !
« Last Edit: October 01, 2008, 03:13:07 PM by snaky »