From Brede Johansen,
"- Replaced some member attributes with local variables in Face record. - Multitexture support in Vertex class. - Renamed VertexList to VertexListRecord (VertexList is now a Vertex array) - new Mesh (with reserved field at offset 12, thanks to Paul Martz) - new LocalVertexPool - new MeshPrimitive - Use ProxyNode for externals. - Local cache for externals"
This commit is contained in:
@@ -19,7 +19,8 @@
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
/* Face record
|
||||
*/
|
||||
class Face : public PrimaryRecord
|
||||
{
|
||||
// flags
|
||||
@@ -32,31 +33,11 @@ class Face : public PrimaryRecord
|
||||
static const unsigned int ROOFLINE_BIT = 0x80000000u >> 6;
|
||||
|
||||
osg::Vec4 _primaryColor;
|
||||
|
||||
int32 _IRColor;
|
||||
int16 _relativePriority;
|
||||
uint8 _drawFlag;
|
||||
uint8 _texturedWhite;
|
||||
int16 _primaryNameIndex;
|
||||
int16 _secondaryNameIndex;
|
||||
uint8 _template;
|
||||
int _detailTexture;
|
||||
int _textureIndex;
|
||||
int _materialIndex;
|
||||
int16 _surface;
|
||||
int16 _feature;
|
||||
int32 _IRMaterial;
|
||||
uint16 _transparency;
|
||||
uint8 _influenceLOD;
|
||||
uint8 _linestyle;
|
||||
uint32 _flags;
|
||||
uint8 _lightMode;
|
||||
osg::Vec4 _primaryPackedColor;
|
||||
osg::Vec4 _secondaryPackedColor;
|
||||
int _textureMappingIndex;
|
||||
int _primaryColorIndex;
|
||||
int _alternateColorIndex;
|
||||
int _shaderIndex;
|
||||
|
||||
osg::ref_ptr<osg::Geode> _geode;
|
||||
osg::ref_ptr<osg::Geometry> _geometry;
|
||||
@@ -126,14 +107,11 @@ public:
|
||||
inline bool isAlphaBlend() const
|
||||
{
|
||||
return (_template==FIXED_ALPHA_BLENDING) ||
|
||||
(_template==AXIAL_ROTATE_WITH_ALPHA_BLENDING) ||
|
||||
(_template==POINT_ROTATE_WITH_ALPHA_BLENDING);
|
||||
(_template==AXIAL_ROTATE_WITH_ALPHA_BLENDING) ||
|
||||
(_template==POINT_ROTATE_WITH_ALPHA_BLENDING);
|
||||
}
|
||||
|
||||
virtual osg::Vec4 getPrimaryColor() const { return _primaryColor; }
|
||||
inline int getMaterialIndex() const { return _materialIndex; }
|
||||
inline int getTextureIndex() const { return _textureIndex; }
|
||||
inline int getTextureMappingIndex() const { return _textureMappingIndex; }
|
||||
inline osg::Vec4 getPrimaryColor() const { return _primaryColor; }
|
||||
inline float getTransparency() const { return (float)_transparency / 65535.0f; }
|
||||
inline bool isTransparent() const { return _transparency > 0; }
|
||||
|
||||
@@ -170,10 +148,13 @@ public:
|
||||
normals->push_back(vertex._normal);
|
||||
}
|
||||
|
||||
if (vertex.validUV())
|
||||
for (int layer=0; layer<Vertex::MAX_LAYERS; layer++)
|
||||
{
|
||||
osg::Vec2Array* UVs = getOrCreateTextureArray(*_geometry,0);
|
||||
UVs->push_back(vertex._uv);
|
||||
if (vertex.validUV(layer))
|
||||
{
|
||||
osg::Vec2Array* UVs = getOrCreateTextureArray(*_geometry,layer);
|
||||
UVs->push_back(vertex._uv[layer]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,10 +190,13 @@ public:
|
||||
normals->push_back(vertex0._normal);
|
||||
}
|
||||
|
||||
if (vertex0.validUV())
|
||||
for (int layer=0; layer<Vertex::MAX_LAYERS; layer++)
|
||||
{
|
||||
osg::Vec2Array* UVs = getOrCreateTextureArray(*_geometry,0);
|
||||
UVs->push_back(vertex0._uv);
|
||||
if (vertex0.validUV(layer))
|
||||
{
|
||||
osg::Vec2Array* UVs = getOrCreateTextureArray(*_geometry,layer);
|
||||
UVs->push_back(vertex0._uv[layer]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,37 +205,37 @@ protected:
|
||||
virtual void readRecord(RecordInputStream& in, Document& document)
|
||||
{
|
||||
std::string id = in.readString(8);
|
||||
_IRColor = in.readInt32();
|
||||
_relativePriority = in.readInt16();
|
||||
int32 IRColor = in.readInt32();
|
||||
int16 relativePriority = in.readInt16();
|
||||
_drawFlag = in.readUInt8();
|
||||
_texturedWhite = in.readUInt8();
|
||||
_primaryNameIndex = in.readInt16(-1);
|
||||
_secondaryNameIndex = in.readInt16(-1);
|
||||
uint8 texturedWhite = in.readUInt8();
|
||||
int16 primaryNameIndex = in.readInt16(-1);
|
||||
int16 secondaryNameIndex = in.readInt16(-1);
|
||||
in.forward(1);
|
||||
_template = in.readUInt8(FIXED_NO_ALPHA_BLENDING);
|
||||
_detailTexture = in.readInt16(-1);
|
||||
_textureIndex = in.readInt16(-1);
|
||||
_materialIndex = in.readInt16(-1);
|
||||
_surface = in.readInt16();
|
||||
_feature = in.readInt16();
|
||||
_IRMaterial = in.readInt32(-1);
|
||||
int detailTexture = in.readInt16(-1);
|
||||
int textureIndex = in.readInt16(-1);
|
||||
int materialIndex = in.readInt16(-1);
|
||||
int16 surface = in.readInt16();
|
||||
int16 feature = in.readInt16();
|
||||
int32 IRMaterial = in.readInt32(-1);
|
||||
_transparency = in.readUInt16(0);
|
||||
// version > 13
|
||||
_influenceLOD = in.readUInt8();
|
||||
_linestyle = in.readUInt8();
|
||||
uint8 influenceLOD = in.readUInt8();
|
||||
uint8 linestyle = in.readUInt8();
|
||||
_flags = in.readUInt32(0);
|
||||
_lightMode = in.readUInt8(FACE_COLOR);
|
||||
in.forward(7);
|
||||
_primaryPackedColor = in.readColor32();
|
||||
_secondaryPackedColor = in.readColor32();
|
||||
osg::Vec4 primaryPackedColor = in.readColor32();
|
||||
osg::Vec4 secondaryPackedColor = in.readColor32();
|
||||
// version >= VERSION_15_1
|
||||
_textureMappingIndex = in.readInt16(-1);
|
||||
int textureMappingIndex = in.readInt16(-1);
|
||||
in.forward(2);
|
||||
_primaryColorIndex = in.readInt32(-1);
|
||||
_alternateColorIndex = in.readInt32(-1);
|
||||
int primaryColorIndex = in.readInt32(-1);
|
||||
int alternateColorIndex = in.readInt32(-1);
|
||||
// version >= 16
|
||||
in.forward(2);
|
||||
_shaderIndex = in.readInt16(-1);
|
||||
int shaderIndex = in.readInt16(-1);
|
||||
|
||||
// Create Geode or Billboard.
|
||||
switch (_template)
|
||||
@@ -289,7 +273,7 @@ protected:
|
||||
_geode->setNodeMask(0);
|
||||
|
||||
// Face color
|
||||
if (_texturedWhite!=0 && _textureIndex>=0)
|
||||
if (texturedWhite!=0 && textureIndex>=0)
|
||||
{
|
||||
_primaryColor = osg::Vec4(1,1,1,1);
|
||||
}
|
||||
@@ -297,15 +281,15 @@ protected:
|
||||
{
|
||||
if (packedColorMode())
|
||||
{
|
||||
_primaryColor = _primaryPackedColor;
|
||||
_primaryColor = primaryPackedColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (document.version() < VERSION_15_1)
|
||||
_primaryColor = document.getColorPool()->getColor(_primaryNameIndex);
|
||||
_primaryColor = document.getColorPool()->getColor(primaryNameIndex);
|
||||
|
||||
else // >= VERSION_15_1
|
||||
_primaryColor = document.getColorPool()->getColor(_primaryColorIndex);
|
||||
_primaryColor = document.getColorPool()->getColor(primaryColorIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,23 +302,23 @@ protected:
|
||||
{
|
||||
osg::Vec4 col = _primaryColor;
|
||||
col.a() = 1.0f - getTransparency();
|
||||
osg::Material* material = document.getOrCreateMaterialPool()->getOrCreateMaterial(_materialIndex,col);
|
||||
osg::Material* material = document.getOrCreateMaterialPool()->getOrCreateMaterial(materialIndex,col);
|
||||
stateset->setAttribute(material);
|
||||
isTransparentMaterial = material->getDiffuse(osg::Material::FRONT).a() < 0.99f;
|
||||
}
|
||||
|
||||
// Shaders
|
||||
if (_shaderIndex >= 0)
|
||||
if (shaderIndex >= 0)
|
||||
{
|
||||
ShaderPool* sp = document.getOrCreateShaderPool();
|
||||
osg::Program* program = sp->get(_shaderIndex);
|
||||
osg::Program* program = sp->get(shaderIndex);
|
||||
if (program)
|
||||
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
// Texture
|
||||
TexturePool* tp = document.getOrCreateTexturePool();
|
||||
osg::StateSet* textureStateSet = tp->get(_textureIndex);
|
||||
osg::StateSet* textureStateSet = tp->get(textureIndex);
|
||||
if (textureStateSet)
|
||||
{
|
||||
// Merge face stateset with texture stateset
|
||||
@@ -390,14 +374,14 @@ protected:
|
||||
|
||||
stateset->setRenderBinDetails(document.subfaceLevel(),"RenderBin");
|
||||
}
|
||||
#if 1
|
||||
|
||||
// A simple share stateset optimization.
|
||||
static osg::ref_ptr<osg::StateSet> lastStateset;
|
||||
if (lastStateset.valid() && (stateset->compare(*lastStateset,false)==0))
|
||||
stateset = lastStateset;
|
||||
else
|
||||
lastStateset = stateset;
|
||||
#endif
|
||||
|
||||
_geode->setStateSet(stateset.get());
|
||||
|
||||
// Add to parent.
|
||||
@@ -485,20 +469,19 @@ protected:
|
||||
};
|
||||
|
||||
RegisterRecordProxy<Face> g_Face(FACE_OP);
|
||||
RegisterRecordProxy<Face> g_Mesh(MESH_OP);
|
||||
|
||||
|
||||
/** VertexList -
|
||||
* The VertexList is a leaf record.
|
||||
* Possible parents: Face, Mesh & LightPoint
|
||||
*/
|
||||
class VertexList : public PrimaryRecord
|
||||
class VertexListRecord : public PrimaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
VertexList() {}
|
||||
VertexListRecord() {}
|
||||
|
||||
META_Record(VertexList)
|
||||
META_Record(VertexListRecord)
|
||||
|
||||
virtual void addVertex(Vertex& vertex)
|
||||
{
|
||||
@@ -516,7 +499,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~VertexList() {}
|
||||
virtual ~VertexListRecord() {}
|
||||
|
||||
virtual void readRecord(RecordInputStream& in, Document& document)
|
||||
{
|
||||
@@ -541,7 +524,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
RegisterRecordProxy<VertexList> g_VertexList(VERTEX_LIST_OP);
|
||||
RegisterRecordProxy<VertexListRecord> g_VertexList(VERTEX_LIST_OP);
|
||||
|
||||
|
||||
/** MorphVertexList -
|
||||
@@ -630,16 +613,538 @@ protected:
|
||||
|
||||
RegisterRecordProxy<MorphVertexList> g_MorphVertexList(MORPH_VERTEX_LIST_OP);
|
||||
|
||||
|
||||
/* Mesh record
|
||||
*/
|
||||
class Mesh : public PrimaryRecord
|
||||
{
|
||||
// flags
|
||||
static const unsigned int TERRAIN_BIT = 0x80000000u >> 0;
|
||||
static const unsigned int NO_COLOR_BIT = 0x80000000u >> 1;
|
||||
static const unsigned int NO_ALT_COLOR_BIT = 0x80000000u >> 2;
|
||||
static const unsigned int PACKED_COLOR_BIT = 0x80000000u >> 3;
|
||||
static const unsigned int FOOTPRINT_BIT = 0x80000000u >> 4; // Terrain culture cutout
|
||||
static const unsigned int HIDDEN_BIT = 0x80000000u >> 5;
|
||||
static const unsigned int ROOFLINE_BIT = 0x80000000u >> 6;
|
||||
|
||||
osg::Vec4 _primaryColor;
|
||||
uint8 _drawFlag;
|
||||
uint8 _template;
|
||||
uint16 _transparency;
|
||||
uint32 _flags;
|
||||
uint8 _lightMode;
|
||||
|
||||
osg::ref_ptr<osg::Geode> _geode;
|
||||
osg::ref_ptr<osg::Geometry> _geometry;
|
||||
|
||||
public:
|
||||
|
||||
Mesh() :
|
||||
_primaryColor(1,1,1,1)
|
||||
{
|
||||
}
|
||||
|
||||
META_Record(Mesh)
|
||||
|
||||
META_setID(_geode)
|
||||
META_setComment(_geode)
|
||||
META_setMatrix(_geode)
|
||||
META_setMultitexture(_geode)
|
||||
|
||||
// draw mode
|
||||
enum DrawMode
|
||||
{
|
||||
SOLID_BACKFACED = 0,
|
||||
SOLID_NO_BACKFACE = 1,
|
||||
WIREFRAME_CLOSED = 2,
|
||||
WIREFRAME_NOT_CLOSED = 3,
|
||||
SURROUND_ALTERNATE_COLOR = 4,
|
||||
OMNIDIRECTIONAL_LIGHT = 8,
|
||||
UNIDIRECTIONAL_LIGHT = 9,
|
||||
BIDIRECTIONAL_LIGHT = 10
|
||||
};
|
||||
|
||||
inline DrawMode getDrawMode() const { return (DrawMode)_drawFlag; }
|
||||
|
||||
// lighting
|
||||
enum LightMode
|
||||
{
|
||||
FACE_COLOR = 0,
|
||||
VERTEX_COLOR = 1,
|
||||
FACE_COLOR_LIGHTING = 2,
|
||||
VERTEX_COLOR_LIGHTING = 3
|
||||
};
|
||||
|
||||
inline LightMode getLightMode() const { return (LightMode)_lightMode; }
|
||||
inline bool isLit() const { return (_lightMode==FACE_COLOR_LIGHTING) || (_lightMode==VERTEX_COLOR_LIGHTING); }
|
||||
inline bool isGouraud() const { return (_lightMode==VERTEX_COLOR) || (_lightMode==VERTEX_COLOR_LIGHTING); }
|
||||
|
||||
// flags
|
||||
inline bool noColor() const { return (_flags & NO_COLOR_BIT)!=0; }
|
||||
inline bool isHidden() const { return (_flags & HIDDEN_BIT)!=0; }
|
||||
inline bool isTerrain() const { return (_flags & TERRAIN_BIT)!=0; }
|
||||
inline bool isFootprint() const { return (_flags & FOOTPRINT_BIT)!=0; }
|
||||
inline bool isRoofline() const { return (_flags & ROOFLINE_BIT)!=0; }
|
||||
inline bool packedColorMode() const { return (_flags & PACKED_COLOR_BIT)!=0; }
|
||||
|
||||
// billboard
|
||||
enum TemplateMode
|
||||
{
|
||||
FIXED_NO_ALPHA_BLENDING = 0,
|
||||
FIXED_ALPHA_BLENDING = 1,
|
||||
AXIAL_ROTATE_WITH_ALPHA_BLENDING = 2,
|
||||
POINT_ROTATE_WITH_ALPHA_BLENDING = 4
|
||||
};
|
||||
|
||||
inline TemplateMode getTemplateMode() const { return (TemplateMode)_template; }
|
||||
|
||||
// transparency & alpha
|
||||
inline bool isAlphaBlend() const
|
||||
{
|
||||
return (_template==FIXED_ALPHA_BLENDING) ||
|
||||
(_template==AXIAL_ROTATE_WITH_ALPHA_BLENDING) ||
|
||||
(_template==POINT_ROTATE_WITH_ALPHA_BLENDING);
|
||||
}
|
||||
|
||||
inline osg::Vec4 getPrimaryColor() const { return _primaryColor; }
|
||||
inline float getTransparency() const { return (float)_transparency / 65535.0f; }
|
||||
inline bool isTransparent() const { return _transparency > 0; }
|
||||
|
||||
virtual void addChild(osg::Node& child)
|
||||
{
|
||||
// Add subface to parent.
|
||||
if (_parent.valid())
|
||||
_parent->addChild(child);
|
||||
}
|
||||
|
||||
virtual void addGeometry(osg::Geometry& geometry)
|
||||
{
|
||||
_geode->addDrawable(&geometry);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void readRecord(RecordInputStream& in, Document& document)
|
||||
{
|
||||
std::string id = in.readString(8);
|
||||
in.forward(4);
|
||||
int32 IRColor = in.readInt32();
|
||||
int16 relativePriority = in.readInt16();
|
||||
_drawFlag = in.readUInt8();
|
||||
uint8 texturedWhite = in.readUInt8();
|
||||
int16 primaryNameIndex = in.readInt16(-1);
|
||||
int16 secondaryNameIndex = in.readInt16(-1);
|
||||
in.forward(1);
|
||||
_template = in.readUInt8(FIXED_NO_ALPHA_BLENDING);
|
||||
int detailTexture = in.readInt16(-1);
|
||||
int textureIndex = in.readInt16(-1);
|
||||
int materialIndex = in.readInt16(-1);
|
||||
int16 surface = in.readInt16();
|
||||
int16 feature = in.readInt16();
|
||||
int32 IRMaterial = in.readInt32(-1);
|
||||
_transparency = in.readUInt16(0);
|
||||
// version > 13
|
||||
uint8 influenceLOD = in.readUInt8();
|
||||
uint8 linestyle = in.readUInt8();
|
||||
_flags = in.readUInt32(0);
|
||||
_lightMode = in.readUInt8(FACE_COLOR);
|
||||
in.forward(7);
|
||||
osg::Vec4 primaryPackedColor = in.readColor32();
|
||||
osg::Vec4 secondaryPackedColor = in.readColor32();
|
||||
// version >= VERSION_15_1
|
||||
int textureMappingIndex = in.readInt16(-1);
|
||||
in.forward(2);
|
||||
int primaryColorIndex = in.readInt32(-1);
|
||||
int alternateColorIndex = in.readInt32(-1);
|
||||
// version >= 16
|
||||
in.forward(2);
|
||||
int shaderIndex = in.readInt16(-1);
|
||||
|
||||
// Create Geode or Billboard.
|
||||
switch (_template)
|
||||
{
|
||||
case AXIAL_ROTATE_WITH_ALPHA_BLENDING:
|
||||
{
|
||||
osg::Billboard* billboard = new osg::Billboard;
|
||||
billboard->setMode(osg::Billboard::AXIAL_ROT);
|
||||
_geode = billboard;
|
||||
}
|
||||
break;
|
||||
case POINT_ROTATE_WITH_ALPHA_BLENDING:
|
||||
{
|
||||
osg::Billboard* billboard = new osg::Billboard;
|
||||
billboard->setMode(osg::Billboard::POINT_ROT_WORLD);
|
||||
_geode = billboard;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_geode = new osg::Geode;
|
||||
}
|
||||
|
||||
_geode->setDataVariance(osg::Object::STATIC);
|
||||
_geode->setName(id);
|
||||
|
||||
// StateSet
|
||||
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
|
||||
|
||||
// Hidden
|
||||
if (isHidden())
|
||||
_geode->setNodeMask(0);
|
||||
|
||||
// Face color
|
||||
if (texturedWhite!=0 && textureIndex>=0)
|
||||
{
|
||||
_primaryColor = osg::Vec4(1,1,1,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (packedColorMode())
|
||||
{
|
||||
_primaryColor = primaryPackedColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (document.version() < VERSION_15_1)
|
||||
_primaryColor = document.getColorPool()->getColor(primaryNameIndex);
|
||||
|
||||
else // >= VERSION_15_1
|
||||
_primaryColor = document.getColorPool()->getColor(primaryColorIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Lighting
|
||||
stateset->setMode(GL_LIGHTING, isLit() ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
|
||||
|
||||
// Material
|
||||
bool isTransparentMaterial = false;
|
||||
if (isLit())
|
||||
{
|
||||
osg::Vec4 col = _primaryColor;
|
||||
col.a() = 1.0f - getTransparency();
|
||||
osg::Material* material = document.getOrCreateMaterialPool()->getOrCreateMaterial(materialIndex,col);
|
||||
stateset->setAttribute(material);
|
||||
isTransparentMaterial = material->getDiffuse(osg::Material::FRONT).a() < 0.99f;
|
||||
}
|
||||
|
||||
// Shaders
|
||||
if (shaderIndex >= 0)
|
||||
{
|
||||
ShaderPool* sp = document.getOrCreateShaderPool();
|
||||
osg::Program* program = sp->get(shaderIndex);
|
||||
if (program)
|
||||
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
// Texture
|
||||
TexturePool* tp = document.getOrCreateTexturePool();
|
||||
osg::StateSet* textureStateSet = tp->get(textureIndex);
|
||||
if (textureStateSet)
|
||||
{
|
||||
// Merge face stateset with texture stateset
|
||||
stateset->merge(*textureStateSet);
|
||||
}
|
||||
|
||||
// Translucent image?
|
||||
bool isImageTranslucent = false;
|
||||
if (textureStateSet)
|
||||
{
|
||||
if (document.getUseTextureAlphaForTransparancyBinning())
|
||||
{
|
||||
osg::Texture2D* texture = dynamic_cast<osg::Texture2D*>(textureStateSet->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
|
||||
if (texture)
|
||||
{
|
||||
osg::Image* image = texture->getImage();
|
||||
if (image && image->isImageTranslucent())
|
||||
isImageTranslucent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable alpha blend?
|
||||
if (isAlphaBlend() || isTransparent() || isTransparentMaterial || isImageTranslucent)
|
||||
{
|
||||
static osg::ref_ptr<osg::BlendFunc> blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
|
||||
stateset->setAttributeAndModes(blendFunc.get(), osg::StateAttribute::ON);
|
||||
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
}
|
||||
|
||||
// Cull face
|
||||
switch(_drawFlag)
|
||||
{
|
||||
case SOLID_BACKFACED: // Enable backface culling
|
||||
{
|
||||
static osg::ref_ptr<osg::CullFace> cullFace = new osg::CullFace(osg::CullFace::BACK);
|
||||
stateset->setAttributeAndModes(cullFace.get(), osg::StateAttribute::ON);
|
||||
break;
|
||||
}
|
||||
case SOLID_NO_BACKFACE: // Disable backface culling
|
||||
stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
|
||||
break;
|
||||
}
|
||||
|
||||
// Subface
|
||||
if (document.subfaceLevel() > 0)
|
||||
{
|
||||
static osg::ref_ptr<osg::PolygonOffset> polygonOffset = new osg::PolygonOffset(-10.0f, -40.0f);
|
||||
stateset->setAttributeAndModes(polygonOffset.get(), osg::StateAttribute::ON);
|
||||
|
||||
static osg::ref_ptr<osg::Depth> depth = new osg::Depth(osg::Depth::LESS, 0.0, 1.0,false);
|
||||
stateset->setAttribute(depth.get());
|
||||
|
||||
stateset->setRenderBinDetails(document.subfaceLevel(),"RenderBin");
|
||||
}
|
||||
|
||||
// A simple share stateset optimization.
|
||||
static osg::ref_ptr<osg::StateSet> lastStateset;
|
||||
if (lastStateset.valid() && (stateset->compare(*lastStateset,false)==0))
|
||||
stateset = lastStateset;
|
||||
else
|
||||
lastStateset = stateset;
|
||||
|
||||
_geode->setStateSet(stateset.get());
|
||||
|
||||
// Add to parent.
|
||||
if (_parent.valid())
|
||||
_parent->addChild(*_geode);
|
||||
}
|
||||
|
||||
virtual ~Mesh() {}
|
||||
};
|
||||
|
||||
RegisterRecordProxy<Mesh> g_Mesh(MESH_OP);
|
||||
|
||||
|
||||
|
||||
/** LocalVertexPool -
|
||||
*/
|
||||
class LocalVertexPool : public Record
|
||||
{
|
||||
// Attribute Mask
|
||||
static const unsigned int HAS_POSITION = 0x80000000u >> 0;
|
||||
static const unsigned int HAS_COLOR_INDEX = 0x80000000u >> 1;
|
||||
static const unsigned int HAS_RGBA_COLOR = 0x80000000u >> 2;
|
||||
static const unsigned int HAS_NORMAL = 0x80000000u >> 3;
|
||||
static const unsigned int HAS_BASE_UV = 0x80000000u >> 4;
|
||||
static const unsigned int HAS_UV_LAYER1 = 0x80000000u >> 5;
|
||||
static const unsigned int HAS_UV_LAYER2 = 0x80000000u >> 6;
|
||||
static const unsigned int HAS_UV_LAYER3 = 0x80000000u >> 7;
|
||||
static const unsigned int HAS_UV_LAYER4 = 0x80000000u >> 8;
|
||||
static const unsigned int HAS_UV_LAYER5 = 0x80000000u >> 9;
|
||||
static const unsigned int HAS_UV_LAYER6 = 0x80000000u >> 10;
|
||||
static const unsigned int HAS_UV_LAYER7 = 0x80000000u >> 11;
|
||||
|
||||
public:
|
||||
|
||||
LocalVertexPool() {}
|
||||
|
||||
META_Record(LocalVertexPool)
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~LocalVertexPool() {}
|
||||
|
||||
virtual void readRecord(RecordInputStream& in, Document& document)
|
||||
{
|
||||
|
||||
uint32 vertices = in.readUInt32();
|
||||
uint32 mask = in.readUInt32();
|
||||
|
||||
osg::ref_ptr<VertexList> _vertexList = new VertexList(vertices);
|
||||
|
||||
|
||||
for (unsigned int n=0; n<vertices; n++)
|
||||
{
|
||||
Vertex vertex;
|
||||
|
||||
if (mask & HAS_POSITION)
|
||||
{
|
||||
osg::Vec3d coord = in.readVec3d();
|
||||
vertex.setCoord(coord*document.unitScale());
|
||||
}
|
||||
|
||||
if (mask & HAS_COLOR_INDEX)
|
||||
{
|
||||
uint32 alphaIndex = in.readUInt32();
|
||||
int index = alphaIndex & 0x00ffffff;
|
||||
uint8 alpha = alphaIndex >> 24;
|
||||
osg::Vec4 color = document.getColorPool()->getColor(index);
|
||||
color.a() = (float)alpha/255;
|
||||
vertex.setColor(color);
|
||||
}
|
||||
|
||||
if (mask & HAS_RGBA_COLOR)
|
||||
{
|
||||
osg::Vec4f color = in.readColor32();
|
||||
vertex.setColor(color);
|
||||
}
|
||||
|
||||
if (mask & HAS_NORMAL)
|
||||
{
|
||||
osg::Vec3f normal = in.readVec3f();
|
||||
vertex.setNormal(normal);
|
||||
}
|
||||
|
||||
for (unsigned int layer=0; layer<8; layer++)
|
||||
{
|
||||
if (mask & (HAS_BASE_UV >> layer))
|
||||
{
|
||||
osg::Vec2f uv = in.readVec2f();
|
||||
vertex.setUV(layer,uv);
|
||||
}
|
||||
}
|
||||
|
||||
(*_vertexList)[n] = vertex;
|
||||
}
|
||||
|
||||
if (_parent.valid())
|
||||
_parent->setLocalVertexPool(_vertexList.get());
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
RegisterRecordProxy<LocalVertexPool> g_LocalVertexPool(LOCAL_VERTEX_POOL_OP);
|
||||
|
||||
|
||||
|
||||
/** MeshPrimitive -
|
||||
*/
|
||||
class MeshPrimitive : public PrimaryRecord
|
||||
{
|
||||
enum PrimitiveType
|
||||
{
|
||||
TRIANGLE_STRIP = 1,
|
||||
TRIANGLE_FAN = 2,
|
||||
QUADRILATERAL_STRIP = 3,
|
||||
INDEXED_POLYGON = 4
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
MeshPrimitive() {}
|
||||
|
||||
META_Record(MeshPrimitive)
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~MeshPrimitive() {}
|
||||
|
||||
virtual void readRecord(RecordInputStream& in, Document& document)
|
||||
{
|
||||
Mesh* mesh = dynamic_cast<Mesh*>(_parent.get());
|
||||
if (!mesh) return;
|
||||
|
||||
VertexList* vertexList = mesh->getLocalVertexPool();
|
||||
if (!vertexList) return;
|
||||
|
||||
int16 type = in.readInt16();
|
||||
uint16 indexSize = in.readUInt16();
|
||||
uint32 vertexCount = in.readUInt32();
|
||||
|
||||
GLenum mode = 0;
|
||||
switch(type)
|
||||
{
|
||||
case TRIANGLE_STRIP:
|
||||
mode = osg::PrimitiveSet::TRIANGLE_STRIP;
|
||||
break;
|
||||
case TRIANGLE_FAN:
|
||||
mode = osg::PrimitiveSet::TRIANGLE_FAN;
|
||||
break;
|
||||
case QUADRILATERAL_STRIP:
|
||||
mode = osg::PrimitiveSet::QUAD_STRIP;
|
||||
break;
|
||||
case INDEXED_POLYGON:
|
||||
mode = osg::PrimitiveSet::POLYGON;
|
||||
break;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
|
||||
geometry->addPrimitiveSet(new osg::DrawArrays(mode,0,vertexCount));
|
||||
|
||||
for (unsigned int n=0; n<vertexCount; n++)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
switch (indexSize)
|
||||
{
|
||||
case 1:
|
||||
index = in.readUInt8();
|
||||
break;
|
||||
case 2:
|
||||
index = in.readUInt16();
|
||||
break;
|
||||
case 4:
|
||||
index = in.readUInt32();
|
||||
break;
|
||||
}
|
||||
|
||||
if (index < vertexList->size())
|
||||
{
|
||||
Vertex& vertex = (*vertexList)[index];
|
||||
|
||||
osg::Vec3Array* vertices = getOrCreateVertexArray(*geometry);
|
||||
vertices->push_back(vertex._coord);
|
||||
|
||||
if (vertex.validColor())
|
||||
{
|
||||
osg::Vec4Array* colors = getOrCreateColorArray(*geometry);
|
||||
colors->push_back(vertex._color);
|
||||
}
|
||||
|
||||
if (vertex.validNormal())
|
||||
{
|
||||
osg::Vec3Array* normals = getOrCreateNormalArray(*geometry);
|
||||
normals->push_back(vertex._normal);
|
||||
}
|
||||
|
||||
for (int layer=0; layer<Vertex::MAX_LAYERS; layer++)
|
||||
{
|
||||
if (vertex.validUV(layer))
|
||||
{
|
||||
osg::Vec2Array* UVs = getOrCreateTextureArray(*geometry,layer);
|
||||
UVs->push_back(vertex._uv[layer]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Color binding
|
||||
if (mesh->isGouraud())
|
||||
{
|
||||
// Color per vertex
|
||||
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Color per face
|
||||
osg::Vec4 col = mesh->getPrimaryColor();
|
||||
col[3] = 1.0f - mesh->getTransparency();
|
||||
|
||||
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
osg::Vec4Array* colors = new osg::Vec4Array(1);
|
||||
(*colors)[0] = col;
|
||||
geometry->setColorArray(colors);
|
||||
}
|
||||
|
||||
// Normal binding
|
||||
if (mesh->isLit())
|
||||
{
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX );
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
|
||||
geometry->setNormalArray(NULL);
|
||||
}
|
||||
|
||||
mesh->addGeometry(*geometry);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
RegisterRecordProxy<MeshPrimitive> g_MeshPrimitive(MESH_PRIMITIVE_OP);
|
||||
|
||||
|
||||
} // end namespace
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <osg/ProxyNode>
|
||||
#include <osg/Sequence>
|
||||
#include <osg/LOD>
|
||||
#include <osg/ProxyNode>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgSim/DOFTransform>
|
||||
#include <osgSim/MultiSwitch>
|
||||
@@ -587,7 +588,7 @@ RegisterRecordProxy<Switch> g_Switch(SWITCH_OP);
|
||||
*/
|
||||
class ExternalReference : public PrimaryRecord
|
||||
{
|
||||
osg::ref_ptr<osg::Group> _external;
|
||||
osg::ref_ptr<osg::ProxyNode> _external;
|
||||
|
||||
public:
|
||||
|
||||
@@ -609,18 +610,9 @@ protected:
|
||||
{
|
||||
std::string strFile = in.readString(200);
|
||||
|
||||
//Path for Nested external references
|
||||
const osgDB::ReaderWriter::Options *options = document.getOptions();
|
||||
std::string filename = osgDB::findDataFile(strFile, options);
|
||||
if (filename.empty())
|
||||
{
|
||||
osg::notify(osg::WARN) << "Can't find external " << strFile << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_external = new osg::Group;
|
||||
_external->setName(strFile);
|
||||
Registry::instance()->addExternal(filename, _external.get());
|
||||
_external = new osg::ProxyNode;
|
||||
_external->setCenterMode(osg::ProxyNode::USE_BOUNDING_SPHERE_CENTER);
|
||||
_external->setFileName(0,strFile);
|
||||
|
||||
// Add this implementation to parent implementation.
|
||||
if (_parent.valid())
|
||||
@@ -761,3 +753,6 @@ RegisterRecordProxy<Extension> g_Extension(EXTENSION_OP);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <osg/Notify>
|
||||
#include <osg/ProxyNode>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/ReentrantMutex>
|
||||
|
||||
#include <osgSim/OpenFlightOptimizer>
|
||||
|
||||
#include "Registry.h"
|
||||
#include "Document.h"
|
||||
#include "RecordInputStream.h"
|
||||
@@ -25,6 +24,35 @@ using namespace osg;
|
||||
using namespace osgDB;
|
||||
|
||||
|
||||
class ReadExternalsVisitor : public osg::NodeVisitor
|
||||
{
|
||||
osg::ref_ptr<ReaderWriter::Options> _options;
|
||||
|
||||
public:
|
||||
|
||||
ReadExternalsVisitor(ReaderWriter::Options* options) :
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_options(options)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ReadExternalsVisitor() {}
|
||||
|
||||
virtual void apply(ProxyNode& node)
|
||||
{
|
||||
for (unsigned int pos=0; pos<node.getNumFileNames(); pos++)
|
||||
{
|
||||
std::string filename = node.getFileName(pos);
|
||||
|
||||
// read external
|
||||
osg::Node* external = osgDB::readNodeFile(filename,_options.get());
|
||||
if (external)
|
||||
node.addChild(external);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FLTReaderWriter : public ReaderWriter
|
||||
{
|
||||
public:
|
||||
@@ -47,18 +75,55 @@ class FLTReaderWriter : public ReaderWriter
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
std::string fileName = osgDB::findDataFile( file, options );
|
||||
std::string fileName = osgDB::findDataFile(file, options);
|
||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
// code for setting up the database path so that internally referenced file are searched for on relative paths.
|
||||
// in local cache?
|
||||
{
|
||||
osg::Node* node = flt::Registry::instance()->getFromLocalCache(fileName);
|
||||
if (node)
|
||||
return ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
|
||||
}
|
||||
|
||||
// setting up the database path so that internally referenced file are searched for on relative paths.
|
||||
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
|
||||
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
|
||||
|
||||
std::ifstream istream;
|
||||
istream.imbue(std::locale::classic());
|
||||
istream.open(fileName.c_str(), std::ios::in | std::ios::binary);
|
||||
ReadResult rr;
|
||||
|
||||
return readNode(istream,local_opt.get());
|
||||
// read file
|
||||
{
|
||||
std::ifstream istream;
|
||||
istream.imbue(std::locale::classic());
|
||||
istream.open(fileName.c_str(), std::ios::in | std::ios::binary);
|
||||
|
||||
if (istream)
|
||||
{
|
||||
rr = readNode(istream,local_opt.get());
|
||||
}
|
||||
}
|
||||
|
||||
static int nestedExternalsLevel = 0;
|
||||
if (rr.success())
|
||||
{
|
||||
// add to local cache.
|
||||
flt::Registry::instance()->addToLocalCache(fileName,rr.getNode());
|
||||
|
||||
// read externals.
|
||||
if (rr.getNode())
|
||||
{
|
||||
nestedExternalsLevel++;
|
||||
ReadExternalsVisitor visitor(local_opt.get());
|
||||
rr.getNode()->accept(visitor);
|
||||
nestedExternalsLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
// clear local cache.
|
||||
if (nestedExternalsLevel==0)
|
||||
flt::Registry::instance()->clearLocalCache();
|
||||
|
||||
return rr;
|
||||
}
|
||||
|
||||
virtual ReadResult readObject(std::istream& fin, const Options* options) const
|
||||
@@ -68,62 +133,45 @@ class FLTReaderWriter : public ReaderWriter
|
||||
|
||||
virtual ReadResult readNode(std::istream& fin, const Options* options) const
|
||||
{
|
||||
try
|
||||
Document document;
|
||||
document.setOptions(options);
|
||||
|
||||
// option string
|
||||
if (options)
|
||||
{
|
||||
Document document;
|
||||
document.setOptions(options);
|
||||
document.setUseTextureAlphaForTransparancyBinning(options->getOptionString().find("noTextureAlphaForTransparancyBinning")==std::string::npos);
|
||||
osg::notify(osg::DEBUG_INFO) << "FltFile.getUseTextureAlphaForTransparancyBinning()=" << document.getUseTextureAlphaForTransparancyBinning() << std::endl;
|
||||
document.setDoUnitsConversion((options->getOptionString().find("noUnitsConversion")==std::string::npos)); // default to true, unless noUnitsConversion is specified.o
|
||||
osg::notify(osg::DEBUG_INFO) << "FltFile.getDoUnitsConversion()=" << document.getDoUnitsConversion() << std::endl;
|
||||
|
||||
// option string
|
||||
if (options)
|
||||
if (document.getDoUnitsConversion())
|
||||
{
|
||||
document.setUseTextureAlphaForTransparancyBinning(options->getOptionString().find("noTextureAlphaForTransparancyBinning")==std::string::npos);
|
||||
osg::notify(osg::DEBUG_INFO) << "FltFile.getUseTextureAlphaForTransparancyBinning()=" << document.getUseTextureAlphaForTransparancyBinning() << std::endl;
|
||||
document.setDoUnitsConversion((options->getOptionString().find("noUnitsConversion")==std::string::npos)); // default to true, unless noUnitsConversion is specified.o
|
||||
osg::notify(osg::DEBUG_INFO) << "FltFile.getDoUnitsConversion()=" << document.getDoUnitsConversion() << std::endl;
|
||||
|
||||
if (document.getDoUnitsConversion())
|
||||
{
|
||||
if (options->getOptionString().find("convertToFeet")!=std::string::npos)
|
||||
document.setDesiredUnits(FEET);
|
||||
else if (options->getOptionString().find("convertToInches")!=std::string::npos)
|
||||
document.setDesiredUnits(INCHES);
|
||||
else if (options->getOptionString().find("convertToMeters")!=std::string::npos)
|
||||
document.setDesiredUnits(METERS);
|
||||
else if (options->getOptionString().find("convertToKilometers")!=std::string::npos)
|
||||
document.setDesiredUnits(KILOMETERS);
|
||||
else if (options->getOptionString().find("convertToNauticalMiles")!=std::string::npos)
|
||||
document.setDesiredUnits(NAUTICAL_MILES);
|
||||
}
|
||||
if (options->getOptionString().find("convertToFeet")!=std::string::npos)
|
||||
document.setDesiredUnits(FEET);
|
||||
else if (options->getOptionString().find("convertToInches")!=std::string::npos)
|
||||
document.setDesiredUnits(INCHES);
|
||||
else if (options->getOptionString().find("convertToMeters")!=std::string::npos)
|
||||
document.setDesiredUnits(METERS);
|
||||
else if (options->getOptionString().find("convertToKilometers")!=std::string::npos)
|
||||
document.setDesiredUnits(KILOMETERS);
|
||||
else if (options->getOptionString().find("convertToNauticalMiles")!=std::string::npos)
|
||||
document.setDesiredUnits(NAUTICAL_MILES);
|
||||
}
|
||||
|
||||
{
|
||||
// read records
|
||||
flt::RecordInputStream recordStream(&fin);
|
||||
while (recordStream().good() && !document.done())
|
||||
{
|
||||
recordStream.readRecord(document);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// optimize
|
||||
osgFlightUtil::Optimizer optimizer;
|
||||
optimizer.optimize(document.getHeaderNode());
|
||||
}
|
||||
|
||||
readExternals(options);
|
||||
|
||||
return document.getHeaderNode();
|
||||
}
|
||||
catch (std::exception &e)
|
||||
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Error reading file: " << e.what() << std::endl;
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
// read records
|
||||
flt::RecordInputStream recordStream(&fin);
|
||||
while (recordStream().good() && !document.done())
|
||||
{
|
||||
recordStream.readRecord(document);
|
||||
}
|
||||
}
|
||||
|
||||
if (!document.getHeaderNode())
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
|
||||
return document.getHeaderNode();
|
||||
}
|
||||
|
||||
virtual WriteResult writeObject(const Object& object,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
|
||||
@@ -164,23 +212,6 @@ class FLTReaderWriter : public ReaderWriter
|
||||
|
||||
protected:
|
||||
|
||||
void readExternals(const Options* options) const
|
||||
{
|
||||
flt::Registry::ExternalQueue& eq = flt::Registry::instance()->getExternalQueue();
|
||||
while (!eq.empty())
|
||||
{
|
||||
std::string extfilename = eq.front().first;
|
||||
osg::ref_ptr<osg::Group> external = eq.front().second;
|
||||
eq.pop();
|
||||
|
||||
if (external.valid())
|
||||
{
|
||||
osg::Node* extmodel = osgDB::readNodeFile(extfilename,options);
|
||||
external->addChild(extmodel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutable osgDB::ReentrantMutex _serializerMutex;
|
||||
};
|
||||
|
||||
@@ -199,3 +230,6 @@ RegisterReaderWriterProxy<FLTReaderWriter> g_FLTReaderWriterProxy;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -77,11 +77,15 @@ public:
|
||||
|
||||
void setNumberOfReplications(int num) { _numberOfReplications = num; }
|
||||
|
||||
void setLocalVertexPool(VertexList* pool) { _localVertexPool = pool; }
|
||||
VertexList* getLocalVertexPool() { return _localVertexPool.get(); }
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~PrimaryRecord() {}
|
||||
|
||||
int _numberOfReplications;
|
||||
osg::ref_ptr<VertexList> _localVertexPool;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define FLT_REGISTRY_H 1
|
||||
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <osg/ref_ptr>
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
@@ -21,31 +22,57 @@ class Registry : public osg::Referenced
|
||||
~Registry();
|
||||
static Registry* instance();
|
||||
|
||||
// Prototypes
|
||||
// Record prototypes
|
||||
void addPrototype(int opcode, Record* prototype);
|
||||
Record* getPrototype(int opcode);
|
||||
|
||||
// Externals
|
||||
typedef std::pair<std::string, osg::Group*> ExtNameNodePair;
|
||||
typedef std::queue<ExtNameNodePair> ExternalQueue;
|
||||
// External read queue
|
||||
typedef std::pair<std::string, osg::Group*> FilenameParentPair; // ExtNameNodePair;
|
||||
typedef std::queue<FilenameParentPair> ExternalQueue;
|
||||
|
||||
inline ExternalQueue& getExternalQueue() { return _externalQueue; }
|
||||
inline ExternalQueue& getExternalReadQueue() { return _externalReadQueue; }
|
||||
void addToExternalReadQueue(const std::string& filename, osg::Group* parent);
|
||||
|
||||
inline void addExternal(const std::string& name, osg::Group* node)
|
||||
{
|
||||
_externalQueue.push( ExtNameNodePair(name,node) );
|
||||
}
|
||||
// Local cache
|
||||
void addToLocalCache(const std::string& filename, osg::Node* node);
|
||||
osg::Node* getFromLocalCache(const std::string& filename);
|
||||
void clearLocalCache();
|
||||
|
||||
protected:
|
||||
|
||||
Registry();
|
||||
|
||||
typedef std::map<int, osg::ref_ptr<Record> > RecordProtoMap;
|
||||
RecordProtoMap _recordProtoMap;
|
||||
RecordProtoMap _recordProtoMap;
|
||||
|
||||
ExternalQueue _externalQueue;
|
||||
ExternalQueue _externalReadQueue;
|
||||
|
||||
typedef std::map<std::string, osg::ref_ptr<osg::Node> > ExternalCacheMap;
|
||||
ExternalCacheMap _externalCacheMap;
|
||||
};
|
||||
|
||||
inline void Registry::addToExternalReadQueue(const std::string& filename, osg::Group* parent)
|
||||
{
|
||||
_externalReadQueue.push( FilenameParentPair(filename,parent) );
|
||||
}
|
||||
|
||||
inline void Registry::addToLocalCache(const std::string& filename, osg::Node* node)
|
||||
{
|
||||
_externalCacheMap[filename] = node;
|
||||
}
|
||||
|
||||
inline osg::Node* Registry::getFromLocalCache(const std::string& filename)
|
||||
{
|
||||
ExternalCacheMap::iterator itr = _externalCacheMap.find(filename);
|
||||
if (itr != _externalCacheMap.end())
|
||||
return (*itr).second.get();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline void Registry::clearLocalCache()
|
||||
{
|
||||
_externalCacheMap.clear();
|
||||
}
|
||||
|
||||
/** Proxy class for automatic registration of reader/writers with the Registry.*/
|
||||
template<class T>
|
||||
|
||||
@@ -13,43 +13,50 @@ Vertex::Vertex():
|
||||
_color(1,1,1,1),
|
||||
_normal(0,0,1),
|
||||
_validColor(false),
|
||||
_validNormal(false),
|
||||
_validUV(false)
|
||||
_validNormal(false)
|
||||
{
|
||||
for (int layer=0; layer<MAX_LAYERS; layer++)
|
||||
_validUV[layer] = false;
|
||||
}
|
||||
|
||||
Vertex::Vertex(const Vertex& vertex):
|
||||
_coord(vertex._coord),
|
||||
_color(vertex._color),
|
||||
_normal(vertex._normal),
|
||||
_uv(vertex._uv),
|
||||
_validColor(vertex._validColor),
|
||||
_validNormal(vertex._validNormal),
|
||||
_validUV(vertex._validUV)
|
||||
_validNormal(vertex._validNormal)
|
||||
{
|
||||
for (int layer=0; layer<MAX_LAYERS; layer++)
|
||||
{
|
||||
_uv[layer] = vertex._uv[layer];
|
||||
_validUV[layer] = vertex._validUV[layer];
|
||||
}
|
||||
}
|
||||
|
||||
void Vertex::setCoord(osg::Vec3 coord)
|
||||
void Vertex::setCoord(const osg::Vec3 coord)
|
||||
{
|
||||
_coord = coord;
|
||||
}
|
||||
|
||||
void Vertex::setColor(osg::Vec4 color)
|
||||
void Vertex::setColor(const osg::Vec4 color)
|
||||
{
|
||||
_color = color;
|
||||
_validColor = true;
|
||||
}
|
||||
|
||||
void Vertex::setNormal(osg::Vec3 normal)
|
||||
void Vertex::setNormal(const osg::Vec3 normal)
|
||||
{
|
||||
_normal = normal;
|
||||
_validNormal = true;
|
||||
}
|
||||
|
||||
void Vertex::setUV(osg::Vec2 uv)
|
||||
void Vertex::setUV(int layer, const osg::Vec2 uv)
|
||||
{
|
||||
_uv = uv;
|
||||
_validUV = true;
|
||||
if (layer>=0 && layer<MAX_LAYERS)
|
||||
{
|
||||
_uv[layer] = uv;
|
||||
_validUV[layer] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#ifndef FLT_VERTEX_H
|
||||
#define FLT_VERTEX_H 1
|
||||
|
||||
#include <vector>
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Referenced>
|
||||
|
||||
namespace flt {
|
||||
|
||||
@@ -20,23 +22,40 @@ public:
|
||||
Vertex();
|
||||
Vertex(const Vertex& vertex);
|
||||
|
||||
void setCoord(osg::Vec3 coord);
|
||||
void setColor(osg::Vec4 color);
|
||||
void setNormal(osg::Vec3 normal);
|
||||
void setUV(osg::Vec2 uv);
|
||||
void setCoord(const osg::Vec3 coord);
|
||||
void setColor(const osg::Vec4 color);
|
||||
void setNormal(const osg::Vec3 normal);
|
||||
void setUV(int layer, const osg::Vec2 uv);
|
||||
|
||||
bool validColor() const { return _validColor; }
|
||||
bool validNormal() const { return _validNormal; }
|
||||
bool validUV() const { return _validUV; }
|
||||
bool validUV(int layer) const { return layer>=0 && layer<MAX_LAYERS && _validUV[layer]; }
|
||||
|
||||
static const int MAX_LAYERS = 8;
|
||||
|
||||
osg::Vec3 _coord;
|
||||
osg::Vec4 _color;
|
||||
osg::Vec3 _normal;
|
||||
osg::Vec2 _uv;
|
||||
osg::Vec2 _uv[MAX_LAYERS];
|
||||
|
||||
bool _validColor;
|
||||
bool _validNormal;
|
||||
bool _validUV;
|
||||
bool _validUV[MAX_LAYERS];
|
||||
};
|
||||
|
||||
|
||||
class VertexList : public osg::Referenced , public std::vector<Vertex>
|
||||
{
|
||||
public:
|
||||
|
||||
VertexList() {}
|
||||
|
||||
explicit VertexList(int size) :
|
||||
std::vector<Vertex>(size) {}
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~VertexList() {}
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
||||
@@ -128,7 +128,7 @@ class VertexCT : public Record
|
||||
|
||||
Vertex vertex;
|
||||
vertex.setCoord(coord*document.unitScale());
|
||||
vertex.setUV(uv);
|
||||
vertex.setUV(0,uv);
|
||||
|
||||
// color
|
||||
if (flags & PACKED_COLOR)
|
||||
@@ -169,7 +169,7 @@ class VertexCNT : public Record
|
||||
Vertex vertex;
|
||||
vertex.setCoord(coord*document.unitScale());
|
||||
vertex.setNormal(normal);
|
||||
vertex.setUV(uv);
|
||||
vertex.setUV(0,uv);
|
||||
|
||||
// color
|
||||
if (flags & PACKED_COLOR)
|
||||
@@ -215,7 +215,7 @@ class AbsoluteVertex : public Record
|
||||
if (in().tellg() < in.getEndOfRecord())
|
||||
{
|
||||
osg::Vec2f uv = in.readVec2f();
|
||||
vertex.setUV(uv);
|
||||
vertex.setUV(0,uv);
|
||||
}
|
||||
|
||||
if (_parent.valid())
|
||||
@@ -263,7 +263,7 @@ class ShadedVertex : public Record
|
||||
if (in().tellg() < in.getEndOfRecord())
|
||||
{
|
||||
osg::Vec2f uv = in.readVec2f();
|
||||
vertex.setUV(uv);
|
||||
vertex.setUV(0,uv);
|
||||
}
|
||||
|
||||
if (_parent.valid())
|
||||
@@ -311,7 +311,7 @@ class NormalVertex : public Record
|
||||
if (in().tellg() < in.getEndOfRecord())
|
||||
{
|
||||
osg::Vec2f uv = in.readVec2f();
|
||||
vertex.setUV(uv);
|
||||
vertex.setUV(0,uv);
|
||||
}
|
||||
|
||||
if (_parent.valid())
|
||||
|
||||
Reference in New Issue
Block a user