1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2010-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nel/3d/tile_bank.h"
23 #include "nel/3d/texture_file.h"
24 #include "nel/3d/tile_noise_map.h"
26 #include "nel/misc/stream.h"
27 #include "nel/misc/common.h"
28 #include "nel/misc/path.h"
29 #include "nel/misc/file.h"
32 using namespace NLMISC
;
43 // ***************************************************************************
44 // ***************************************************************************
46 // ***************************************************************************
47 // ***************************************************************************
50 // ***************************************************************************
51 const sint
CTileLand::_Version
=0;
52 // ***************************************************************************
53 void CTileLand::serial(NLMISC::IStream
&f
)
55 (void)f
.serialVersion(_Version
);
58 f
.serialCont (_TileSet
);
60 // ***************************************************************************
61 void CTileLand::addTileSet (const std::string
& name
)
63 _TileSet
.insert (name
);
65 // ***************************************************************************
66 void CTileLand::removeTileSet (const std::string
& name
)
68 _TileSet
.erase (name
);
70 // ***************************************************************************
71 void CTileLand::setName (const std::string
& name
)
75 // ***************************************************************************
78 // ***************************************************************************
79 // ***************************************************************************
81 // ***************************************************************************
82 // ***************************************************************************
85 // ***************************************************************************
86 const sint
CTileBank::_Version
=4;
87 // ***************************************************************************
88 CTileBank::CTileBank ()
90 // Default _DisplacementMap
91 _DisplacementMap
.resize (1);
94 _DisplacementMap
[0].setEmpty ();
96 // ***************************************************************************
97 void CTileBank::serial(NLMISC::IStream
&f
)
99 f
.serialCheck (std::string ("BANK"));
101 sint streamver
= f
.serialVersion(_Version
);
103 // Version 1 not compatible
107 throw EOlderStream(f
);
113 // Displacement map array
114 f
.serialCont (_DisplacementMap
);
118 nlassert (!_DisplacementMap
.empty());
121 _DisplacementMap
[0].setEmpty ();
127 // Serial all containers
128 f
.serialCont (_LandVector
);
129 f
.serialCont (_TileSetVector
);
130 f
.serialCont (_TileVector
);
133 // Compute XRef in read mode
137 // If Version<=2, remove diffuse and alpha tiles in transitions
141 nlassert (f
.isReading());
146 // Remove diffuse and additive in transition
147 uint tileCount
=(uint
)getTileCount ();
148 for (uint i
=0; i
<tileCount
; i
++)
155 getTileXRef (i
, tileSet
, number
, type
);
158 if (type
==transition
)
160 // Remove diffuse bitmap
161 getTileSet(tileSet
)->clearTransition ((CTileSet::TTransition
)number
, CTile::diffuse
, *this);
163 // Remove alpha bitmap
164 getTileSet(tileSet
)->clearTransition ((CTileSet::TTransition
)number
, CTile::alpha
, *this);
169 // ***************************************************************************
170 sint
CTileBank::addLand (const std::string
& name
)
172 sint last
=(sint
)_LandVector
.size();
173 _LandVector
.push_back(CTileLand());
174 _LandVector
[last
].setName (name
);
177 // ***************************************************************************
178 void CTileBank::removeLand (sint landIndex
)
181 nlassert (landIndex
>=0);
182 nlassert (landIndex
<(sint
)_LandVector
.size());
184 _LandVector
.erase (_LandVector
.begin ()+landIndex
);
186 // ***************************************************************************
187 sint
CTileBank::addTileSet (const std::string
& name
)
189 sint last
=(sint
)_TileSetVector
.size();
190 _TileSetVector
.push_back(CTileSet());
191 _TileSetVector
[last
].setName (name
);
192 for (int i
=0; i
<CTileSet::count
; i
++)
194 _TileSetVector
[last
]._TileTransition
[i
]._Tile
=createTile ();
198 // ***************************************************************************
199 void CTileBank::removeTileSet (sint setIndex
)
202 nlassert (setIndex
>=0);
203 nlassert (setIndex
<(sint
)_TileSetVector
.size());
205 for (int i
=0; i
<CTileSet::count
; i
++)
207 int index
=_TileSetVector
[setIndex
]._TileTransition
[i
]._Tile
;
211 _TileSetVector
.erase (_TileSetVector
.begin ()+setIndex
);
213 // ***************************************************************************
214 void CTileBank::clear ()
216 _LandVector
.clear ();
217 _TileSetVector
.clear ();
218 _TileVector
.clear ();
220 _DisplacementMap
.clear ();
223 // ***************************************************************************
224 sint
CTileBank::createTile ()
226 // Look for a free tile
227 for (int i
=0; i
<(sint
)_TileVector
.size(); i
++)
229 if (_TileVector
[i
].isFree())
231 _TileVector
[i
].setFileName (CTile::diffuse
, "");
232 _TileVector
[i
].setFileName (CTile::additive
, "");
233 _TileVector
[i
].setFileName (CTile::alpha
, "");
238 // Nothing free, add a tile at the end
239 _TileVector
.push_back (CTile());
240 _TileVector
[_TileVector
.size()-1].setFileName (CTile::diffuse
, "");
241 _TileVector
[_TileVector
.size()-1].setFileName (CTile::additive
, "");
242 _TileVector
[_TileVector
.size()-1].setFileName (CTile::alpha
, "");
243 return (sint
)_TileVector
.size()-1;
245 // ***************************************************************************
246 void CTileBank::freeTile (int tileIndex
)
249 nlassert (tileIndex
>=0);
250 nlassert (tileIndex
<(sint
)_TileVector
.size());
253 _TileVector
[tileIndex
].freeBlock();
257 for (i
=(sint
)_TileVector
.size()-1; i
>=0; i
--)
259 if (!_TileVector
[i
].isFree ())
262 if (i
<(sint
)_TileVector
.size()-1)
263 _TileVector
.resize (i
+1);
265 // ***************************************************************************
266 sint
CTileBank::getNumBitmap (CTile::TBitmap bitmap
) const
268 std::set
<std::string
> setString
;
269 for (int i
=0; i
<(sint
)_TileVector
.size(); i
++)
271 if (!_TileVector
[i
].isFree())
273 const std::string
&str
=_TileVector
[i
].getRelativeFileName (bitmap
);
276 std::vector
<char> vect (str
.length()+1);
277 memcpy (&*vect
.begin(), str
.c_str(), str
.length()+1);
278 toLowerAscii(&*vect
.begin());
279 setString
.insert (std::string (&*vect
.begin()));
283 return (sint
)setString
.size();
285 // ***************************************************************************
286 void CTileBank::computeXRef ()
289 _TileXRef
.resize (_TileVector
.size());
291 // Erase number of the tileset in xref
292 for (int tile
=0; tile
<(sint
)_TileVector
.size(); tile
++)
293 _TileXRef
[tile
]._XRefTileSet
=-1;
295 // Erase number of the tileset in xref
296 for (int s
=0; s
<(sint
)_TileSetVector
.size(); s
++)
299 CTileSet
*tileSet
=getTileSet (s
);
300 for (t
=0; t
<tileSet
->getNumTile128(); t
++)
302 int index
=tileSet
->getTile128 (t
);
303 _TileXRef
[index
]._XRefTileSet
=s
;
304 _TileXRef
[index
]._XRefTileNumber
=t
;
305 _TileXRef
[index
]._XRefTileType
=_128x128
;
307 for (t
=0; t
<tileSet
->getNumTile256(); t
++)
309 int index
=tileSet
->getTile256 (t
);
310 _TileXRef
[index
]._XRefTileSet
=s
;
311 _TileXRef
[index
]._XRefTileNumber
=t
;
312 _TileXRef
[index
]._XRefTileType
=_256x256
;
314 for (t
=0; t
<CTileSet::count
; t
++)
316 int index
=tileSet
->getTransition (t
)->getTile();
317 _TileXRef
[index
]._XRefTileSet
=s
;
318 _TileXRef
[index
]._XRefTileNumber
=t
;
319 _TileXRef
[index
]._XRefTileType
=transition
;
323 // ***************************************************************************
324 void CTileBank::xchgTileset (sint firstTileSet
, sint secondTileSet
)
327 nlassert ((firstTileSet
>=0)&&(firstTileSet
<(sint
)_TileSetVector
.size()));
328 nlassert ((secondTileSet
>=0)&&(secondTileSet
<(sint
)_TileSetVector
.size()));
331 CTileSet tmp
=_TileSetVector
[firstTileSet
];
332 _TileSetVector
[firstTileSet
]=_TileSetVector
[secondTileSet
];
333 _TileSetVector
[secondTileSet
]=tmp
;
335 // ***************************************************************************
336 void TroncFileName (char* sDest
, const char* sSrc
)
338 const char* ptr
=strrchr (sSrc
, '\\');
340 ptr
=strrchr (sSrc
, '/');
348 strcpy (sDest
, sSrc
);
351 // ***************************************************************************
352 // TODO: this is a temporary hack, see if it could be removed
353 void CTileBank::makeAllPathRelative ()
356 for (sint nTile
=0; nTile
<(sint
)_TileVector
.size(); nTile
++)
359 char sTmpFileName
[512];
362 TroncFileName (sTmpFileName
, _TileVector
[nTile
].getRelativeFileName (CTile::diffuse
).c_str());
363 _TileVector
[nTile
].setFileName (CTile::diffuse
, sTmpFileName
);
366 TroncFileName (sTmpFileName
, _TileVector
[nTile
].getRelativeFileName (CTile::additive
).c_str());
367 _TileVector
[nTile
].setFileName (CTile::additive
, sTmpFileName
);
370 TroncFileName (sTmpFileName
, _TileVector
[nTile
].getRelativeFileName (CTile::alpha
).c_str());
371 _TileVector
[nTile
].setFileName (CTile::alpha
, sTmpFileName
);
375 for (uint i
=0; i
<_DisplacementMap
.size(); i
++)
378 char sTmpFileName
[512];
380 TroncFileName (sTmpFileName
, _DisplacementMap
[i
]._FileName
.c_str());
381 _DisplacementMap
[i
]._FileName
= sTmpFileName
;
386 // ***************************************************************************
387 void CTileBank::makeAllExtensionDDS ()
390 for (sint nTile
=0; nTile
<(sint
)_TileVector
.size(); nTile
++)
393 string::size_type pos
;
396 tmp
= _TileVector
[nTile
].getRelativeFileName (CTile::diffuse
);
397 pos
= tmp
.rfind(".tga");
398 if (pos
== string::npos
)
399 pos
= tmp
.rfind(".png");
400 if(pos
!= string::npos
)
402 tmp
.replace(pos
, 4, ".dds");
403 _TileVector
[nTile
].setFileName (CTile::diffuse
, tmp
);
407 tmp
= _TileVector
[nTile
].getRelativeFileName (CTile::additive
);
408 pos
= tmp
.rfind(".tga");
409 if (pos
== string::npos
)
410 pos
= tmp
.rfind(".png");
411 if(pos
!= string::npos
)
413 tmp
.replace(pos
, 4, ".dds");
414 _TileVector
[nTile
].setFileName (CTile::additive
, tmp
);
418 tmp
= _TileVector
[nTile
].getRelativeFileName (CTile::alpha
);
419 pos
= tmp
.rfind(".tga");
420 if (pos
== string::npos
)
421 pos
= tmp
.rfind(".png");
422 if(pos
!= string::npos
)
424 tmp
.replace(pos
, 4, ".dds");
425 _TileVector
[nTile
].setFileName (CTile::alpha
, tmp
);
431 // ***************************************************************************
432 void CTileBank::cleanUnusedData ()
434 // Clean each tileset
435 for (uint i
=0; i
<_TileSetVector
.size(); i
++)
438 _TileSetVector
[i
].cleanUnusedData ();
441 // Clear the land vector
444 // ***************************************************************************
445 CTileNoiseMap
*CTileBank::getTileNoiseMap (uint tileNumber
, uint tileSubNoise
)
447 if (_DisplacementMap
.empty())
449 // it happens when serial a tile bank with version < 4
453 // Check tile number..
454 if (tileNumber
<_TileVector
.size())
456 // Get tileset number
457 uint tileSet
=_TileXRef
[tileNumber
]._XRefTileSet
;
460 if (tileSet
<_TileSetVector
.size())
462 nlassert (tileSubNoise
<CTileSet::CountDisplace
);
463 //nlassert (_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]<_DisplacementMap.size());
465 if (_TileSetVector
[tileSet
]._DisplacementBitmap
[tileSubNoise
]>=_DisplacementMap
.size())
468 // Return the tile noise map
469 CTileNoise
&tileNoise
=_DisplacementMap
[_TileSetVector
[tileSet
]._DisplacementBitmap
[tileSubNoise
]];
472 if (tileNoise
._TileNoiseMap
==NULL
)
475 CTextureFile
texture (getAbsPath()+tileNoise
._FileName
);
476 texture
.loadGrayscaleAsAlpha (false);
478 texture
.convertToType (CBitmap::Luminance
);
481 tileNoise
._TileNoiseMap
=new CTileNoiseMap
;
484 if ((texture
.getWidth ()==NL3D_TILE_NOISE_MAP_SIZE
)&&(texture
.getHeight()==NL3D_TILE_NOISE_MAP_SIZE
))
487 memcpy (tileNoise
._TileNoiseMap
->Pixels
, &texture
.getPixels()[0], NL3D_TILE_NOISE_MAP_SIZE
*NL3D_TILE_NOISE_MAP_SIZE
);
490 for (uint i
=0; i
<NL3D_TILE_NOISE_MAP_SIZE
*NL3D_TILE_NOISE_MAP_SIZE
; i
++)
492 tileNoise
._TileNoiseMap
->Pixels
[i
]=(sint8
)((uint8
)tileNoise
._TileNoiseMap
->Pixels
[i
]-128);
493 if (tileNoise
._TileNoiseMap
->Pixels
[i
]==-128)
494 tileNoise
._TileNoiseMap
->Pixels
[i
]=-127;
499 // This is not a normal behaviour.
500 string pathname
= getAbsPath()+tileNoise
._FileName
;
501 if( texture
.getWidth ()==0 || texture
.getHeight ()==0 )
502 nlwarning("TileNoiseMap not found: %s.", pathname
.c_str());
504 nlwarning("Bad TileNoiseMap size: %s.", pathname
.c_str());
506 // Not good size, copy a static map
507 sint8 notGoodSizeForm
[NL3D_TILE_NOISE_MAP_SIZE
*NL3D_TILE_NOISE_MAP_SIZE
]=
509 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
510 00, 99, 99, 99, 99, 99, 99, 99, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
511 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
512 00, 99, 00, 99, 99, 99, 99, 99, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
513 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
514 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
515 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
516 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
517 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
518 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
519 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
520 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
521 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
522 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
523 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
524 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
525 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
526 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
527 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
528 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
529 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
530 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
531 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
532 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
533 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
534 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
535 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
536 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
537 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 99, 99, 99, 99, 99, 00, 99, 00,
538 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00,
539 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 99, 99, 99, 99, 99, 99, 99, 00,
540 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
544 memcpy (tileNoise
._TileNoiseMap
->Pixels
, notGoodSizeForm
, NL3D_TILE_NOISE_MAP_SIZE
*NL3D_TILE_NOISE_MAP_SIZE
);
548 // Return the noise map
549 return tileNoise
._TileNoiseMap
;
553 if (_DisplacementMap
.empty() || _DisplacementMap
[0]._TileNoiseMap
)
557 nlassert (_DisplacementMap
[0]._TileNoiseMap
);
558 return _DisplacementMap
[0]._TileNoiseMap
;
560 // ***************************************************************************
561 void CTileBank::removeDisplacementMap (uint mapId
)
564 nlassert (mapId
<_DisplacementMap
.size());
568 // Check if another tileSet uses it
570 for (tileSet
=0; tileSet
<_TileSetVector
.size(); tileSet
++)
574 for (tile
=0; tile
<CTileSet::CountDisplace
; tile
++)
577 if (_TileSetVector
[tileSet
]._DisplacementBitmap
[tile
]==mapId
)
581 if (tile
!=CTileSet::CountDisplace
)
584 if (tileSet
==_TileSetVector
.size())
587 _DisplacementMap
[mapId
].reset();
590 if (mapId
==_DisplacementMap
.size()-1)
592 // Resize the array ?
593 while ((mapId
>0)&&(_DisplacementMap
[mapId
]._FileName
.empty()))
594 _DisplacementMap
.resize (mapId
--);
599 // ***************************************************************************
600 uint
CTileBank::getDisplacementMap (const string
&fileName
)
603 string lower
=toLowerAscii(fileName
);
605 // Look for this texture filename
607 for (noiseTile
=0; noiseTile
<_DisplacementMap
.size(); noiseTile
++)
610 if (lower
==_DisplacementMap
[noiseTile
]._FileName
)
614 // Look for a free space
615 for (noiseTile
=0; noiseTile
<_DisplacementMap
.size(); noiseTile
++)
618 if (_DisplacementMap
[noiseTile
]._FileName
.empty())
621 if (noiseTile
==_DisplacementMap
.size())
624 _DisplacementMap
.resize (noiseTile
+1);
628 _DisplacementMap
[noiseTile
]._FileName
=lower
;
632 // ***************************************************************************
633 const char* CTileBank::getDisplacementMap (uint noiseMap
)
635 return _DisplacementMap
[noiseMap
]._FileName
.c_str();
637 // ***************************************************************************
638 void CTileBank::setDisplacementMap (uint noiseMap
, const char *newName
)
640 _DisplacementMap
[noiseMap
]._FileName
=newName
;
642 // ***************************************************************************
643 uint
CTileBank::getDisplacementMapCount () const
645 return (uint
)_DisplacementMap
.size();
649 // ***************************************************************************
650 const CTileVegetableDesc
&CTileBank::getTileVegetableDesc(uint tileNumber
) const
652 // Check tile number..
653 if (tileNumber
<_TileVector
.size())
655 // Get tileset number
656 uint tileSet
=_TileXRef
[tileNumber
]._XRefTileSet
;
659 if (tileSet
<_TileSetVector
.size())
661 return _TileSetVector
[tileSet
].getTileVegetableDesc();
666 // if fails for any reason, return an empty tileVegetableDesc;
667 static CTileVegetableDesc emptyTvd
;
672 // ***************************************************************************
673 void CTileBank::loadTileVegetableDescs()
678 for(tileSet
=0; tileSet
<_TileSetVector
.size(); tileSet
++)
680 // load their fileName
681 _TileSetVector
[tileSet
].loadTileVegetableDesc();
686 // ***************************************************************************
687 void CTileBank::initTileVegetableDescs(CVegetableManager
*vegetableManager
)
692 for(tileSet
=0; tileSet
<_TileSetVector
.size(); tileSet
++)
694 CTileVegetableDesc
&tvd
= _TileSetVector
[tileSet
].getTileVegetableDesc();
695 tvd
.registerToManager(vegetableManager
);
700 // ***************************************************************************
701 void CTileBank::postfixTileFilename (const char *postfix
)
705 for (tile
=0; tile
<_TileVector
.size (); tile
++)
709 for (bitmap
=0; bitmap
<CTile::bitmapCount
; bitmap
++)
711 string
&filename
= _TileVector
[tile
]._BitmapName
[bitmap
];
712 if (!filename
.empty())
714 string ext
= CFile::getExtension(filename
);
715 string name
= CFile::getFilenameWithoutExtension(filename
);
716 filename
= CFile::getPath (filename
);
727 // ***************************************************************************
728 void CTileBank::postfixTileVegetableDesc (const char *postfix
)
732 for (tileSet
=0; tileSet
<_TileSetVector
.size (); tileSet
++)
734 string
&filename
= _TileSetVector
[tileSet
]._TileVegetableDescFileName
;
735 if (!filename
.empty())
737 string ext
= CFile::getExtension(filename
);
738 string name
= CFile::getFilenameWithoutExtension(filename
);
739 filename
= CFile::getPath (filename
);
749 // ***************************************************************************
750 // ***************************************************************************
752 // ***************************************************************************
753 // ***************************************************************************
756 // ***************************************************************************
757 const sint
CTile::_Version
=4;
758 // ***************************************************************************
759 void CTile::serial(NLMISC::IStream
&f
)
761 sint streamver
= f
.serialVersion(_Version
);
774 // Version 2, flags are not the same
776 _Flags
=(_Flags
&NL3D_CTILE_ROT_MASK
)|(_Flags
&NL3D_CTILE_GROUP_MASK_V2
)|(((_Flags
&NL3D_CTILE_FREE_FLAG_V2
)!=0)?NL3D_CTILE_FREE_FLAG
:0);
778 _Flags
=(_Flags
&NL3D_CTILE_ROT_MASK
)|(_Flags
&NL3D_CTILE_GROUP_MASK_V3
)|(((_Flags
&NL3D_CTILE_FREE_FLAG_V3
)!=0)?NL3D_CTILE_FREE_FLAG
:0);
780 f
.serial (_BitmapName
[diffuse
]);
781 f
.serial (_BitmapName
[additive
]);
782 f
.serial (_BitmapName
[alpha
]);
785 // Don't need invert many more
791 // Initialize alpha name
792 _BitmapName
[alpha
].clear();
797 // If free, set the flag
799 _Flags
|=NL3D_CTILE_FREE_FLAG
;
801 // Read diffuse bitmap and additive
802 f
.serial (_BitmapName
[diffuse
]);
803 f
.serial (_BitmapName
[additive
]);
805 // Don't need bump name
811 // ***************************************************************************
812 void CTile::clearTile (CTile::TBitmap type
)
814 _BitmapName
[type
].clear();
818 // ***************************************************************************
819 // ***************************************************************************
821 // ***************************************************************************
822 // ***************************************************************************
825 // ***************************************************************************
826 const sint
CTileSet::_Version
=5;
827 // ***************************************************************************
828 const char* CTileSet::_ErrorMessage
[CTileSet::errorCount
]=
831 "Top interface is incompatible.", // topInterfaceProblem
832 "Bottom interface is incompatible.", // bottomInterfaceProblem
833 "Left interface is incompatible.", // leftInterfaceProblem
834 "Right interface is incompatible.", // rightInterfaceProblem
835 "Add first a 128x128 tile.", // addFirstA128128
836 "Top and bottom interface not the same.", // topBottomNotTheSame,
837 "Right and left interface not the same.", // rightLeftNotTheSame
838 "Invalide bitmap size.", // sizeInvalide
840 // ***************************************************************************
841 const CTileSet::TFlagBorder
CTileSet::_TransitionFlags
[CTileSet::count
][4]=
843 {_0000
,_1111
,_0111
,_0111
}, // tile 0
844 {_0111
,_1111
,_0111
,_1111
}, // tile 1
845 {_0000
,_0111
,_0000
,_0111
}, // tile 2
846 {_1110
,_1110
,_1111
,_0000
}, // tile 3
847 {_1110
,_1111
,_1111
,_0111
}, // tile 4
848 {_0000
,_1110
,_0111
,_0000
}, // tile 5
850 {_0000
,_1111
,_0001
,_0001
}, // tile 6
851 {_0000
,_1000
,_0001
,_0000
}, // tile 7
852 {_1111
,_1000
,_1111
,_1000
}, // tile 8
853 {_1000
,_1000
,_1111
,_0000
}, // tile 9
854 {_1000
,_0000
,_1000
,_0000
}, // tile 10
855 {_1111
,_0001
,_1000
,_1111
}, // tile 11
857 {_0000
,_1111
,_0111
,_0001
}, // tile 12
858 {_0000
,_1111
,_0001
,_0111
}, // tile 13
859 {_0111
,_1111
,_0001
,_1111
}, // tile 14
860 {_1110
,_1000
,_1111
,_0000
}, // tile 15
861 {_1000
,_1110
,_1111
,_0000
}, // tile 16
862 {_1111
,_0001
,_1110
,_1111
}, // tile 17
864 {_1000
,_0000
,_1110
,_0000
}, // tile 18
865 {_0000
,_0111
,_0000
,_0001
}, // tile 19
866 {_1111
,_1000
,_1111
,_1110
}, // tile 21
867 {_0111
,_0000
,_0000
,_1000
}, // tile 21
868 {_0000
,_1000
,_0111
,_0000
}, // tile 22
869 {_1111
,_0111
,_1000
,_1111
}, // tile 23
871 {_1111
,_0000
,_1110
,_1110
}, // tile 24
872 {_1111
,_1110
,_1111
,_1110
}, // tile 25
873 {_1110
,_0000
,_1110
,_0000
}, // tile 26
874 {_0111
,_0111
,_0000
,_1111
}, // tile 27
875 {_1111
,_0111
,_1110
,_1111
}, // tile 28
876 {_0111
,_0000
,_0000
,_1110
}, // tile 29
878 {_1111
,_0000
,_1000
,_1000
}, // tile 30
879 {_0001
,_0000
,_0000
,_1000
}, // tile 31
880 {_0001
,_1111
,_0001
,_1111
}, // tile 32
881 {_0001
,_0001
,_0000
,_1111
}, // tile 33
882 {_0000
,_0001
,_0000
,_0001
}, // tile 34
883 {_1000
,_1111
,_1111
,_0001
}, // tile 35
885 {_1111
,_0000
,_1000
,_1110
}, // tile 36
886 {_1111
,_0000
,_1110
,_1000
}, // tile 37
887 {_1000
,_1111
,_1111
,_0111
}, // tile 38
888 {_0001
,_0111
,_0000
,_1111
}, // tile 39
889 {_0111
,_0001
,_0000
,_1111
}, // tile 40
890 {_1111
,_1110
,_1111
,_1000
}, // tile 41
892 {_0000
,_0001
,_0000
,_0111
}, // tile 42
893 {_1110
,_0000
,_1000
,_0000
}, // tile 43
894 {_0001
,_1111
,_0111
,_1111
}, // tile 44
895 {_0000
,_1110
,_0001
,_0000
}, // tile 45
896 {_0001
,_0000
,_0000
,_1110
}, // tile 46
897 {_1110
,_1111
,_1111
,_0001
} // tile 47
899 // ***************************************************************************
900 CTileSet::CTileSet ()
902 // Default, tileset 0
905 for (displace
=FirstDisplace
; displace
<CountDisplace
; displace
++)
906 _DisplacementBitmap
[displace
]=0;
908 // Default user surface data
911 // ***************************************************************************
912 void CTileSet::setName (const std::string
& name
)
916 // ***************************************************************************
917 const std::string
& CTileSet::getName () const
921 // ***************************************************************************
922 void CTileSet::serial(NLMISC::IStream
&f
)
924 sint streamver
= f
.serialVersion(_Version
);
928 // serial the user surface data
931 f
.serial (SurfaceData
);
934 // serial the oriented info which tell if the tile has a special orientation
937 f
.serial (_Oriented
);
940 // serial vegetable info.
943 // serialisze only the FileName, not the descrpitor
944 f
.serial(_TileVegetableDescFileName
);
951 for (displace
=FirstDisplace
; displace
<CountDisplace
; displace
++)
952 f
.serial (_DisplacementBitmap
[displace
]);
955 // Serial displacement map filename, obsolete
958 // Remove obsolete data
960 for (uint displace
=FirstDisplace
; displace
<CountDisplace
; displace
++)
966 f
.serialCont (_Tile128
);
967 f
.serialCont (_Tile256
);
968 for (i
=0; i
<count
; i
++)
969 f
.serial (_TileTransition
[i
]);
970 f
.serialCont (_ChildName
);
971 f
.serial (_Border128
[CTile::diffuse
]);
972 f
.serial (_Border128
[CTile::additive
]);
974 // old field, border bump 128
978 f
.serial (_Border256
[CTile::diffuse
]);
979 f
.serial (_Border256
[CTile::additive
]);
981 // old field, border bump 256
985 for (i
=0; i
<count
; i
++)
987 f
.serial (_BorderTransition
[i
][CTile::diffuse
]);
988 f
.serial (_BorderTransition
[i
][CTile::additive
]);
989 f
.serial (_BorderTransition
[i
][CTile::alpha
]);
991 // Reset the diffuse and alpha border if old version
994 _BorderTransition
[i
][CTile::diffuse
].reset();
995 _BorderTransition
[i
][CTile::alpha
].reset();
999 // ***************************************************************************
1000 void CTileSet::addTile128 (int& indexInTileSet
, CTileBank
& bank
)
1003 sint index
=bank
.createTile ();
1005 // Index of the new tile
1006 indexInTileSet
=(int)_Tile128
.size();
1008 // Add to the end of the list
1009 _Tile128
.push_back (index
);
1011 // ***************************************************************************
1012 void CTileSet::setBorder (CTile::TBitmap type
, const CTileBorder
& border
)
1014 // This is our new border desc
1015 _Border128
[type
]=border
;
1016 _Border256
[type
]=border
;
1017 _Border256
[type
].doubleSize ();
1019 // ***************************************************************************
1020 void CTileSet::setTile128 (int indexInTileSet
, const std::string
& name
, CTile::TBitmap type
, CTileBank
& bank
)
1023 CTile
*tile
=bank
.getTile (_Tile128
[indexInTileSet
]);
1024 tile
->setFileName (type
, name
);
1025 tile
->setRotAlpha (0);
1027 // ***************************************************************************
1028 CTileSet::TError
CTileSet::checkTile128 (CTile::TBitmap type
, const CTileBorder
& border
, int& pixel
, int& composante
)
1031 if ((border
.getWidth()!=128)||(border
.getHeight()!=128))
1032 return sizeInvalide
;
1033 if (!CTileBorder::compare (border
, border
, CTileBorder::top
, CTileBorder::bottom
, pixel
, composante
))
1034 return topBottomNotTheSame
;
1035 if (!CTileBorder::compare (border
, border
, CTileBorder::left
, CTileBorder::right
, pixel
, composante
))
1036 return rightLeftNotTheSame
;
1039 if (_Border128
[type
].isSet())
1042 if (!CTileBorder::compare (border
, _Border128
[type
], CTileBorder::top
, CTileBorder::top
, pixel
, composante
))
1043 return topInterfaceProblem
;
1044 if (!CTileBorder::compare (border
, _Border128
[type
], CTileBorder::bottom
, CTileBorder::bottom
, pixel
, composante
))
1045 return bottomInterfaceProblem
;
1046 if (!CTileBorder::compare (border
, _Border128
[type
], CTileBorder::left
, CTileBorder::left
, pixel
, composante
))
1047 return leftInterfaceProblem
;
1048 if (!CTileBorder::compare (border
, _Border128
[type
], CTileBorder::right
, CTileBorder::right
, pixel
, composante
))
1049 return rightInterfaceProblem
;
1053 return addFirstA128128
;
1058 // ***************************************************************************
1059 void CTileSet::addTile256 (int& indexInTileSet
, CTileBank
& bank
)
1062 sint index
=bank
.createTile ();
1064 // Index of the new tile
1065 indexInTileSet
=(int)_Tile256
.size();
1067 // Add to the end of the list
1068 _Tile256
.push_back (index
);
1070 // ***************************************************************************
1071 CTileSet::TError
CTileSet::checkTile256 (CTile::TBitmap type
, const CTileBorder
& border
, int& pixel
, int& composante
)
1074 if ((border
.getWidth()!=256)||(border
.getHeight()!=256))
1075 return sizeInvalide
;
1076 if (!CTileBorder::compare (border
, border
, CTileBorder::top
, CTileBorder::bottom
, pixel
, composante
))
1077 return topBottomNotTheSame
;
1078 if (!CTileBorder::compare (border
, border
, CTileBorder::left
, CTileBorder::right
, pixel
, composante
))
1079 return rightLeftNotTheSame
;
1082 if ((!_Border256
[type
].isSet())&&(_Border128
[type
].isSet()))
1084 _Border256
[type
]=_Border128
[type
];
1085 _Border256
[type
].doubleSize ();
1089 if (_Border256
[type
].isSet())
1093 if (!CTileBorder::compare (border
, _Border256
[type
], CTileBorder::top
, CTileBorder::top
, pixel
, composante
))
1094 return topInterfaceProblem
;
1095 if (!CTileBorder::compare (border
, _Border256
[type
], CTileBorder::bottom
, CTileBorder::bottom
, pixel
, composante
))
1096 return bottomInterfaceProblem
;
1097 if (!CTileBorder::compare (border
, _Border256
[type
], CTileBorder::left
, CTileBorder::left
, pixel
, composante
))
1098 return leftInterfaceProblem
;
1099 if (!CTileBorder::compare (border
, _Border256
[type
], CTileBorder::right
, CTileBorder::right
, pixel
, composante
))
1100 return rightInterfaceProblem
;
1104 return addFirstA128128
;
1109 // ***************************************************************************
1110 void CTileSet::setTile256 (int indexInTileSet
, const std::string
& name
, CTile::TBitmap type
, CTileBank
& bank
)
1113 CTile
*tile
=bank
.getTile (_Tile256
[indexInTileSet
]);
1114 tile
->setFileName (type
, name
);
1115 tile
->setRotAlpha (0);
1117 // ***************************************************************************
1118 void CTileSet::setTileTransition (TTransition transition
, const std::string
& name
, CTile::TBitmap type
, CTileBank
& bank
,
1119 const CTileBorder
& border
)
1121 // Check is not an alpha channel
1122 nlassert (type
!=CTile::alpha
); // use setTileTransitionAlpha
1125 _BorderTransition
[transition
][type
]=border
;
1127 // Set the tile file name
1128 CTile
*tile
=bank
.getTile (_TileTransition
[transition
]._Tile
);
1129 tile
->setFileName (type
, name
);
1131 // ***************************************************************************
1132 void CTileSet::setTileTransitionAlpha (TTransition transition
, const std::string
& name
, CTileBank
& bank
,
1133 const CTileBorder
& border
, uint8 rot
)
1139 _BorderTransition
[transition
][CTile::alpha
]=border
;
1141 // Set the tile file name
1142 CTile
*tile
=bank
.getTile (_TileTransition
[transition
]._Tile
);
1143 tile
->setFileName (CTile::alpha
, name
);
1144 tile
->setRotAlpha (rot
);
1146 // ***************************************************************************
1147 CTileSet::TError
CTileSet::checkTileTransition (TTransition transition
, CTile::TBitmap type
, const CTileBorder
& border
, int& indexError
,
1148 int& pixel
, int& composante
)
1150 nlassert (transition
>=0);
1151 nlassert (transition
<count
);
1157 indexError
=getExistingTransitionTile ((TFlagBorder
)_TransitionFlags
[transition
][top
], dontcare
, dontcare
, dontcare
, transition
, type
);
1160 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::top
, CTileBorder::top
, pixel
, composante
))
1161 return topInterfaceProblem
;
1163 indexError
=getExistingTransitionTile (dontcare
, (TFlagBorder
)_TransitionFlags
[transition
][top
], dontcare
, dontcare
, transition
, type
);
1166 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::top
, CTileBorder::bottom
, pixel
, composante
))
1167 return topInterfaceProblem
;
1170 if (_TransitionFlags
[transition
][top
]==_1111
)
1172 if (!CTileBorder::allAlphaSet (border
, CTileBorder::top
, pixel
, composante
))
1173 return topInterfaceProblem
;
1177 indexError
=getExistingTransitionTile (dontcare
, (TFlagBorder
)_TransitionFlags
[transition
][bottom
], dontcare
, dontcare
, transition
, type
);
1180 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::bottom
, CTileBorder::bottom
, pixel
, composante
))
1181 return bottomInterfaceProblem
;
1183 indexError
=getExistingTransitionTile ((TFlagBorder
)_TransitionFlags
[transition
][bottom
], dontcare
, dontcare
, dontcare
, transition
, type
);
1186 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::bottom
, CTileBorder::top
, pixel
, composante
))
1187 return bottomInterfaceProblem
;
1190 if (_TransitionFlags
[transition
][bottom
]==_1111
)
1192 if (!CTileBorder::allAlphaSet (border
, CTileBorder::bottom
, pixel
, composante
))
1193 return bottomInterfaceProblem
;
1197 indexError
=getExistingTransitionTile (dontcare
, dontcare
, (TFlagBorder
)_TransitionFlags
[transition
][left
], dontcare
, transition
, type
);
1200 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::left
, CTileBorder::left
, pixel
, composante
))
1201 return leftInterfaceProblem
;
1203 indexError
=getExistingTransitionTile (dontcare
, dontcare
, dontcare
, (TFlagBorder
)_TransitionFlags
[transition
][left
], transition
, type
);
1206 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::left
, CTileBorder::right
, pixel
, composante
))
1207 return leftInterfaceProblem
;
1210 if (_TransitionFlags
[transition
][left
]==_1111
)
1212 if (!CTileBorder::allAlphaSet (border
, CTileBorder::left
, pixel
, composante
))
1213 return leftInterfaceProblem
;
1217 indexError
=getExistingTransitionTile (dontcare
, dontcare
, dontcare
, (TFlagBorder
)_TransitionFlags
[transition
][right
], transition
, type
);
1220 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::right
, CTileBorder::right
, pixel
, composante
))
1221 return rightInterfaceProblem
;
1223 indexError
=getExistingTransitionTile (dontcare
, dontcare
, (TFlagBorder
)_TransitionFlags
[transition
][right
], dontcare
, transition
, type
);
1226 if (!CTileBorder::compare (border
, _BorderTransition
[indexError
][type
], CTileBorder::right
, CTileBorder::left
, pixel
, composante
))
1227 return rightInterfaceProblem
;
1230 if (_TransitionFlags
[transition
][right
]==_1111
)
1232 if (!CTileBorder::allAlphaSet (border
, CTileBorder::right
, pixel
, composante
))
1233 return rightInterfaceProblem
;
1237 // ***************************************************************************
1238 void CTileSet::removeTile128 (int indexInTileSet
, CTileBank
& bank
)
1241 nlassert (indexInTileSet
>=0);
1242 nlassert (indexInTileSet
<(sint
)_Tile128
.size());
1245 int index
=_Tile128
[indexInTileSet
];
1248 _Tile128
.erase (_Tile128
.begin()+indexInTileSet
);
1249 bank
.freeTile (index
);
1251 // Erase border if it is the last texture
1252 deleteBordersIfLast (bank
, CTile::diffuse
);
1253 deleteBordersIfLast (bank
, CTile::additive
);
1254 deleteBordersIfLast (bank
, CTile::alpha
);
1256 // ***************************************************************************
1257 void CTileSet::removeTile256 (int indexInTileSet
, CTileBank
& bank
)
1260 nlassert (indexInTileSet
>=0);
1261 nlassert (indexInTileSet
<(sint
)_Tile256
.size());
1264 int index
=_Tile256
[indexInTileSet
];
1267 _Tile256
.erase (_Tile256
.begin()+indexInTileSet
);
1268 bank
.freeTile (index
);
1270 // Erase border if it is the last texture
1271 deleteBordersIfLast (bank
, CTile::diffuse
);
1272 deleteBordersIfLast (bank
, CTile::additive
);
1273 deleteBordersIfLast (bank
, CTile::alpha
);
1275 // ***************************************************************************
1276 CTileSet::TTransition
CTileSet::getTransitionTile (TFlagBorder _top
, TFlagBorder _bottom
, TFlagBorder _left
, TFlagBorder _right
)
1278 for (int n
=first
; n
<count
; n
++)
1280 if (((_top
==dontcare
)||(_top
==(TFlagBorder
)_TransitionFlags
[n
][top
]))&&
1281 ((_bottom
==dontcare
)||(_bottom
==(TFlagBorder
)_TransitionFlags
[n
][bottom
]))&&
1282 ((_left
==dontcare
)||(_left
==(TFlagBorder
)_TransitionFlags
[n
][left
]))&&
1283 ((_right
==dontcare
)||(_right
==(TFlagBorder
)_TransitionFlags
[n
][right
])))
1285 return (TTransition
)n
;
1290 // ***************************************************************************
1291 CTileSet::TTransition
CTileSet::getExistingTransitionTile (TFlagBorder _top
, TFlagBorder _bottom
, TFlagBorder _left
, TFlagBorder _right
, int reject
, CTile::TBitmap type
)
1293 for (int n
=first
; n
<count
; n
++)
1296 (_BorderTransition
[n
][type
].isSet ())&&
1297 ((_top
==dontcare
)||(_top
==(TFlagBorder
)_TransitionFlags
[n
][top
]))&&
1298 ((_bottom
==dontcare
)||(_bottom
==(TFlagBorder
)_TransitionFlags
[n
][bottom
]))&&
1299 ((_left
==dontcare
)||(_left
==(TFlagBorder
)_TransitionFlags
[n
][left
]))&&
1300 ((_right
==dontcare
)||(_right
==(TFlagBorder
)_TransitionFlags
[n
][right
])))
1302 return (TTransition
)n
;
1307 // ***************************************************************************
1308 void CTileSet::addChild (const std::string
& name
)
1310 _ChildName
.insert (name
);
1312 // ***************************************************************************
1313 void CTileSet::removeChild (const std::string
& name
)
1315 _ChildName
.erase (name
);
1317 // ***************************************************************************
1318 CTileSet::TTransition
CTileSet::getComplementaryTransition (TTransition transition
)
1320 nlassert ((transition
>=first
)&&(transition
<=last
));
1321 TTransition trans
=getTransitionTile (getComplementaryBorder (_TransitionFlags
[transition
][top
]),
1322 getComplementaryBorder (_TransitionFlags
[transition
][bottom
]),
1323 getComplementaryBorder (_TransitionFlags
[transition
][left
]),
1324 getComplementaryBorder (_TransitionFlags
[transition
][right
]));
1326 nlassert (trans
!=notfound
);
1330 // ***************************************************************************
1331 CTileSet::TFlagBorder
CTileSet::getComplementaryBorder (TFlagBorder border
)
1352 // ***************************************************************************
1353 CTileSet::TFlagBorder
CTileSet::getInvertBorder (TFlagBorder border
)
1374 // ***************************************************************************
1375 CTileSet::TFlagBorder
CTileSet::getOrientedBorder (TBorder where
, TFlagBorder border
)
1384 return getInvertBorder (border
);
1390 // ***************************************************************************
1391 CTileSet::TTransition
CTileSet::rotateTransition (TTransition transition
)
1393 return getTransitionTile (
1394 getOrientedBorder (top
, getOrientedBorder (right
, _TransitionFlags
[transition
][right
])), // top
1395 getOrientedBorder (bottom
, getOrientedBorder (left
, _TransitionFlags
[transition
][left
])), // bottom
1396 getOrientedBorder (left
, getOrientedBorder (top
, _TransitionFlags
[transition
][top
])), // left
1397 getOrientedBorder (right
, getOrientedBorder (bottom
, _TransitionFlags
[transition
][bottom
])) // right
1400 // ***************************************************************************
1401 void CTileSet::clearTile128 (int indexInTileSet
, CTile::TBitmap type
, CTileBank
& bank
)
1403 int nTile
=_Tile128
[indexInTileSet
];
1404 bank
.getTile (nTile
)->clearTile(type
);
1406 // Erase border if it is the last texture
1407 deleteBordersIfLast (bank
, type
);
1409 // ***************************************************************************
1410 void CTileSet::clearTile256 (int indexInTileSet
, CTile::TBitmap type
, CTileBank
& bank
)
1412 int nTile
=_Tile256
[indexInTileSet
];
1413 bank
.getTile (nTile
)->clearTile(type
);
1415 // Erase border if it is the last texture
1416 deleteBordersIfLast (bank
, type
);
1418 // ***************************************************************************
1419 void CTileSet::clearTransition (TTransition transition
, CTile::TBitmap type
, CTileBank
& bank
)
1421 int nTile
=_TileTransition
[transition
]._Tile
;
1423 bank
.getTile (nTile
)->clearTile(type
);
1424 _BorderTransition
[transition
][type
].reset();
1426 // Erase border if it is the last texture
1427 deleteBordersIfLast (bank
, type
);
1429 // ***************************************************************************
1430 // Delete 128 and 256 borders if no more valid texture file name for each bitmap type.
1431 void CTileSet::deleteBordersIfLast (const CTileBank
& bank
, CTile::TBitmap type
)
1437 std::vector
<sint32
>::iterator ite
=_Tile128
.begin();
1439 // Check all the 128x128 tiles
1440 while (ite
!=_Tile128
.end())
1442 // If the file name is valid
1443 if (!bank
.getTile (*ite
)->getRelativeFileName(type
).empty())
1451 // If break, not empty, return
1452 if (ite
!=_Tile128
.end())
1455 // Check all the 256x256 tiles
1456 ite
=_Tile256
.begin();
1457 while (ite
!=_Tile256
.end())
1459 // If the file name is valid
1460 if (!bank
.getTile (*ite
)->getRelativeFileName(type
).empty())
1468 // If break, not empty, return
1469 if (ite
!=_Tile256
.end())
1473 // Check all the transitions tiles
1475 for (trans
=0; trans
<count
; trans
++)
1477 // Get the tile associed with the transition
1478 int nTile
=_TileTransition
[trans
]._Tile
;
1480 // If it is not NULL..
1483 // If the file name is valid
1484 if (!bank
.getTile (nTile
)->getRelativeFileName(type
).empty())
1495 // Ok, erase borders because no tile use it anymore
1496 _Border128
[type
].reset();
1497 _Border256
[type
].reset();
1499 // ***************************************************************************
1500 void CTileSet::clearDisplacement (TDisplacement displacement
, CTileBank
& bank
)
1503 nlassert (displacement
>=FirstDisplace
);
1504 nlassert (displacement
<=LastDisplace
);
1507 int id
=_DisplacementBitmap
[displacement
];
1510 _DisplacementBitmap
[displacement
]=0;
1512 // Tell the bank we remove it
1513 bank
.removeDisplacementMap (id
);
1515 // ***************************************************************************
1516 void CTileSet::setDisplacement (TDisplacement displacement
, const std::string
& fileName
, CTileBank
& bank
)
1519 nlassert (displacement
>=FirstDisplace
);
1520 nlassert (displacement
<=LastDisplace
);
1523 bank
.removeDisplacementMap (_DisplacementBitmap
[displacement
]);
1525 // Get displacement map
1526 _DisplacementBitmap
[displacement
]=bank
.getDisplacementMap (fileName
);
1528 // ***************************************************************************
1529 void CTileSet::cleanUnusedData ()
1533 _Border128
[0].reset ();
1534 _Border128
[1].reset ();
1535 _Border256
[0].reset ();
1536 _Border256
[1].reset ();
1537 for (uint i
=0; i
<count
; i
++)
1538 for (uint j
=0; j
<CTile::bitmapCount
; j
++)
1539 _BorderTransition
[i
][j
].reset();
1543 // ***************************************************************************
1544 void CTileSet::setTileVegetableDescFileName (const std::string
&fileName
)
1546 _TileVegetableDescFileName
= fileName
;
1548 // ***************************************************************************
1549 const std::string
& CTileSet::getTileVegetableDescFileName () const
1551 return _TileVegetableDescFileName
;
1553 // ***************************************************************************
1554 void CTileSet::setTileVegetableDesc (const CTileVegetableDesc
&tvd
)
1556 _TileVegetableDesc
= tvd
;
1559 // ***************************************************************************
1560 CTileVegetableDesc
&CTileSet::getTileVegetableDesc()
1562 return _TileVegetableDesc
;
1565 // ***************************************************************************
1566 const CTileVegetableDesc
&CTileSet::getTileVegetableDesc() const
1568 return _TileVegetableDesc
;
1571 // ***************************************************************************
1572 void CTileSet::loadTileVegetableDesc()
1574 if(!_TileVegetableDescFileName
.empty())
1578 string fname
= CPath::lookup(_TileVegetableDescFileName
);
1580 // load the TileVegetableDesc
1581 f
.serial(_TileVegetableDesc
);
1583 catch(const Exception
&e
)
1585 nlinfo("Error loading TileVegetableDesc: %s", e
.what());
1591 // ***************************************************************************
1592 // ***************************************************************************
1594 // ***************************************************************************
1595 // ***************************************************************************
1598 // ***************************************************************************
1599 const sint
CTileBorder::_Version
=0;
1600 // ***************************************************************************
1601 void CTileBorder::serial(NLMISC::IStream
&f
)
1603 (void)f
.serialVersion(_Version
);
1608 f
.serialCont (_Borders
[top
]);
1609 f
.serialCont (_Borders
[bottom
]);
1610 f
.serialCont (_Borders
[left
]);
1611 f
.serialCont (_Borders
[right
]);
1613 // ***************************************************************************
1614 void CTileBorder::set (int width
, int height
, const std::vector
<CBGRA
>& array
)
1618 nlassert (height
>0);
1619 nlassert ((sint
)array
.size()==width
*height
);
1626 int lastLine
=(_Height
-1)*width
;
1627 int lastCol
=(_Width
-1);
1628 _Borders
[top
].resize (_Width
);
1629 _Borders
[bottom
].resize (_Width
);
1630 _Borders
[left
].resize (_Height
);
1631 _Borders
[right
].resize (_Height
);
1633 // Copy top/bottom border
1634 for (int w
=0; w
<_Width
; w
++)
1636 _Borders
[top
][w
]=array
[w
];
1637 _Borders
[bottom
][w
]=array
[w
+lastLine
];
1640 // Copy left/right border
1641 for (int h
=0; h
<_Height
; h
++)
1643 _Borders
[left
][h
]=array
[h
*_Width
];
1644 _Borders
[right
][h
]=array
[h
*_Width
+lastCol
];
1650 // ***************************************************************************
1651 void CTileBorder::get (int &width
, int &height
, std::vector
<CBGRA
>& array
) const
1659 array
.resize (_Width
*_Height
);
1660 nlassert (_Borders
[bottom
].size()==(uint
)_Width
);
1661 nlassert (_Borders
[top
].size()==(uint
)_Width
);
1662 nlassert (_Borders
[left
].size()==(uint
)_Height
);
1663 nlassert (_Borders
[right
].size()==(uint
)_Height
);
1667 for (int p
=0; p
<_Width
*_Height
; p
++)
1673 int lastLine
=(_Height
-1)*_Width
;
1674 int lastCol
=(_Width
-1);
1676 // Copy top/bottom border
1677 for (int w
=0; w
<_Width
; w
++)
1679 array
[w
]=_Borders
[top
][w
];
1680 array
[w
+lastLine
]=_Borders
[bottom
][w
];
1683 // Copy left/right border
1684 for (int h
=0; h
<_Height
; h
++)
1686 array
[h
*_Width
]=_Borders
[left
][h
];
1687 array
[h
*_Width
+lastCol
]=_Borders
[right
][h
];
1697 // ***************************************************************************
1698 bool CTileBorder::compare (const CTileBorder
& border1
, const CTileBorder
& border2
, TBorder where1
, TBorder where2
, int& pixel
, int& composante
)
1700 // Check border is initialized
1701 nlassert (border1
.isSet());
1702 nlassert (border2
.isSet());
1704 if (border1
._Borders
[where1
].size()!=border2
._Borders
[where2
].size())
1706 for (pixel
=0; pixel
<(int)border1
._Borders
[where1
].size(); pixel
++)
1708 if (border1
._Borders
[where1
][pixel
].R
!=border2
._Borders
[where2
][pixel
].R
)
1713 else if (border1
._Borders
[where1
][pixel
].G
!=border2
._Borders
[where2
][pixel
].G
)
1718 else if (border1
._Borders
[where1
][pixel
].B
!=border2
._Borders
[where2
][pixel
].B
)
1723 else if (border1
._Borders
[where1
][pixel
].A
!=border2
._Borders
[where2
][pixel
].A
)
1732 // ***************************************************************************
1733 bool CTileBorder::allAlphaSet (const CTileBorder
& border
, TBorder where
, int& pixel
, int& composante
)
1735 // Check border is initialized
1736 nlassert (border
.isSet());
1741 for (pixel
=0; pixel
<(int)border
._Borders
[where
].size(); pixel
++)
1743 if (border
._Borders
[where
][pixel
].A
!=0xff)
1749 // ***************************************************************************
1750 bool CTileBorder::operator== (const CTileBorder
& border
) const
1752 return (_Width
==border
._Width
) && (_Height
==border
._Height
) && (_Borders
==border
._Borders
);
1754 // ***************************************************************************
1755 void CTileBorder::operator= (const CTileBorder
& border
)
1758 _Width
=border
._Width
;
1759 _Height
=border
._Width
;
1760 _Borders
[top
]=border
._Borders
[top
];
1761 _Borders
[bottom
]=border
._Borders
[bottom
];
1762 _Borders
[left
]=border
._Borders
[left
];
1763 _Borders
[right
]=border
._Borders
[right
];
1766 // ***************************************************************************
1767 void CTileBorder::doubleSize ()
1769 _Borders
[top
].resize (_Width
*2);
1770 _Borders
[bottom
].resize (_Width
*2);
1771 _Borders
[left
].resize (_Height
*2);
1772 _Borders
[right
].resize (_Height
*2);
1774 for (int w
=0; w
<_Width
; w
++)
1776 _Borders
[top
][w
+_Width
]=_Borders
[top
][w
];
1777 _Borders
[bottom
][w
+_Width
]=_Borders
[bottom
][w
];
1779 for (int h
=0; h
<_Height
; h
++)
1781 _Borders
[left
][h
+_Height
]=_Borders
[left
][h
];
1782 _Borders
[right
][h
+_Height
]=_Borders
[right
][h
];
1785 // ***************************************************************************
1786 void CTileBorder::rotate()
1789 std::vector
<NLMISC::CBGRA
> tmpLeft
=_Borders
[left
];
1791 // Top inverted becomes left
1793 size
=(uint
)_Borders
[top
].size();
1794 _Borders
[left
].resize (size
);
1797 for (i
=0; i
<size
; i
++)
1798 _Borders
[left
][i
]=_Borders
[top
][size
-i
-1];
1801 _Borders
[top
]=_Borders
[right
];
1803 // bottom inverted becomes right
1804 size
=(uint
)_Borders
[bottom
].size();
1805 _Borders
[right
].resize (size
);
1808 for (i
=0; i
<size
; i
++)
1809 _Borders
[right
][i
]=_Borders
[bottom
][size
-i
-1];
1811 // Left become bottom
1812 _Borders
[bottom
]=tmpLeft
;
1815 sint32 tmpSize
=_Width
;
1820 // ***************************************************************************
1821 // ***************************************************************************
1822 // CTileSetTransition.
1823 // ***************************************************************************
1824 // ***************************************************************************
1827 // ***************************************************************************
1828 const sint
CTileSetTransition::_Version
=1;
1829 // ***************************************************************************
1830 void CTileSetTransition::serial(NLMISC::IStream
&f
)
1832 sint streamver
= f
.serialVersion(_Version
);
1840 f
.serial (doomy
); // skip the old argu
1848 // ***************************************************************************
1851 // ***************************************************************************
1852 // ***************************************************************************
1854 // ***************************************************************************
1855 // ***************************************************************************
1858 // ***************************************************************************
1859 CTileNoise::CTileNoise ()
1864 // ***************************************************************************
1865 CTileNoise::CTileNoise (const CTileNoise
&src
)
1873 // ***************************************************************************
1874 CTileNoise::~CTileNoise ()
1878 delete _TileNoiseMap
;
1882 // ***************************************************************************
1883 CTileNoise
& CTileNoise::operator= (const CTileNoise
&src
)
1885 // Copy the filename
1886 _FileName
=src
._FileName
;
1889 if (src
._TileNoiseMap
)
1891 if (_TileNoiseMap
==NULL
)
1894 _TileNoiseMap
=new CTileNoiseMap
;
1897 // Copy the noise map
1898 *_TileNoiseMap
=*src
._TileNoiseMap
;
1905 delete _TileNoiseMap
;
1911 // ***************************************************************************
1912 void CTileNoise::serial (NLMISC::IStream
& f
)
1915 f
.serialVersion (0);
1917 // Serial the file name
1918 f
.serial (_FileName
);
1920 // ***************************************************************************
1921 void CTileNoise::setEmpty ()
1925 _FileName
="EmptyDisplacementMap";
1926 _TileNoiseMap
=new CTileNoiseMap();
1927 memset (_TileNoiseMap
->Pixels
, 0, NL3D_TILE_NOISE_MAP_SIZE
*NL3D_TILE_NOISE_MAP_SIZE
);
1929 // ***************************************************************************
1930 void CTileNoise::reset()
1935 delete _TileNoiseMap
;
1942 // ***************************************************************************