|
|
|
@ -22,6 +22,8 @@
|
|
|
|
|
|
|
|
|
|
#include <nel/misc/debug.h>
|
|
|
|
|
|
|
|
|
|
#include <nel/3d/tile_bank.h>
|
|
|
|
|
|
|
|
|
|
Node::Node() : m_parentItem(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
@ -264,18 +266,230 @@ void TileTypeNode::reindex()
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
NL3D::CTile::TBitmap channelToTBitmap( TileModel::TTileChannel channel )
|
|
|
|
|
{
|
|
|
|
|
NL3D::CTile::TBitmap bm;
|
|
|
|
|
|
|
|
|
|
switch( channel )
|
|
|
|
|
{
|
|
|
|
|
case TileModel::TileDiffuse: bm = NL3D::CTile::diffuse; break;
|
|
|
|
|
case TileModel::TileAdditive: bm = NL3D::CTile::additive; break;
|
|
|
|
|
case TileModel::TileAlpha: bm = NL3D::CTile::alpha; break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class TileItemNodePvt
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
TileItemNodePvt()
|
|
|
|
|
{
|
|
|
|
|
for( int i = 0; i < TileModel::TileChannelCount; i++ )
|
|
|
|
|
m_borderFirst[ i ] = false;
|
|
|
|
|
|
|
|
|
|
m_id = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool pixmapToCBGRA( QPixmap &pixmap, std::vector< NLMISC::CBGRA >& pixels )
|
|
|
|
|
{
|
|
|
|
|
QImage img = pixmap.toImage();
|
|
|
|
|
if( img.format() != QImage::Format_ARGB32 )
|
|
|
|
|
img = img.convertToFormat( QImage::Format_ARGB32 );
|
|
|
|
|
|
|
|
|
|
if( img.format() != QImage::Format_ARGB32 )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
int c = img.width() * img.height();
|
|
|
|
|
|
|
|
|
|
const unsigned char *data = img.bits();
|
|
|
|
|
const unsigned int *idata = reinterpret_cast< const unsigned int* >( data );
|
|
|
|
|
|
|
|
|
|
NLMISC::CBGRA bgra;
|
|
|
|
|
pixels.clear();
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
while( i < c )
|
|
|
|
|
{
|
|
|
|
|
bgra.A = ( idata[ i ] & 0xFF000000 ) >> 24;
|
|
|
|
|
bgra.R = ( idata[ i ] & 0x00FF0000 ) >> 16;
|
|
|
|
|
bgra.G = ( idata[ i ] & 0x0000FF00 ) >> 8;
|
|
|
|
|
bgra.B = ( idata[ i ] & 0x000000FF );
|
|
|
|
|
pixels.push_back( bgra );
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int getWidthForType( TileModel::TNodeTileType type, TileModel::TTileChannel channel )
|
|
|
|
|
{
|
|
|
|
|
int width = -1;
|
|
|
|
|
|
|
|
|
|
switch( type )
|
|
|
|
|
{
|
|
|
|
|
case TileModel::Tile128: width = 128; break;
|
|
|
|
|
case TileModel::Tile256: width = 256; break;
|
|
|
|
|
case TileModel::TileTransition:
|
|
|
|
|
{
|
|
|
|
|
if( channel != TileModel::TileAlpha )
|
|
|
|
|
width = 128;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case TileModel::TileDisplacement: width = 32; break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NL3D::CTileSet::TError checkTile( TileModel::TTileChannel channel )
|
|
|
|
|
{
|
|
|
|
|
if( m_type == TileModel::TileDisplacement )
|
|
|
|
|
return NL3D::CTileSet::ok;
|
|
|
|
|
|
|
|
|
|
if( channel == TileModel::TileAdditive )
|
|
|
|
|
return NL3D::CTileSet::ok;
|
|
|
|
|
|
|
|
|
|
int pixel;
|
|
|
|
|
int component;
|
|
|
|
|
int index;
|
|
|
|
|
|
|
|
|
|
NL3D::CTileSet set;
|
|
|
|
|
NL3D::CTile::TBitmap bm = channelToTBitmap( channel );
|
|
|
|
|
|
|
|
|
|
NL3D::CTileSet::TError error = NL3D::CTileSet::ok;
|
|
|
|
|
|
|
|
|
|
switch( m_type )
|
|
|
|
|
{
|
|
|
|
|
case TileModel::Tile128:
|
|
|
|
|
error = set.checkTile128( bm, m_border[ channel ], pixel, component );
|
|
|
|
|
break;
|
|
|
|
|
case TileModel::Tile256:
|
|
|
|
|
error = set.checkTile256( bm, m_border[ channel ], pixel, component );
|
|
|
|
|
break;
|
|
|
|
|
case TileModel::TileTransition:
|
|
|
|
|
if( channel != TileModel::TileAlpha )
|
|
|
|
|
error = set.checkTile128( bm, m_border[ channel ], pixel, component );
|
|
|
|
|
else
|
|
|
|
|
error = set.checkTileTransition( NL3D::CTileSet::TTransition( m_id ), bm, m_border[ channel ], index, pixel, component );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( error == NL3D::CTileSet::ok )
|
|
|
|
|
return NL3D::CTileSet::ok;
|
|
|
|
|
if( error == NL3D::CTileSet::addFirstA128128 )
|
|
|
|
|
return NL3D::CTileSet::addFirstA128128;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
enum TError { ok=0, topInterfaceProblem, bottomInterfaceProblem, leftInterfaceProblem,
|
|
|
|
|
rightInterfaceProblem, addFirstA128128, topBottomNotTheSame, rightLeftNotTheSame,
|
|
|
|
|
sizeInvalide, errorCount };
|
|
|
|
|
*/
|
|
|
|
|
static const char* comp[]={"Red", "Green", "Blue", "Alpha", ""};
|
|
|
|
|
|
|
|
|
|
if( error != NL3D::CTileSet::ok )
|
|
|
|
|
{
|
|
|
|
|
m_lastError = "ERROR: ";
|
|
|
|
|
m_lastError += NL3D::CTileSet::getErrorMessage( error );
|
|
|
|
|
m_lastError += "\n";
|
|
|
|
|
|
|
|
|
|
switch( m_type )
|
|
|
|
|
{
|
|
|
|
|
case TileModel::Tile128:
|
|
|
|
|
case TileModel::Tile256:
|
|
|
|
|
m_lastError += QString( "pixel: %1 component: %2" ).arg( pixel ).arg( comp[ component ] );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case TileModel::TileTransition:
|
|
|
|
|
if( channel != TileModel::TileAlpha )
|
|
|
|
|
{
|
|
|
|
|
m_lastError += QString( "pixel: %1 component: %2" ).arg( pixel ).arg( comp[ component ] );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((error==NL3D::CTileSet::topInterfaceProblem)||(error==NL3D::CTileSet::bottomInterfaceProblem)||
|
|
|
|
|
(error==NL3D::CTileSet::leftInterfaceProblem)||(error==NL3D::CTileSet::rightInterfaceProblem)||
|
|
|
|
|
(error==NL3D::CTileSet::topBottomNotTheSame)||(error==NL3D::CTileSet::rightLeftNotTheSame)
|
|
|
|
|
||(error==NL3D::CTileSet::topInterfaceProblem))
|
|
|
|
|
{
|
|
|
|
|
if( index != -1 )
|
|
|
|
|
{
|
|
|
|
|
m_lastError += QString( "tile: %1 pixel: %2 component: %3" ).arg( index ).arg( pixel ).arg( comp[ component ] );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_lastError += QString( "incompatible with a 128 tile, pixel: %1 component: %2" ).arg( pixel ).arg( comp[ component ] );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool checkPixmap( TileModel::TTileChannel channel, QPixmap &pixmap )
|
|
|
|
|
{
|
|
|
|
|
int w = pixmap.width();
|
|
|
|
|
int h = pixmap.height();
|
|
|
|
|
|
|
|
|
|
if( w != h )
|
|
|
|
|
{
|
|
|
|
|
m_lastError = QObject::tr( "Not a square texture." );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int width = getWidthForType( m_type, channel );
|
|
|
|
|
|
|
|
|
|
if( width != -1 )
|
|
|
|
|
{
|
|
|
|
|
if( width != w )
|
|
|
|
|
{
|
|
|
|
|
m_lastError = QObject::tr( "Not the proper size." );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector< NLMISC::CBGRA > pixels;
|
|
|
|
|
|
|
|
|
|
pixmapToCBGRA( pixmap, pixels );
|
|
|
|
|
|
|
|
|
|
m_border[ channel ].set( w, h, pixels );
|
|
|
|
|
|
|
|
|
|
NL3D::CTileSet::TError error = checkTile( channel );
|
|
|
|
|
if( error == NL3D::CTileSet::addFirstA128128 )
|
|
|
|
|
{
|
|
|
|
|
m_borderFirst[ channel ] = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( error != NL3D::CTileSet::ok )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool loadImage( TileModel::TTileChannel channel, const QString &fn )
|
|
|
|
|
bool loadImage( TileModel::TTileChannel channel, const QString &fn, bool empty = false )
|
|
|
|
|
{
|
|
|
|
|
QPixmap temp;
|
|
|
|
|
bool b = temp.load( fn );
|
|
|
|
|
|
|
|
|
|
if( !b )
|
|
|
|
|
{
|
|
|
|
|
m_lastError = QObject::tr( "Cannot open file %1" ).arg( fn );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !empty )
|
|
|
|
|
{
|
|
|
|
|
if( !checkPixmap( channel, temp ) )
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pixmaps[ channel ] = temp;
|
|
|
|
|
|
|
|
|
@ -291,19 +505,34 @@ public:
|
|
|
|
|
return pixmaps[ channel ];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setType( TileModel::TNodeTileType type ){ m_type = type; }
|
|
|
|
|
void setId( int id ){ m_id = id; }
|
|
|
|
|
int id() const{ return m_id; }
|
|
|
|
|
|
|
|
|
|
QString getLastError() const{ return m_lastError; }
|
|
|
|
|
bool borderFirst( TileModel::TTileChannel channel ) const{ return m_borderFirst[ channel ]; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
QPixmap pixmaps[ TileModel::TileChannelCount ];
|
|
|
|
|
|
|
|
|
|
TileModel::TNodeTileType m_type;
|
|
|
|
|
NL3D::CTileBorder m_border[ TileModel::TileChannelCount ];
|
|
|
|
|
int m_id;
|
|
|
|
|
QString m_lastError;
|
|
|
|
|
bool m_borderFirst[ TileModel::TileChannelCount ];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TileModel::TTileChannel TileItemNode::s_displayChannel = TileModel::TileDiffuse;
|
|
|
|
|
|
|
|
|
|
TileItemNode::TileItemNode(int tileId, TileModel::TTileChannel channel, QString filename, Node *parent) : m_tileId(tileId)
|
|
|
|
|
TileItemNode::TileItemNode( TileModel::TNodeTileType type, int tileId, TileModel::TTileChannel channel, QString filename, Node *parent)
|
|
|
|
|
{
|
|
|
|
|
m_parentItem = parent;
|
|
|
|
|
//nlinfo("dispalying tile %d - %s", m_tileId, m_tileFilename[TileModel::TileDiffuse].toAscii().data());
|
|
|
|
|
|
|
|
|
|
pvt = new TileItemNodePvt();
|
|
|
|
|
pvt->setType( type );
|
|
|
|
|
pvt->setId( tileId );
|
|
|
|
|
|
|
|
|
|
m_hasError = false;
|
|
|
|
|
|
|
|
|
|
setTileFilename( channel, filename );
|
|
|
|
|
}
|
|
|
|
@ -319,11 +548,16 @@ TileItemNode::~TileItemNode()
|
|
|
|
|
bool TileItemNode::setTileFilename(TileModel::TTileChannel channel, QString filename)
|
|
|
|
|
{
|
|
|
|
|
QString fn = filename;
|
|
|
|
|
bool empty = false;
|
|
|
|
|
|
|
|
|
|
if( filename.isEmpty() || ( filename == "empty" ) )
|
|
|
|
|
{
|
|
|
|
|
fn = ":/placeHolder/images/empty_image.png";
|
|
|
|
|
empty = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool b = pvt->loadImage( channel, fn );
|
|
|
|
|
bool b = pvt->loadImage( channel, fn, empty );
|
|
|
|
|
m_hasError = !b;
|
|
|
|
|
if( !b )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
@ -341,6 +575,26 @@ QString TileItemNode::getTileFilename(TileModel::TTileChannel channel)
|
|
|
|
|
return itr.value();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TileItemNode::setId( int id )
|
|
|
|
|
{
|
|
|
|
|
pvt->setId( id );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TileItemNode::id() const
|
|
|
|
|
{
|
|
|
|
|
return pvt->id();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString TileItemNode::getLastError() const
|
|
|
|
|
{
|
|
|
|
|
return pvt->getLastError();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TileItemNode::borderFirst() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant TileItemNode::data(int column, int role) const
|
|
|
|
|
{
|
|
|
|
|
QString tileFilename = m_tileFilename[ TileItemNode::s_displayChannel ];
|
|
|
|
@ -375,11 +629,11 @@ QVariant TileItemNode::data(int column, int role) const
|
|
|
|
|
}
|
|
|
|
|
else if(role == TileModel::TileIndexRole)
|
|
|
|
|
{
|
|
|
|
|
return QVariant("("+QString::number(m_tileId)+")");
|
|
|
|
|
return QVariant("("+QString::number(pvt->id())+")");
|
|
|
|
|
}
|
|
|
|
|
else if(role == TileModel::TileFilenameIndexRole)
|
|
|
|
|
{
|
|
|
|
|
return QVariant(tileFilename + " ("+QString::number(m_tileId)+")");
|
|
|
|
|
return QVariant(tileFilename + " ("+QString::number(pvt->id())+")");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
|