diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 5fd8c22ef..0e2dcdd39 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,6 +1,17 @@ == CHANGELOG == -This is version 1.1.1 of NifSkope. +This is version 1.1.2 of NifSkope. + +changes since 1.1.1: +* When combining material properties, keep original material names as much as possible (reported by koniption). +* Fix display of transformed havok shapes (reported by koniption). +* Skyrim material updates (contributed by ttl269). +* Skyrim body part updates. +* Document sane defaults for Skyrim bhkRigidBody "Unknown 7 Shorts" (reported by ttl296). +* Rename: binormals are now more accurately called bitangents. +* Collada export improvements (contributed by mharj). +* Support node culling by regular expression in collada/obj export (contributed by mharj). +* Fix block order of bhkCompressedMeshShapeData (reported by ttl269). changes since 1.1.0: * Fix unsigned int enum issue. @@ -25,7 +36,7 @@ changes since 1.1.0-RC7: * Fix: fixed #3525690 NifSkope Crash: MoppBvTree Triangles * Fix: blocked invalid memory access when "triangles" is empty * Fix: stopped triangle reordering on .obj import into "FO:NV" "NiTriShape" -* nif.xml: bhkCompressedMeshShape: merged "skyfox", "ttl296" and probably other peoples work +* nif.xml: bhkCompressedMeshShape: merged "skyfox", "ttl269" and probably other peoples work changes since 1.1.0-RC6: * Added initial support for "BSLODTriShape" - its being rendered diff --git a/NifSkope.pro b/NifSkope.pro index 56e130719..e98e75386 100644 --- a/NifSkope.pro +++ b/NifSkope.pro @@ -4,7 +4,7 @@ TARGET = NifSkope QT += xml opengl network -CONFIG += qt debug_and_release thread warn_on +CONFIG += qt debug_and_release debug_and_release_target thread warn_on CONFIG += fsengine @@ -22,8 +22,6 @@ macx{ # uncomment this if you want the text stats gl option #DEFINES += USE_GL_QPAINTER -# On Windows this builds Release in release/ and Debug in debug/ -# On Linux you may need CONFIG += debug_and_release debug_and_release_target DESTDIR = . # NIFSKOPE_VERSION macro diff --git a/VERSION b/VERSION index 8cfbc905b..45a1b3f44 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.1 \ No newline at end of file +1.1.2 diff --git a/docsys b/docsys index 6d523e04a..52bbd8906 160000 --- a/docsys +++ b/docsys @@ -1 +1 @@ -Subproject commit 6d523e04afa11c1872fed651f0b128f8c4b97c23 +Subproject commit 52bbd89064fd984e6a1cacf33afcf2c04339f976 diff --git a/gl/glmesh.cpp b/gl/glmesh.cpp index 183d6d124..7ed863b6f 100644 --- a/gl/glmesh.cpp +++ b/gl/glmesh.cpp @@ -218,7 +218,7 @@ void Mesh::clear() colors.clear(); coords.clear(); tangents.clear(); - binormals.clear(); + bitangents.clear(); triangles.clear(); tristrips.clear(); weights.clear(); @@ -229,7 +229,7 @@ void Mesh::clear() transNorms.clear(); transColors.clear(); transTangents.clear(); - transBinormals.clear(); + transBitangents.clear(); double_sided = false; } @@ -580,7 +580,7 @@ void Mesh::transform() for (int i = 0; i < colors.count(); i++) colors[i].setRGBA(colors[i].red(), colors[i].green(), colors[i].blue(), 1); tangents = nif->getArray( iData, "Tangents" ); - binormals = nif->getArray( iData, "Binormals" ); + bitangents = nif->getArray( iData, "Bitangents" ); if ( norms.count() < verts.count() ) norms.clear(); if ( colors.count() < verts.count() ) colors.clear(); @@ -658,12 +658,12 @@ void Mesh::transform() if ( data.count() == verts.count() * 4 * 3 * 2 ) { tangents.resize( verts.count() ); - binormals.resize( verts.count() ); + bitangents.resize( verts.count() ); Vector3 * t = (Vector3 *) data.data(); for ( int c = 0; c < verts.count(); c++ ) tangents[c] = *t++; for ( int c = 0; c < verts.count(); c++ ) - binormals[c] = *t++; + bitangents[c] = *t++; } } } @@ -731,8 +731,8 @@ void Mesh::transformShapes() transNorms.fill( Vector3() ); transTangents.resize( tangents.count() ); transTangents.fill( Vector3() ); - transBinormals.resize( binormals.count() ); - transBinormals.fill( Vector3() ); + transBitangents.resize( bitangents.count() ); + transBitangents.fill( Vector3() ); Node * root = findParent( skelRoot ); @@ -768,8 +768,8 @@ void Mesh::transformShapes() transNorms[vindex] += trans.rotation * norms[ vindex ] * weight.second; if ( tangents.count() > vindex ) transTangents[vindex] += trans.rotation * tangents[ vindex ] * weight.second; - if ( binormals.count() > vindex ) - transBinormals[vindex] += trans.rotation * binormals[ vindex ] * weight.second; + if ( bitangents.count() > vindex ) + transBitangents[vindex] += trans.rotation * bitangents[ vindex ] * weight.second; } } } @@ -794,8 +794,8 @@ void Mesh::transformShapes() transNorms[ vw.vertex ] += natrix * norms[ vw.vertex ] * vw.weight; if ( transTangents.count() > vw.vertex ) transTangents[ vw.vertex ] += natrix * tangents[ vw.vertex ] * vw.weight; - if ( transBinormals.count() > vw.vertex ) - transBinormals[ vw.vertex ] += natrix * binormals[ vw.vertex ] * vw.weight; + if ( transBitangents.count() > vw.vertex ) + transBitangents[ vw.vertex ] += natrix * bitangents[ vw.vertex ] * vw.weight; } } } @@ -804,8 +804,8 @@ void Mesh::transformShapes() transNorms[n].normalize(); for ( int t = 0; t < transTangents.count(); t++ ) transTangents[t].normalize(); - for ( int t = 0; t < transBinormals.count(); t++ ) - transBinormals[t].normalize(); + for ( int t = 0; t < transBitangents.count(); t++ ) + transBitangents[t].normalize(); bndSphere = BoundSphere( transVerts ); bndSphere.applyInv( viewTrans() ); @@ -816,7 +816,7 @@ void Mesh::transformShapes() transVerts = verts; transNorms = norms; transTangents = tangents; - transBinormals = binormals; + transBitangents = bitangents; } /* @@ -1028,7 +1028,7 @@ void Mesh::drawSelection() const } if ( n == "Vertices" || n == "Normals" || n == "Vertex Colors" - || n == "UV Sets" || n == "Tangents" || n == "Binormals" ) + || n == "UV Sets" || n == "Tangents" || n == "Bitangents" ) { glDepthFunc( GL_LEQUAL ); glNormalColor(); @@ -1104,12 +1104,12 @@ void Mesh::drawSelection() const if ( n == "TSpace" ) { - for ( int j = 0; j < transVerts.count() && j < transTangents.count() && j < transBinormals.count(); j++ ) + for ( int j = 0; j < transVerts.count() && j < transTangents.count() && j < transBitangents.count(); j++ ) { glVertex( transVerts.value( j ) ); glVertex( transVerts.value( j ) + transTangents.value( j ) * normalScale ); glVertex( transVerts.value( j ) ); - glVertex( transVerts.value( j ) + transBinormals.value( j ) * normalScale ); + glVertex( transVerts.value( j ) + transBitangents.value( j ) * normalScale ); } } @@ -1156,7 +1156,7 @@ void Mesh::drawSelection() const glEnd(); } } - if ( n == "Binormals" ) + if ( n == "Bitangents" ) { glDepthFunc( GL_LEQUAL ); glNormalColor(); @@ -1166,12 +1166,12 @@ void Mesh::drawSelection() const if ( normalScale < 0.1f ) normalScale = 0.1f; glBegin( GL_LINES ); - for ( int j = 0; j < transVerts.count() && j < transBinormals.count(); j++ ) + for ( int j = 0; j < transVerts.count() && j < transBitangents.count(); j++ ) { glVertex( transVerts.value( j ) ); - glVertex( transVerts.value( j ) + transBinormals.value( j ) * normalScale * 2 ); + glVertex( transVerts.value( j ) + transBitangents.value( j ) * normalScale * 2 ); glVertex( transVerts.value( j ) ); - glVertex( transVerts.value( j ) - transBinormals.value( j ) * normalScale / 2 ); + glVertex( transVerts.value( j ) - transBitangents.value( j ) * normalScale / 2 ); } glEnd(); @@ -1181,9 +1181,9 @@ void Mesh::drawSelection() const glHighlightColor(); glBegin( GL_LINES ); glVertex( transVerts.value( i ) ); - glVertex( transVerts.value( i ) + transBinormals.value( i ) * normalScale * 2); + glVertex( transVerts.value( i ) + transBitangents.value( i ) * normalScale * 2); glVertex( transVerts.value( i ) ); - glVertex( transVerts.value( i ) - transBinormals.value( i ) * normalScale / 2 ); + glVertex( transVerts.value( i ) - transBitangents.value( i ) * normalScale / 2 ); glEnd(); } } diff --git a/gl/glmesh.h b/gl/glmesh.h index e19567c05..49a5fd8b5 100644 --- a/gl/glmesh.h +++ b/gl/glmesh.h @@ -86,8 +86,8 @@ class Mesh : public Node QVector colors; //! Tangents QVector tangents; - //! Binormals - QVector binormals; + //! Bitangents + QVector bitangents; //! UV coordinate sets QList< QVector > coords; @@ -100,8 +100,8 @@ class Mesh : public Node QVector transColors; //! Transformed tangents QVector transTangents; - //! Transformed binormals - QVector transBinormals; + //! Transformed bitangents + QVector transBitangents; int skelRoot; Transform skelTrans; diff --git a/gl/glnode.cpp b/gl/glnode.cpp index a98dcd5f0..049022a96 100644 --- a/gl/glnode.cpp +++ b/gl/glnode.cpp @@ -955,7 +955,12 @@ void drawHvkShape( const NifModel * nif, const QModelIndex & iShape, QStackget( iShape, "Transform" ); - glMultMatrix( tm ); + // TODO find a better way to apply tm + Transform t; + Vector3 s; + tm.decompose(t.translation, t.rotation, s); + t.scale = (s[0] + s[1] + s[2]) / 3.0; // assume uniform + glMultMatrix( t ); drawHvkShape( nif, nif->getBlock( nif->getLink( iShape, "Shape" ) ), stack, scene, origin_color3fv ); glPopMatrix(); } diff --git a/gl/renderer.cpp b/gl/renderer.cpp index b07d7116d..28915fbea 100644 --- a/gl/renderer.cpp +++ b/gl/renderer.cpp @@ -327,7 +327,7 @@ bool Renderer::Program::load( const QString & filepath, Renderer * renderer ) QString id = list.value( 1 ).toLower(); if ( ! ok || id.isEmpty() ) throw QString( "malformed texcoord tag" ); - if ( id != "tangents" && id != "binormals" && TexturingProperty::getId( id ) < 0 ) + if ( id != "tangents" && id != "bitangents" && TexturingProperty::getId( id ) < 0 ) throw QString( "texcoord tag referres to unknown texture id '%1'" ).arg( id ); if ( texcoords.contains( unit ) ) throw QString( "texture unit %1 is assigned twiced" ).arg( unit ); @@ -579,12 +579,12 @@ bool Renderer::setupProgram( Program * prog, Mesh * mesh, const PropertyList & p glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glTexCoordPointer( 3, GL_FLOAT, 0, mesh->transTangents.data() ); } - else if ( itx.value() == "binormals" ) + else if ( itx.value() == "bitangents" ) { - if ( ! mesh->transBinormals.count() ) + if ( ! mesh->transBitangents.count() ) return false; glEnableClientState( GL_TEXTURE_COORD_ARRAY ); - glTexCoordPointer( 3, GL_FLOAT, 0, mesh->transBinormals.data() ); + glTexCoordPointer( 3, GL_FLOAT, 0, mesh->transBitangents.data() ); } else if (texprop != NULL) { diff --git a/importex/col.cpp b/importex/col.cpp index a00f5ce8e..dd1f717b8 100644 --- a/importex/col.cpp +++ b/importex/col.cpp @@ -48,6 +48,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../config.h" +#include "../options.h" + #define tr(x) QApplication::tr(x) /** @@ -79,7 +81,8 @@ QDomElement libraryImages; QDomElement libraryMaterials; QDomElement libraryEffects; QDomElement libraryGeometries; - +bool culling; +QRegExp cullRegExp; QVector textureIds; QVector textureNames; @@ -104,6 +107,42 @@ QDomElement dateElement(QString type,QDateTime time) { } +void addLibraryImages(int idx,QString type,QString file) { + file.replace("\\","/"); // nix way + QDomElement image = doc.createElement("image"); + image.setAttribute("id",QString("nifid_%1_%2_image").arg(idx).arg(type)); + image.setAttribute("name",QFileInfo(file).baseName()); + QDomElement init_from = doc.createElement("init_from"); + init_from.appendChild(doc.createTextNode(file)); + image.appendChild(init_from); + libraryImages.appendChild(image); +} + +void addSufaceSample(QDomElement profile,int idx,QString type) { + QString surfaceSid = QString("nifid_%1_%2-surface").arg(idx).arg(type); + QString samplerSid = QString("nifid_%1_%2-sampler").arg(idx).arg(type); + QString imageId = QString("nifid_%1_%2_image").arg(idx).arg(type); + // surface + QDomElement newparam = doc.createElement("newparam"); + newparam.setAttribute("sid",surfaceSid); + QDomElement surface = doc.createElement("surface"); + surface.setAttribute("type","2D"); + newparam.appendChild(surface); + QDomElement init_from = doc.createElement("init_from"); + init_from.appendChild(doc.createTextNode( imageId ) ); + surface.appendChild(init_from); + profile.appendChild(newparam); + // sampler + newparam = doc.createElement("newparam"); + newparam.setAttribute("sid",samplerSid); + QDomElement sampler = doc.createElement("sampler2D"); + newparam.appendChild(sampler); + QDomElement source = doc.createElement("source"); + source.appendChild(doc.createTextNode( surfaceSid ) ); + sampler.appendChild(source); + profile.appendChild(newparam); +} + /** * create matrix element * @param trans Translation @@ -515,12 +554,14 @@ QDomElement textureElement(const NifModel * nif,QDomElement effect,QModelIndex c * FIXME: handle multiple UV maps in .. find example! */ void attachNiShape (const NifModel * nif,QDomElement parentNode,int idx) { + bool haveVertex = false; bool haveNormal = false; bool haveColors = false; bool haveMaterial = false; int haveUV = 0; QModelIndex iBlock = nif->getBlock( idx ); + QDomElement extra; QDomElement textureBaseTexture; QDomElement textureDarkTexture; QDomElement textureGlowTexture; @@ -529,6 +570,11 @@ void attachNiShape (const NifModel * nif,QDomElement parentNode,int idx) { QDomElement effect; // profile QDomElement profile; + + // export culling + if ( culling && ! cullRegExp.isEmpty() && nif->get( iBlock, "Name" ).contains(cullRegExp) ) + return; + foreach ( qint32 link, nif->getChildLinks(idx) ) { QModelIndex iProp = nif->getBlock( link ); if ( nif->inherits( iProp, "NiTexturingProperty" ) ) { @@ -545,6 +591,8 @@ void attachNiShape (const NifModel * nif,QDomElement parentNode,int idx) { // glow texture = map emission textureGlowTexture = textureElement(nif,profile,nif->getIndex( iProp, "Glow Texture" ),idx); + // TODO: Shader Textures array and mapping (for DAoC check NiIntegerExtraData for order) + } else if ( nif->inherits( iProp, "NiTextureProperty" ) ) { if ( ! effect.isElement() ) { effect = doc.createElement("effect"); @@ -569,15 +617,22 @@ void attachNiShape (const NifModel * nif,QDomElement parentNode,int idx) { QVector textures = nif->getArray( iTextures, "Textures" ); if ( ! textures.at(0).isEmpty() ) textureBaseTexture = textureArrayElement(textures.at(0),profile,subIdx,"base"); - // TODO: add normal map - /* - - - - - - - */ + /* add normal map with FCOLLADA profile + * could also be gloss as per nif.xml? */ + if ( ! textures.at(1).isEmpty() ) { + addLibraryImages(subIdx,"normal",textures.at(1)); + addSufaceSample(profile,subIdx,"normal"); + extra = doc.createElement("extra"); + QDomElement extraTechnique = doc.createElement("technique"); + extraTechnique.setAttribute("profile","FCOLLADA"); + extra.appendChild(extraTechnique); + QDomElement extraTechniqueBump = doc.createElement("bump"); + extraTechnique.appendChild(extraTechniqueBump); + QDomElement extraTechniqueBumpTexture = doc.createElement("texture"); + extraTechniqueBumpTexture.setAttribute("texture",QString("nifid_%1_normal-sampler").arg(subIdx)); + extraTechniqueBumpTexture.setAttribute("texcoord","UVSET0"); // TODO: something better? + extraTechniqueBump.appendChild(extraTechniqueBumpTexture); + } } // Material parameters haveMaterial = true; @@ -641,6 +696,9 @@ void attachNiShape (const NifModel * nif,QDomElement parentNode,int idx) { // transparency phong.appendChild( colorElement("transparent", Color3(1.0f,1.0f,1.0f))); phong.appendChild( effectElement("transparency" , nif->get( iProp, "Alpha" ) ) ); + + if ( extra.isElement() ) + profile.appendChild(extra); } else if ( nif->inherits( iProp, "NiTriBasedGeomData" ) ) { QDomElement geometry = doc.createElement("geometry"); geometry.setAttribute("id",QString("nifid_%1-lib").arg(idx)); @@ -800,7 +858,12 @@ void attachNiShape (const NifModel * nif,QDomElement parentNode,int idx) { * Node "tree" looping */ void attachNiNode (const NifModel * nif,QDomElement parentNode,int idx) { + QModelIndex iBlock = nif->getBlock( idx ); + // export culling + if ( culling && ! cullRegExp.isEmpty() && nif->get( iBlock, "Name" ).contains(cullRegExp) ) + return; + QDomElement node = doc.createElement("node"); QString nodeName = nif->get( iBlock, "Name" ).replace(" ","_"); QString nodeID = QString("nifid_%1_node").arg(idx); @@ -827,6 +890,9 @@ void attachNiNode (const NifModel * nif,QDomElement parentNode,int idx) { } void exportCol( const NifModel * nif,QFileInfo fileInfo ) { + culling = Options::get()->exportCullEnabled(); + cullRegExp = Options::get()->cullExpression(); + QList roots = nif->getRootLinks(); QString question; QSettings settings; diff --git a/importex/obj.cpp b/importex/obj.cpp index 16f23af35..28ccf8771 100644 --- a/importex/obj.cpp +++ b/importex/obj.cpp @@ -46,8 +46,15 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../gl/gltex.h" +#include "../options.h" + #define tr(x) QApplication::tr(x) +// "globals" +bool objCulling; +QRegExp objCullRegExp; + + /* * .OBJ EXPORT */ @@ -134,6 +141,10 @@ static void writeShape( const NifModel * nif, const QModelIndex & iShape, QTextS Color3 mata, matd, mats; float matt = 1.0, matg = 33.0; + // export culling + if ( objCulling && ! objCullRegExp.isEmpty() && nif->get( iShape, "Name" ).contains(objCullRegExp) ) + return; + foreach ( qint32 link, nif->getChildLinks( nif->getBlockNumber( iShape ) ) ) { QModelIndex iProp = nif->getBlock( link ); @@ -214,6 +225,9 @@ static void writeShape( const NifModel * nif, const QModelIndex & iShape, QTextS static void writeParent( const NifModel * nif, const QModelIndex & iNode, QTextStream & obj, QTextStream & mtl, int ofs[], Transform t ) { + // export culling + if ( objCulling && ! objCullRegExp.isEmpty() && nif->get( iNode, "Name" ).contains(objCullRegExp) ) + return; t = t * Transform( nif, iNode ); foreach ( int l, nif->getChildLinks( nif->getBlockNumber( iNode ) ) ) { @@ -292,6 +306,9 @@ static void writeParent( const NifModel * nif, const QModelIndex & iNode, QTextS void exportObj( const NifModel * nif, const QModelIndex & index ) { + objCulling = Options::get()->exportCullEnabled(); + objCullRegExp = Options::get()->cullExpression(); + //--Determine how the file will export, and be sure the user wants to continue--// QList roots; QModelIndex iBlock = nif->getBlock( index ); diff --git a/lang/NifSkope_de.ts b/lang/NifSkope_de.ts index 0a41553cf..d2d3ddb97 100644 --- a/lang/NifSkope_de.ts +++ b/lang/NifSkope_de.ts @@ -1044,7 +1044,7 @@ - need vertices, normals, texture coordinates and faces to calculate tangents and binormals + need vertices, normals, texture coordinates and faces to calculate tangents and bitangents diff --git a/lang/NifSkope_fr.ts b/lang/NifSkope_fr.ts index d3915296a..6c7af40a0 100644 --- a/lang/NifSkope_fr.ts +++ b/lang/NifSkope_fr.ts @@ -884,7 +884,7 @@ - need vertices, normals, texture coordinates and faces to calculate tangents and binormals + need vertices, normals, texture coordinates and faces to calculate tangents and bitangents Pour calculer les tangentes et les binormales, il faut des sommets, des normales, des faces et des coordonnées de texture diff --git a/linux-install/nifskope.spec.in b/linux-install/nifskope.spec.in index 32b9dedb7..622a9e8cd 100644 --- a/linux-install/nifskope.spec.in +++ b/linux-install/nifskope.spec.in @@ -231,7 +231,7 @@ rm -rf $RPM_BUILD_ROOT - fixed corruption of BSShaderNoLightingProperty file names when using texture chooser - fixed rendering settings which sometimes broke texture rendering when shader not used - added settings page for selecting displayed user interface language -- fixed Binormals and Tangents swapped in Fallout 3 files [ niftools-Bugs-2466995 ] +- fixed Bitangents and Tangents swapped in Fallout 3 files [ niftools-Bugs-2466995 ] - added Block | Convert Spell for cleanly changing node type - set default stencil property flags to 19840 for Fallout 3 (suggested by Saiden) * Mon Dec 22 2008 amorilia - 1.0.17-1 diff --git a/nifskope.cpp b/nifskope.cpp index 4152ff325..9c948b24d 100644 --- a/nifskope.cpp +++ b/nifskope.cpp @@ -840,8 +840,8 @@ void NifSkope::load() lineLoad->setText( niffile.filePath() ); lineSave->setText( niffile.filePath() ); } - - setWindowTitle( "NifSkope - " + niffile.fileName() ); + + setWindowTitle( niffile.fileName() + " - NifSkope"); } ogl->tAnim->setEnabled( true ); @@ -901,7 +901,7 @@ void NifSkope::save() lineSave->setState(FileSelector::stSuccess); } - setWindowTitle( "NifSkope - " + nifname.right( nifname.length() - nifname.lastIndexOf( '/' ) - 1 ) ); + setWindowTitle( nifname.right( nifname.length() - nifname.lastIndexOf( '/' ) - 1 ) + " - NifSkope" ); } setEnabled( true ); diff --git a/options.cpp b/options.cpp index 43dd3ccc2..3996b11ca 100644 --- a/options.cpp +++ b/options.cpp @@ -366,10 +366,11 @@ Options::Options() texPage->addWidget( CullExpr = new QLineEdit( cfg.value( "Cull Expression", "^collidee|^shadowcaster|^\\!LoD_cullme|^footprint" ).toString() ) ); CullExpr->setToolTip( tr("Enter a regular expression. Nodes which names match the expression will be hidden") ); - CullExpr->setEnabled( CullByID->isChecked() ); +// leave RegExp input open as both rendering and collada cull sharing this +// CullExpr->setEnabled( CullByID->isChecked() ); + CullExpr->setEnabled( true ); connect( CullExpr, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( sigChanged() ) ); - connect( CullByID, SIGNAL( toggled( bool ) ), CullExpr, SLOT( setEnabled( bool ) ) ); - +// connect( CullByID, SIGNAL( toggled( bool ) ), CullExpr, SLOT( setEnabled( bool ) ) ); texPage->popLayout(); texPage->popLayout(); @@ -531,6 +532,19 @@ Options::Options() cfg.endGroup(); } + + GroupBox *exportPage; + tab->addTab( exportPage = new GroupBox(Qt::Vertical), tr("Export")); + { + cfg.beginGroup( "Export Settings" ); + exportPage->pushLayout( tr("Export Settings"), Qt::Vertical, 1 ); + exportPage->addWidget( exportCull = new QCheckBox( tr("Use 'Cull Nodes by Name' rendering option to cull nodes on export") ),1,Qt::AlignTop); + exportCull->setChecked( cfg.value("export_culling",false).toBool() ); + connect( exportCull, SIGNAL( toggled( bool ) ), this, SIGNAL( sigChanged() ) ); + exportPage->popLayout(); + cfg.endGroup(); + } + // set render page as default tab->setCurrentWidget( texPage ); @@ -648,6 +662,10 @@ void Options::save() //cfg.setValue( "Maximum String Length", maxStringLength() ); cfg.endGroup(); // Settings + + cfg.beginGroup( "Export Settings" ); + cfg.setValue( "export_culling", exportCullEnabled() ); + cfg.endGroup(); // Export Settings } void Options::textureFolderAutoDetect() @@ -1064,3 +1082,7 @@ int Options::maxStringLength() return get()->StringLength->value(); } */ + +bool Options::exportCullEnabled() { + return get()->exportCull->isChecked(); +} diff --git a/options.h b/options.h index 7de8543e9..eaa6089fc 100644 --- a/options.h +++ b/options.h @@ -156,6 +156,8 @@ class Options : public QObject static QLocale translationLocale(); // Maximum string length (see NifIStream::init for the current usage) //static int maxStringLength(); + //! status of Collada Cull setting + static bool exportCullEnabled(); signals: //! Signal emitted when a value changes @@ -248,6 +250,10 @@ public slots: QCheckBox * overrideMatCheck; ColorWheel * matColors[4]; + + ////////////////////////////////////////////////////////////////////////// + // Export Settings page + QCheckBox * exportCull; ////////////////////////////////////////////////////////////////////////// diff --git a/shaders/ob_normal+glowmap.prog b/shaders/ob_normal+glowmap.prog index cc27f7b41..c805d15c1 100644 --- a/shaders/ob_normal+glowmap.prog +++ b/shaders/ob_normal+glowmap.prog @@ -6,6 +6,6 @@ check NiTriBasedGeom/Has Shader == 0 texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_glowmap.vert ob_normalglowmap.frag diff --git a/shaders/ob_normalmap.prog b/shaders/ob_normalmap.prog index f0f1ebaec..795c3a409 100644 --- a/shaders/ob_normalmap.prog +++ b/shaders/ob_normalmap.prog @@ -22,6 +22,6 @@ checkgroup end texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_material_default.vert ob_normalmap.frag diff --git a/shaders/ob_normalmap_vcol_ad.prog b/shaders/ob_normalmap_vcol_ad.prog index 1383e6d4c..fbee00aef 100644 --- a/shaders/ob_normalmap_vcol_ad.prog +++ b/shaders/ob_normalmap_vcol_ad.prog @@ -16,6 +16,6 @@ checkgroup end texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_vcolors_ad.vert ob_normalmap.frag diff --git a/shaders/ob_normalmap_vcol_e.prog b/shaders/ob_normalmap_vcol_e.prog index 580b3fbb0..74c66bdb3 100644 --- a/shaders/ob_normalmap_vcol_e.prog +++ b/shaders/ob_normalmap_vcol_e.prog @@ -12,6 +12,6 @@ checkgroup end texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_vcolors_e.vert ob_normalmap.frag diff --git a/shaders/ob_parallax+glowmap.prog b/shaders/ob_parallax+glowmap.prog index 670f56553..2622cf0b6 100644 --- a/shaders/ob_parallax+glowmap.prog +++ b/shaders/ob_parallax+glowmap.prog @@ -6,6 +6,6 @@ check NiTriBasedGeom/Has Shader == 0 texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_glowmap.vert ob_parallaxglowmap.frag diff --git a/shaders/ob_parallax.prog b/shaders/ob_parallax.prog index 0e8eac246..ba85a9a64 100644 --- a/shaders/ob_parallax.prog +++ b/shaders/ob_parallax.prog @@ -14,6 +14,6 @@ checkgroup end texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_material_default.vert ob_parallax.frag diff --git a/shaders/ob_parallax_vcol_ad.prog b/shaders/ob_parallax_vcol_ad.prog index 595fb2d03..7863ade8a 100644 --- a/shaders/ob_parallax_vcol_ad.prog +++ b/shaders/ob_parallax_vcol_ad.prog @@ -16,6 +16,6 @@ checkgroup end texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_vcolors_ad.vert ob_parallax.frag diff --git a/shaders/ob_parallax_vcol_e.prog b/shaders/ob_parallax_vcol_e.prog index 16bfd4b1b..ba132839b 100644 --- a/shaders/ob_parallax_vcol_e.prog +++ b/shaders/ob_parallax_vcol_e.prog @@ -12,6 +12,6 @@ checkgroup end texcoords 0 base texcoords 1 tangents -texcoords 2 binormals +texcoords 2 bitangents shaders ob_vcolors_e.vert ob_parallax.frag diff --git a/spells/normals.cpp b/spells/normals.cpp index fbc2daf40..bd429c240 100644 --- a/spells/normals.cpp +++ b/spells/normals.cpp @@ -210,7 +210,7 @@ REGISTER_SPELL( spSmoothNormals ) //! Normalises any single Vector3 or array. /** - * Most used on Normals, Binormals and Tangents. + * Most used on Normals, Bitangents and Tangents. */ class spNormalize : public Spell { diff --git a/spells/optimize.cpp b/spells/optimize.cpp index 7d288034a..effd7fbd0 100644 --- a/spells/optimize.cpp +++ b/spells/optimize.cpp @@ -48,8 +48,10 @@ class spCombiProps : public Spell for ( qint32 b = 0; b < nif->getBlockCount(); b++ ) { QModelIndex iBlock = nif->getBlock( b ); + QString original_material_name; if ( nif->isNiBlock( iBlock, "NiMaterialProperty" ) ) { + original_material_name = nif->get( iBlock, "Name" ); if ( nif->get( iBlock, "Name" ).contains( "Material" ) ) nif->set( iBlock, "Name", "Material" ); else if ( nif->get( iBlock, "Name" ).contains( "Default" ) ) @@ -68,6 +70,11 @@ class spCombiProps : public Spell nif->save( data, iBlock ); props.insert( b, data.buffer() ); } + // restore name + if ( nif->isNiBlock( iBlock, "NiMaterialProperty" ) ) + { + nif->set( iBlock, "Name", original_material_name ); + } } foreach ( qint32 x, props.keys() ) diff --git a/spells/strippify.cpp b/spells/strippify.cpp index 8524bb019..ef8fb880e 100644 --- a/spells/strippify.cpp +++ b/spells/strippify.cpp @@ -76,7 +76,7 @@ class spStrippify : public Spell copyArray( nif, iStripData, iData, "Normals" ); copyValue( nif, iStripData, iData, "TSpace Flag" ); - copyArray( nif, iStripData, iData, "Binormals" ); + copyArray( nif, iStripData, iData, "Bitangents" ); copyArray( nif, iStripData, iData, "Tangents" ); copyValue( nif, iStripData, iData, "Has Vertex Colors" ); @@ -227,7 +227,7 @@ class spTriangulate : public Spell copyArray( nif, iTriData, iStripData, "Normals" ); copyValue( nif, iTriData, iStripData, "TSpace Flag" ); - copyArray( nif, iTriData, iStripData, "Binormals" ); + copyArray( nif, iTriData, iStripData, "Bitangents" ); copyArray( nif, iTriData, iStripData, "Tangents" ); copyValue( nif, iTriData, iStripData, "Has Vertex Colors" ); diff --git a/spells/tangentspace.cpp b/spells/tangentspace.cpp index 90df0bde1..0cb8ebf1b 100644 --- a/spells/tangentspace.cpp +++ b/spells/tangentspace.cpp @@ -22,7 +22,7 @@ bool spTangentSpace::isApplicable( const NifModel * nif, const QModelIndex & ind if ( nif->getUserVersion() == 11 ) return true; - // 10.1.0.0 and greater can have tangents and binormals + // 10.1.0.0 and greater can have tangents and bitangents if ( nif->checkVersion( 0x0A010000, 0 ) ) return true; @@ -62,7 +62,7 @@ QModelIndex spTangentSpace::cast( NifModel * nif, const QModelIndex & iBlock ) if ( verts.isEmpty() || norms.count() != verts.count() || texco.count() != verts.count() || triangles.isEmpty() ) { - qWarning() << Spell::tr( "need vertices, normals, texture coordinates and faces to calculate tangents and binormals" ); + qWarning() << Spell::tr( "need vertices, normals, texture coordinates and faces to calculate tangents and bitangents" ); return iBlock; } @@ -217,7 +217,7 @@ QModelIndex spTangentSpace::cast( NifModel * nif, const QModelIndex & iBlock ) tspaceFlags = 0x10; nif->set( iShape, "TSpace Flag", tspaceFlags); nif->set( iShape, "Num UV Sets", numUVSets); - QModelIndex iBinorms = nif->getIndex( iData, "Binormals" ); + QModelIndex iBinorms = nif->getIndex( iData, "Bitangents" ); QModelIndex iTangents = nif->getIndex( iData, "Tangents" ); nif->updateArray(iBinorms); nif->updateArray(iTangents); @@ -244,7 +244,7 @@ class spAllTangentSpaces : public Spell if ( nif->getUserVersion() == 11 ) return true; - // 10.1.0.0 and greater can have tangents and binormals + // 10.1.0.0 and greater can have tangents and bitangents if ( nif->checkVersion( 0x0A010000, 0 ) ) return true; diff --git a/spells/tangentspace.h b/spells/tangentspace.h index d63748f5b..3af16d456 100644 --- a/spells/tangentspace.h +++ b/spells/tangentspace.h @@ -3,7 +3,7 @@ #include "../spellbook.h" -//! Calculates tangents and binormals +//! Calculates tangents and bitangents /*! * Much fun reading on this can be found at * http://en.wikipedia.org/wiki/Frenet%E2%80%93Serret_formulas