From Guy Volckaert, "Changes to the openflight plugin to support replacing double sided polygons by 2 opposite facing polygons. This is sometimes required to resolved lighting and intersection issues. A new import option was was added to activate this feature called "replaceDoubleSidedPolys".
This commit is contained in:
@@ -26,6 +26,7 @@ Document::Document() :
|
||||
_replaceClampWithClampToEdge(false),
|
||||
_preserveFace(false),
|
||||
_preserveObject(false),
|
||||
_replaceDoubleSidedPolys(false),
|
||||
_defaultDOFAnimationState(false),
|
||||
_useTextureAlphaForTransparancyBinning(true),
|
||||
_useBillboardCenter(false),
|
||||
|
||||
@@ -183,6 +183,8 @@ class Document
|
||||
bool getPreserveFace() const { return _preserveFace; }
|
||||
void setPreserveObject(bool flag) { _preserveObject = flag; }
|
||||
bool getPreserveObject() const { return _preserveObject; }
|
||||
void setReplaceDoubleSidedPolys(bool flag) { _replaceDoubleSidedPolys = flag; }
|
||||
bool getReplaceDoubleSidedPolys() const { return _replaceDoubleSidedPolys; }
|
||||
void setDefaultDOFAnimationState(bool state) { _defaultDOFAnimationState = state; }
|
||||
bool getDefaultDOFAnimationState() const { return _defaultDOFAnimationState; }
|
||||
void setUseTextureAlphaForTransparancyBinning(bool flag) { _useTextureAlphaForTransparancyBinning=flag; }
|
||||
@@ -207,6 +209,7 @@ class Document
|
||||
bool _replaceClampWithClampToEdge;
|
||||
bool _preserveFace;
|
||||
bool _preserveObject;
|
||||
bool _replaceDoubleSidedPolys;
|
||||
bool _defaultDOFAnimationState;
|
||||
bool _useTextureAlphaForTransparancyBinning;
|
||||
bool _useBillboardCenter;
|
||||
|
||||
@@ -29,8 +29,108 @@
|
||||
#include "Document.h"
|
||||
#include "RecordInputStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace flt {
|
||||
|
||||
template<class ARRAY>
|
||||
void reverseWindingOrder( ARRAY* data, GLenum mode, GLint first, GLint last )
|
||||
{
|
||||
switch( mode )
|
||||
{
|
||||
case osg::PrimitiveSet::TRIANGLES:
|
||||
case osg::PrimitiveSet::QUADS:
|
||||
case osg::PrimitiveSet::POLYGON:
|
||||
// reverse all the vertices.
|
||||
std::reverse(data->begin()+first, data->begin()+last);
|
||||
break;
|
||||
case osg::PrimitiveSet::TRIANGLE_STRIP:
|
||||
case osg::PrimitiveSet::QUAD_STRIP:
|
||||
// reverse only the shared edges.
|
||||
for( GLint i = first; i < last-1; i+=2 )
|
||||
{
|
||||
std::swap( (*data)[i], (*data)[i+1] );
|
||||
}
|
||||
break;
|
||||
case osg::PrimitiveSet::TRIANGLE_FAN:
|
||||
// reverse all vertices except the first vertex.
|
||||
std::reverse(data->begin()+first+1, data->begin()+last);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void addDrawableAndReverseWindingOrder( osg::Geode* geode )
|
||||
{
|
||||
// Replace double sided polygons by duplicating the drawables and inverting the normals.
|
||||
std::vector<osg::Geometry*> new_drawables;
|
||||
|
||||
for (size_t i=0; i<geode->getNumDrawables(); ++i)
|
||||
{
|
||||
const osg::Geometry* geometry = dynamic_cast<const osg::Geometry*>(geode->getDrawable(i));
|
||||
if(geometry)
|
||||
{
|
||||
osg::Geometry* geom = new osg::Geometry(*geometry
|
||||
, osg::CopyOp::DEEP_COPY_ARRAYS | osg::CopyOp::DEEP_COPY_PRIMITIVES);
|
||||
new_drawables.push_back(geom);
|
||||
|
||||
for( size_t i = 0; i < geom->getNumPrimitiveSets( ); ++i )
|
||||
{
|
||||
osg::DrawArrays* drawarray = dynamic_cast<osg::DrawArrays*>( geom->getPrimitiveSet( i ) );
|
||||
if( drawarray )
|
||||
{
|
||||
GLint first = drawarray->getFirst();
|
||||
GLint last = drawarray->getFirst()+drawarray->getCount();
|
||||
|
||||
// Invert vertex order.
|
||||
osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
|
||||
if( vertices )
|
||||
{
|
||||
reverseWindingOrder( vertices, drawarray->getMode(), first, last );
|
||||
}
|
||||
|
||||
if( geom->getNormalBinding( ) == osg::Geometry::BIND_PER_VERTEX )
|
||||
{
|
||||
osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geom->getNormalArray());
|
||||
if( normals )
|
||||
{
|
||||
// First, invert the direction of the normals.
|
||||
for( GLint i = first; i < last; ++i )
|
||||
{
|
||||
(*normals)[i] = -(*normals)[i];
|
||||
}
|
||||
reverseWindingOrder( normals, drawarray->getMode(), first, last );
|
||||
}
|
||||
}
|
||||
|
||||
if( geom->getColorBinding( ) == osg::Geometry::BIND_PER_VERTEX )
|
||||
{
|
||||
osg::Vec4Array* colors = dynamic_cast<osg::Vec4Array*>(geom->getColorArray());
|
||||
if( colors )
|
||||
{
|
||||
reverseWindingOrder( colors, drawarray->getMode(), first, last );
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < geom->getNumTexCoordArrays(); ++i )
|
||||
{
|
||||
osg::Vec2Array* UVs = dynamic_cast<osg::Vec2Array*>(geom->getTexCoordArray(i));
|
||||
if( UVs )
|
||||
{
|
||||
reverseWindingOrder( UVs, drawarray->getMode(), first, last );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now add the new geometry drawable.
|
||||
for( size_t i = 0; i < new_drawables.size( ); ++i )
|
||||
{
|
||||
geode->addDrawable( new_drawables[i] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Face record
|
||||
*/
|
||||
class Face : public PrimaryRecord
|
||||
@@ -374,7 +474,15 @@ protected:
|
||||
break;
|
||||
}
|
||||
case SOLID_NO_BACKFACE: // Disable backface culling
|
||||
stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
|
||||
if( document.getReplaceDoubleSidedPolys( ) )
|
||||
{
|
||||
static osg::ref_ptr<osg::CullFace> cullFace = new osg::CullFace(osg::CullFace::BACK);
|
||||
stateset->setAttributeAndModes(cullFace.get(), osg::StateAttribute::ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -477,6 +585,11 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
if( getDrawMode( ) == SOLID_NO_BACKFACE && document.getReplaceDoubleSidedPolys( ) )
|
||||
{
|
||||
addDrawableAndReverseWindingOrder( _geode.get() );
|
||||
}
|
||||
|
||||
osg::StateSet* stateset = _geode->getOrCreateStateSet();
|
||||
|
||||
// Translucent image?
|
||||
@@ -930,7 +1043,15 @@ protected:
|
||||
break;
|
||||
}
|
||||
case SOLID_NO_BACKFACE: // Disable backface culling
|
||||
stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
|
||||
if( document.getReplaceDoubleSidedPolys( ) )
|
||||
{
|
||||
static osg::ref_ptr<osg::CullFace> cullFace = new osg::CullFace(osg::CullFace::BACK);
|
||||
stateset->setAttributeAndModes(cullFace.get(), osg::StateAttribute::ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -960,6 +1081,11 @@ protected:
|
||||
insertMatrixTransform(*_geode,*_matrix,_numberOfReplications);
|
||||
}
|
||||
|
||||
if( getDrawMode( ) == SOLID_NO_BACKFACE && document.getReplaceDoubleSidedPolys( ) )
|
||||
{
|
||||
addDrawableAndReverseWindingOrder( _geode.get() );
|
||||
}
|
||||
|
||||
osg::StateSet* stateset = _geode->getOrCreateStateSet();
|
||||
|
||||
// Translucent image?
|
||||
|
||||
@@ -231,6 +231,7 @@ class FLTReaderWriter : public ReaderWriter
|
||||
supportsOption("keepExternalReferences","Import option");
|
||||
supportsOption("preserveFace","Import option");
|
||||
supportsOption("preserveObject","Import option");
|
||||
supportsOption("replaceDoubleSidedPolys","Import option");
|
||||
supportsOption("dofAnimation","Import option");
|
||||
supportsOption("billboardCenter","Import option");
|
||||
supportsOption("noTextureAlphaForTransparancyBinning","Import option");
|
||||
@@ -360,6 +361,9 @@ class FLTReaderWriter : public ReaderWriter
|
||||
document.setPreserveObject((options->getOptionString().find("preserveObject")!=std::string::npos));
|
||||
OSG_DEBUG << readerMsg << "preserveObject=" << document.getPreserveObject() << std::endl;
|
||||
|
||||
document.setReplaceDoubleSidedPolys((options->getOptionString().find("replaceDoubleSidedPolys")!=std::string::npos));
|
||||
OSG_DEBUG << readerMsg << "replaceDoubleSidedPolys=" << document.getReplaceDoubleSidedPolys() << std::endl;
|
||||
|
||||
document.setDefaultDOFAnimationState((options->getOptionString().find("dofAnimation")!=std::string::npos));
|
||||
OSG_DEBUG << readerMsg << "dofAnimation=" << document.getDefaultDOFAnimationState() << std::endl;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user