Various fixes to the flt loader, and knock on changes to the osgUtil::Optimizer
to better support removal of seperate osg::Geometry instances where they share the same state and bindings.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@@ -40,12 +41,18 @@ Array* Geometry::getTexCoordArray(unsigned int unit)
|
||||
else return 0;
|
||||
}
|
||||
|
||||
const Array* Geometry::getTexCoordArray(unsigned int unit) const
|
||||
{
|
||||
if (unit<_texCoordList.size()) return _texCoordList[unit].get();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void Geometry::drawImmediateMode(State& state)
|
||||
{
|
||||
if (!_vertexArray.valid()) return;
|
||||
|
||||
// set up the vertex arrays.
|
||||
state.setVertexPointer(3,GL_FLOAT,0,_vertexArray->dataPointer());
|
||||
state.setVertexPointer(3,GL_FLOAT,0,_vertexArray->getDataPointer());
|
||||
|
||||
// set up texture coordinates.
|
||||
unsigned int i;
|
||||
@@ -53,7 +60,7 @@ void Geometry::drawImmediateMode(State& state)
|
||||
{
|
||||
Array* array = _texCoordList[i].get();
|
||||
if (array)
|
||||
state.setTexCoordPointer(i,array->dataSize(),array->dataType(),0,array->dataPointer());
|
||||
state.setTexCoordPointer(i,array->getDataSize(),array->getDataType(),0,array->getDataPointer());
|
||||
else
|
||||
state.disableTexCoordPointer(i);
|
||||
}
|
||||
@@ -96,19 +103,19 @@ void Geometry::drawImmediateMode(State& state)
|
||||
{
|
||||
case(Array::UByte4ArrayType):
|
||||
{
|
||||
colorPointer = reinterpret_cast<const unsigned char*>(_colorArray->dataPointer());
|
||||
colorPointer = reinterpret_cast<const unsigned char*>(_colorArray->getDataPointer());
|
||||
colorStride = 4;
|
||||
break;
|
||||
}
|
||||
case(Array::Vec3ArrayType):
|
||||
{
|
||||
colorPointer = reinterpret_cast<const unsigned char*>(_colorArray->dataPointer());
|
||||
colorPointer = reinterpret_cast<const unsigned char*>(_colorArray->getDataPointer());
|
||||
colorStride = 12;
|
||||
break;
|
||||
}
|
||||
case(Array::Vec4ArrayType):
|
||||
{
|
||||
colorPointer = reinterpret_cast<const unsigned char*>(_colorArray->dataPointer());
|
||||
colorPointer = reinterpret_cast<const unsigned char*>(_colorArray->getDataPointer());
|
||||
colorStride = 16;
|
||||
break;
|
||||
}
|
||||
@@ -146,7 +153,7 @@ void Geometry::drawImmediateMode(State& state)
|
||||
state.disableColorPointer();
|
||||
break;
|
||||
case(BIND_PER_VERTEX):
|
||||
if (colorPointer) state.setColorPointer(_colorArray->dataSize(),_colorArray->dataType(),0,colorPointer);
|
||||
if (colorPointer) state.setColorPointer(_colorArray->getDataSize(),_colorArray->getDataType(),0,colorPointer);
|
||||
else state.disableColorPointer();
|
||||
}
|
||||
|
||||
@@ -255,3 +262,148 @@ const bool Geometry::computeBound() const
|
||||
return _bbox.valid();
|
||||
}
|
||||
|
||||
bool Geometry::verifyBindings() const
|
||||
{
|
||||
switch(_normalBinding)
|
||||
{
|
||||
case(BIND_OFF):
|
||||
if (_normalArray.valid() && _normalArray->getNumElements()>0) return false;
|
||||
break;
|
||||
case(BIND_OVERALL):
|
||||
if (!_normalArray.valid()) return false;
|
||||
if (_normalArray->getNumElements()!=1) return false;
|
||||
break;
|
||||
case(BIND_PER_PRIMITIVE):
|
||||
if (!_normalArray.valid()) return false;
|
||||
if (_normalArray->getNumElements()!=_primitives.size()) return false;
|
||||
break;
|
||||
case(BIND_PER_VERTEX):
|
||||
if (_vertexArray.valid())
|
||||
{
|
||||
if (!_normalArray.valid()) return false;
|
||||
if (_normalArray->getNumElements()!=_vertexArray->getNumElements()) return false;
|
||||
}
|
||||
else if (_normalArray.valid() && _normalArray->getNumElements()>0) return false;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_colorBinding)
|
||||
{
|
||||
case(BIND_OFF):
|
||||
if (_colorArray.valid() && _colorArray->getNumElements()>0) return false;
|
||||
break;
|
||||
case(BIND_OVERALL):
|
||||
if (!_colorArray.valid()) return false;
|
||||
if (_colorArray->getNumElements()!=1) return false;
|
||||
break;
|
||||
case(BIND_PER_PRIMITIVE):
|
||||
if (!_colorArray.valid()) return false;
|
||||
if (_colorArray->getNumElements()!=_primitives.size()) return false;
|
||||
break;
|
||||
case(BIND_PER_VERTEX):
|
||||
if (_vertexArray.valid())
|
||||
{
|
||||
if (!_colorArray.valid()) return false;
|
||||
if (_colorArray->getNumElements()!=_vertexArray->getNumElements()) return false;
|
||||
}
|
||||
else if (_colorArray.valid() && _colorArray->getNumElements()>0) return false;
|
||||
break;
|
||||
}
|
||||
|
||||
for(TexCoordArrayList::const_iterator itr=_texCoordList.begin();
|
||||
itr!=_texCoordList.end();
|
||||
++itr)
|
||||
{
|
||||
const Array* array = itr->get();
|
||||
if (_vertexArray.valid())
|
||||
{
|
||||
if (array && array->getNumElements()!=_vertexArray->getNumElements()) return false;
|
||||
}
|
||||
else if (array && array->getNumElements()>0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Geometry::computeCorrectBindingsAndArraySizes()
|
||||
{
|
||||
if (verifyBindings()) return;
|
||||
|
||||
if (!_vertexArray.valid() || _vertexArray->empty())
|
||||
{
|
||||
// no vertex array so switch everything off.
|
||||
|
||||
_vertexArray = 0;
|
||||
|
||||
_colorArray = 0;
|
||||
_colorBinding = BIND_OFF;
|
||||
|
||||
_normalArray = 0;
|
||||
_normalBinding = BIND_OFF;
|
||||
|
||||
_texCoordList.clear();
|
||||
|
||||
notify(INFO)<<"Info: remove redundent attribute arrays from empty osg::Geometry"<<std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch(_normalBinding)
|
||||
{
|
||||
case(BIND_OFF):
|
||||
if (_normalArray.valid()) _normalArray = 0;
|
||||
break;
|
||||
case(BIND_OVERALL):
|
||||
if (!_normalArray.valid())
|
||||
{
|
||||
_normalBinding = BIND_OFF;
|
||||
}
|
||||
else if (_normalArray->getNumElements()==0)
|
||||
{
|
||||
_normalArray = 0;
|
||||
_normalBinding = BIND_OFF;
|
||||
}
|
||||
else if (_normalArray->getNumElements()>1)
|
||||
{
|
||||
// trim the array down to 1 element long.
|
||||
_normalArray->erase(_normalArray->begin()+1,_normalArray->end());
|
||||
}
|
||||
break;
|
||||
case(BIND_PER_PRIMITIVE):
|
||||
if (!_normalArray.valid())
|
||||
{
|
||||
_normalBinding = BIND_OFF;
|
||||
}
|
||||
else if (_normalArray->getNumElements()<_primitives.size())
|
||||
{
|
||||
_normalArray = 0;
|
||||
_normalBinding = BIND_OFF;
|
||||
}
|
||||
else if (_normalArray->getNumElements()>_primitives.size())
|
||||
{
|
||||
// trim the array down to size of the number of primitives.
|
||||
_normalArray->erase(_normalArray->begin()+_primitives.size(),_normalArray->end());
|
||||
}
|
||||
break;
|
||||
case(BIND_PER_VERTEX):
|
||||
if (!_normalArray.valid())
|
||||
{
|
||||
_normalBinding = BIND_OFF;
|
||||
}
|
||||
else if (_normalArray->getNumElements()<_vertexArray->getNumElements())
|
||||
{
|
||||
_normalArray = 0;
|
||||
_normalBinding = BIND_OFF;
|
||||
}
|
||||
else if (_normalArray->getNumElements()>_vertexArray->getNumElements())
|
||||
{
|
||||
// trim the array down to size of the number of primitives.
|
||||
_normalArray->erase(_normalArray->begin()+_vertexArray->getNumElements(),_normalArray->end());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO colours and tex coords.
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user