that they arn't created on the stack inappropriately. Split the implemention of Matrix up so that it is a simple no referenced counted class and can be safefly created on the stack. To support referenced counting a seperate subclass now exists, this is RefMatrix which inherits from both Matrix and Object.
1050 lines
30 KiB
C++
1050 lines
30 KiB
C++
#include <osg/Geometry>
|
|
#include <osg/Notify>
|
|
|
|
#include <osgDB/Registry>
|
|
#include <osgDB/Input>
|
|
#include <osgDB/ParameterOutput>
|
|
|
|
using namespace osg;
|
|
using namespace osgDB;
|
|
|
|
// forward declare functions to use later.
|
|
bool Geometry_readLocalData(Object& obj, Input& fr);
|
|
bool Geometry_writeLocalData(const Object& obj, Output& fw);
|
|
|
|
bool Geometry_matchBindingTypeStr(const char* str,Geometry::AttributeBinding& mode);
|
|
const char* Geometry_getBindingTypeStr(Geometry::AttributeBinding mode);
|
|
|
|
bool Geometry_matchPrimitiveModeStr(const char* str,GLenum& mode);
|
|
const char* Geometry_getPrimitiveModeStr(GLenum mode);
|
|
|
|
Array* Array_readLocalData(Input& fr);
|
|
|
|
bool Primitive_readLocalData(Input& fr,osg::Geometry& geom);
|
|
|
|
//register the read and write functions with the osgDB::Registry.
|
|
RegisterDotOsgWrapperProxy g_GeometryFuncProxy
|
|
(
|
|
new osg::Geometry,
|
|
"Geometry",
|
|
"Object Drawable Geometry",
|
|
&Geometry_readLocalData,
|
|
&Geometry_writeLocalData,
|
|
DotOsgWrapper::READ_AND_WRITE
|
|
);
|
|
|
|
bool Geometry_readLocalData(Object& obj, Input& fr)
|
|
{
|
|
bool iteratorAdvanced = false;
|
|
|
|
Geometry& geom = static_cast<Geometry&>(obj);
|
|
|
|
if (fr.matchSequence("Primitives %i {") || fr.matchSequence("PrimitiveSets %i {") )
|
|
{
|
|
int entry = fr[1].getNoNestedBrackets();
|
|
|
|
int capacity;
|
|
fr[1].getInt(capacity);
|
|
|
|
Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList();
|
|
if (capacity>0) primitives.reserve(capacity);
|
|
|
|
|
|
fr += 3;
|
|
|
|
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
if (!Primitive_readLocalData(fr,geom)) fr.advanceOverCurrentFieldOrBlock();
|
|
}
|
|
|
|
++fr;
|
|
|
|
iteratorAdvanced = true;
|
|
|
|
}
|
|
|
|
if (fr[0].matchWord("VertexArray"))
|
|
{
|
|
if (fr.matchSequence("VertexArray %i {"))
|
|
{
|
|
|
|
int entry = fr[0].getNoNestedBrackets();
|
|
|
|
int capacity;
|
|
fr[1].getInt(capacity);
|
|
|
|
Vec3Array* vertices = new Vec3Array;
|
|
vertices->reserve(capacity);
|
|
|
|
fr += 3;
|
|
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
Vec3 v;
|
|
if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()))
|
|
{
|
|
fr += 3;
|
|
vertices->push_back(v);
|
|
}
|
|
else
|
|
{
|
|
++fr;
|
|
}
|
|
}
|
|
|
|
geom.setVertexArray(vertices);
|
|
|
|
iteratorAdvanced = true;
|
|
++fr;
|
|
|
|
}
|
|
else
|
|
{
|
|
// post 0.9.3 releases.
|
|
++fr;
|
|
Vec3Array* vertices = dynamic_cast<Vec3Array*>(Array_readLocalData(fr));
|
|
if (vertices)
|
|
{
|
|
geom.setVertexArray(vertices);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
}
|
|
|
|
if (fr[0].matchWord("VertexIndices"))
|
|
{
|
|
++fr;
|
|
|
|
IndexArray* indices = dynamic_cast<IndexArray*>(Array_readLocalData(fr));
|
|
if (indices)
|
|
{
|
|
geom.setVertexIndices(indices);
|
|
}
|
|
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
|
|
Geometry::AttributeBinding normalBinding=Geometry::BIND_OFF;
|
|
if (fr[0].matchWord("NormalBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),normalBinding))
|
|
{
|
|
geom.setNormalBinding(normalBinding);
|
|
fr+=2;
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (fr[0].matchWord("NormalArray"))
|
|
{
|
|
if (fr.matchSequence("NormalArray %i {"))
|
|
{
|
|
// pre 0.9.3 releases..
|
|
int entry = fr[0].getNoNestedBrackets();
|
|
|
|
int capacity;
|
|
fr[1].getInt(capacity);
|
|
|
|
Vec3Array* normals = new Vec3Array;
|
|
normals->reserve(capacity);
|
|
|
|
fr += 3;
|
|
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
Vec3 v;
|
|
if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()))
|
|
{
|
|
fr += 3;
|
|
normals->push_back(v);
|
|
}
|
|
else
|
|
{
|
|
++fr;
|
|
}
|
|
}
|
|
|
|
geom.setNormalArray(normals);
|
|
|
|
iteratorAdvanced = true;
|
|
++fr;
|
|
}
|
|
else
|
|
{
|
|
// post 0.9.3 releases.
|
|
++fr;
|
|
Vec3Array* normals = dynamic_cast<Vec3Array*>(Array_readLocalData(fr));
|
|
if (normals)
|
|
{
|
|
geom.setNormalArray(normals);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
}
|
|
if (fr[0].matchWord("NormalIndices"))
|
|
{
|
|
++fr;
|
|
IndexArray* indices = dynamic_cast<IndexArray*>(Array_readLocalData(fr));
|
|
if (indices)
|
|
{
|
|
geom.setNormalIndices(indices);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
Geometry::AttributeBinding colorBinding=Geometry::BIND_OFF;
|
|
if (fr[0].matchWord("ColorBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),colorBinding))
|
|
{
|
|
geom.setColorBinding(colorBinding);
|
|
fr+=2;
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (fr[0].matchWord("ColorArray"))
|
|
{
|
|
++fr;
|
|
Array* colors = Array_readLocalData(fr);
|
|
if (colors)
|
|
{
|
|
geom.setColorArray(colors);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (fr[0].matchWord("ColorIndices"))
|
|
{
|
|
++fr;
|
|
IndexArray* indices = dynamic_cast<IndexArray*>(Array_readLocalData(fr));
|
|
if (indices)
|
|
{
|
|
geom.setColorIndices(indices);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
|
|
Geometry::AttributeBinding secondaryColorBinding=Geometry::BIND_OFF;
|
|
if (fr[0].matchWord("SecondaryColorBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),secondaryColorBinding))
|
|
{
|
|
geom.setSecondaryColorBinding(secondaryColorBinding);
|
|
fr+=2;
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (fr[0].matchWord("SecondaryColorArray"))
|
|
{
|
|
++fr;
|
|
Array* colors = Array_readLocalData(fr);
|
|
if (colors)
|
|
{
|
|
geom.setSecondaryColorArray(colors);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (fr[0].matchWord("SecondaryColorIndices"))
|
|
{
|
|
++fr;
|
|
IndexArray* indices = dynamic_cast<IndexArray*>(Array_readLocalData(fr));
|
|
if (indices)
|
|
{
|
|
geom.setSecondaryColorIndices(indices);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
|
|
Geometry::AttributeBinding fogCoordBinding=Geometry::BIND_OFF;
|
|
if (fr[0].matchWord("FogCoordBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),fogCoordBinding))
|
|
{
|
|
geom.setFogCoordBinding(fogCoordBinding);
|
|
fr+=2;
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (fr[0].matchWord("FogCoordArray"))
|
|
{
|
|
++fr;
|
|
Array* fogcoords = Array_readLocalData(fr);
|
|
if (fogcoords)
|
|
{
|
|
geom.setFogCoordArray(fogcoords);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (fr[0].matchWord("FogCoordIndices"))
|
|
{
|
|
++fr;
|
|
IndexArray* indices = dynamic_cast<IndexArray*>(Array_readLocalData(fr));
|
|
if (indices)
|
|
{
|
|
geom.setFogCoordIndices(indices);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
|
|
if (fr.matchSequence("TexCoordArray %i"))
|
|
{
|
|
int unit=0;
|
|
fr[1].getInt(unit);
|
|
|
|
fr+=2;
|
|
Array* texcoords = Array_readLocalData(fr);
|
|
if (texcoords)
|
|
{
|
|
geom.setTexCoordArray(unit,texcoords);
|
|
}
|
|
iteratorAdvanced = true;
|
|
|
|
}
|
|
|
|
if (fr.matchSequence("TexCoordIndices %i"))
|
|
{
|
|
int unit=0;
|
|
fr[1].getInt(unit);
|
|
|
|
fr+=2;
|
|
IndexArray* indices = dynamic_cast<IndexArray*>(Array_readLocalData(fr));
|
|
if (indices)
|
|
{
|
|
geom.setTexCoordIndices(unit,indices);
|
|
}
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
return iteratorAdvanced;
|
|
}
|
|
|
|
|
|
Array* Array_readLocalData(Input& fr)
|
|
{
|
|
if (fr[0].matchWord("Use"))
|
|
{
|
|
if (fr[1].isString())
|
|
{
|
|
Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
|
|
if (obj)
|
|
{
|
|
fr+=2;
|
|
return dynamic_cast<Array*>(obj);
|
|
}
|
|
}
|
|
|
|
osg::notify(osg::WARN)<<"Warning: invalid uniqueID found in file."<<std::endl;
|
|
return NULL;
|
|
}
|
|
|
|
std::string uniqueID;
|
|
if (fr[0].matchWord("UniqueID") && fr[1].isString())
|
|
{
|
|
uniqueID = fr[1].getStr();
|
|
fr += 2;
|
|
}
|
|
|
|
|
|
int entry = fr[0].getNoNestedBrackets();
|
|
|
|
const char* arrayName = fr[0].getStr();
|
|
|
|
unsigned int capacity = 0;
|
|
fr[1].getUInt(capacity);
|
|
++fr;
|
|
|
|
fr += 2;
|
|
|
|
|
|
Array* return_array = 0;
|
|
|
|
if (strcmp(arrayName,"ByteArray")==0)
|
|
{
|
|
ByteArray* array = new ByteArray;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
int int_value;
|
|
if (fr[0].getInt(int_value))
|
|
{
|
|
++fr;
|
|
array->push_back(int_value);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"ShortArray")==0)
|
|
{
|
|
ShortArray* array = new ShortArray;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
int int_value;
|
|
if (fr[0].getInt(int_value))
|
|
{
|
|
++fr;
|
|
array->push_back(int_value);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"IntArray")==0)
|
|
{
|
|
IntArray* array = new IntArray;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
int int_value;
|
|
if (fr[0].getInt(int_value))
|
|
{
|
|
++fr;
|
|
array->push_back(int_value);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"UByteArray")==0)
|
|
{
|
|
UByteArray* array = new UByteArray;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int uint_value;
|
|
if (fr[0].getUInt(uint_value))
|
|
{
|
|
++fr;
|
|
array->push_back(uint_value);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"UShortArray")==0)
|
|
{
|
|
UShortArray* array = new UShortArray;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int uint_value;
|
|
if (fr[0].getUInt(uint_value))
|
|
{
|
|
++fr;
|
|
array->push_back(uint_value);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"UIntArray")==0)
|
|
{
|
|
UIntArray* array = new UIntArray;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int uint_value;
|
|
if (fr[0].getUInt(uint_value))
|
|
{
|
|
++fr;
|
|
array->push_back(uint_value);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"UByte4Array")==0)
|
|
{
|
|
UByte4Array* array = new UByte4Array;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int r,g,b,a;
|
|
if (fr[0].getUInt(r) &&
|
|
fr[1].getUInt(g) &&
|
|
fr[2].getUInt(b) &&
|
|
fr[3].getUInt(a))
|
|
{
|
|
++fr;
|
|
array->push_back(osg::UByte4(r,g,b,a));
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"FloatArray")==0)
|
|
{
|
|
FloatArray* array = new FloatArray;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
float float_value;
|
|
if (fr[0].getFloat(float_value))
|
|
{
|
|
++fr;
|
|
array->push_back(float_value);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"Vec2Array")==0)
|
|
{
|
|
Vec2Array* array = new Vec2Array;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
Vec2 v;
|
|
if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()))
|
|
{
|
|
fr += 2;
|
|
array->push_back(v);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"Vec3Array")==0)
|
|
{
|
|
Vec3Array* array = new Vec3Array;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
Vec3 v;
|
|
if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()))
|
|
{
|
|
fr += 3;
|
|
array->push_back(v);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
else if (strcmp(arrayName,"Vec4Array")==0)
|
|
{
|
|
Vec4Array* array = new Vec4Array;
|
|
array->reserve(capacity);
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
Vec4 v;
|
|
if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()) && fr[3].getFloat(v.w()))
|
|
{
|
|
fr += 4;
|
|
array->push_back(v);
|
|
}
|
|
else ++fr;
|
|
}
|
|
++fr;
|
|
return_array = array;
|
|
}
|
|
|
|
if (return_array)
|
|
{
|
|
if (!uniqueID.empty()) fr.regisiterUniqueIDForObject(uniqueID.c_str(),return_array);
|
|
}
|
|
|
|
return return_array;
|
|
}
|
|
|
|
|
|
bool Array_writeLocalData(const Array& array,Output& fw)
|
|
{
|
|
if (array.referenceCount()>1)
|
|
{
|
|
std::string uniqueID;
|
|
if (fw.getUniqueIDForObject(&array,uniqueID))
|
|
{
|
|
fw << "Use " << uniqueID << std::endl;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
std::string uniqueID;
|
|
fw.createUniqueIDForObject(&array,uniqueID);
|
|
fw.registerUniqueIDForObject(&array,uniqueID);
|
|
fw << "UniqueID " << uniqueID << " ";
|
|
}
|
|
}
|
|
|
|
|
|
switch(array.getType())
|
|
{
|
|
case(Array::ByteArrayType):
|
|
{
|
|
const ByteArray& carray = static_cast<const ByteArray&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArrayAsInts(fw,carray.begin(),carray.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::ShortArrayType):
|
|
{
|
|
const ShortArray& carray = static_cast<const ShortArray&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArray(fw,carray.begin(),carray.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::IntArrayType):
|
|
{
|
|
const IntArray& carray = static_cast<const IntArray&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArray(fw,carray.begin(),carray.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::UByteArrayType):
|
|
{
|
|
const UByteArray& carray = static_cast<const UByteArray&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArrayAsInts(fw,carray.begin(),carray.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::UShortArrayType):
|
|
{
|
|
const UShortArray& carray = static_cast<const UShortArray&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArray(fw,carray.begin(),carray.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::UIntArrayType):
|
|
{
|
|
const UIntArray& carray = static_cast<const UIntArray&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<" ";
|
|
writeArray(fw,carray.begin(),carray.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::UByte4ArrayType):
|
|
{
|
|
const UByte4Array& carray = static_cast<const UByte4Array&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<" ";
|
|
writeArray(fw,carray.begin(),carray.end(),1);
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::FloatArrayType):
|
|
{
|
|
const FloatArray& carray = static_cast<const FloatArray&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArray(fw,carray.begin(),carray.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::Vec2ArrayType):
|
|
{
|
|
const Vec2Array& carray = static_cast<const Vec2Array&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArray(fw,carray.begin(),carray.end(),1);
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::Vec3ArrayType):
|
|
{
|
|
const Vec3Array& carray = static_cast<const Vec3Array&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArray(fw,carray.begin(),carray.end(),1);
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::Vec4ArrayType):
|
|
{
|
|
const Vec4Array& carray = static_cast<const Vec4Array&>(array);
|
|
fw<<array.className()<<" "<<carray.size()<<std::endl;
|
|
writeArray(fw,carray.begin(),carray.end(),1);
|
|
return true;
|
|
}
|
|
break;
|
|
case(Array::ArrayType):
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
|
{
|
|
bool iteratorAdvanced = false;
|
|
if (fr.matchSequence("DrawArrays %w %i %i"))
|
|
{
|
|
|
|
GLenum mode;
|
|
Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode);
|
|
|
|
int first;
|
|
fr[2].getInt(first);
|
|
|
|
int count;
|
|
fr[3].getInt(count);
|
|
|
|
geom.addPrimitiveSet(new DrawArrays(mode,first,count));
|
|
|
|
fr += 4;
|
|
|
|
iteratorAdvanced = true;
|
|
|
|
}
|
|
else if (fr.matchSequence("DrawArrayLengths %w %i %i {"))
|
|
{
|
|
int entry = fr[1].getNoNestedBrackets();
|
|
|
|
GLenum mode;
|
|
Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode);
|
|
|
|
int first;
|
|
fr[2].getInt(first);
|
|
|
|
int capacity;
|
|
fr[3].getInt(capacity);
|
|
|
|
fr += 5;
|
|
|
|
DrawArrayLengths* prim = new DrawArrayLengths;
|
|
prim->setMode(mode);
|
|
prim->setFirst(first);
|
|
prim->reserve(capacity);
|
|
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int i;
|
|
if (fr[0].getUInt(i))
|
|
{
|
|
prim->push_back(i);
|
|
++fr;
|
|
}
|
|
}
|
|
++fr;
|
|
|
|
geom.addPrimitiveSet(prim);
|
|
|
|
iteratorAdvanced = true;
|
|
}
|
|
else if (fr.matchSequence("DrawElementsUByte %w %i {"))
|
|
{
|
|
int entry = fr[1].getNoNestedBrackets();
|
|
|
|
GLenum mode;
|
|
Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode);
|
|
|
|
int capacity;
|
|
fr[2].getInt(capacity);
|
|
|
|
fr += 4;
|
|
|
|
DrawElementsUByte* prim = new DrawElementsUByte;
|
|
prim->setMode(mode);
|
|
prim->reserve(capacity);
|
|
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int i;
|
|
if (fr[0].getUInt(i))
|
|
{
|
|
prim->push_back(i);
|
|
++fr;
|
|
}
|
|
}
|
|
++fr;
|
|
|
|
geom.addPrimitiveSet(prim);
|
|
|
|
iteratorAdvanced = true;
|
|
}
|
|
else if (fr.matchSequence("DrawElementsUShort %w %i {"))
|
|
{
|
|
int entry = fr[1].getNoNestedBrackets();
|
|
|
|
GLenum mode;
|
|
Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode);
|
|
|
|
int capacity;
|
|
fr[2].getInt(capacity);
|
|
|
|
fr += 4;
|
|
|
|
DrawElementsUShort* prim = new DrawElementsUShort;
|
|
prim->setMode(mode);
|
|
prim->reserve(capacity);
|
|
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int i;
|
|
if (fr[0].getUInt(i))
|
|
{
|
|
prim->push_back(i);
|
|
++fr;
|
|
}
|
|
}
|
|
++fr;
|
|
|
|
geom.addPrimitiveSet(prim);
|
|
|
|
iteratorAdvanced = true;
|
|
}
|
|
else if (fr.matchSequence("DrawElementsUInt %w %i {"))
|
|
{
|
|
int entry = fr[1].getNoNestedBrackets();
|
|
|
|
GLenum mode;
|
|
Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode);
|
|
|
|
int capacity;
|
|
fr[2].getInt(capacity);
|
|
|
|
fr += 4;
|
|
|
|
DrawElementsUInt* prim = new DrawElementsUInt;
|
|
prim->setMode(mode);
|
|
prim->reserve(capacity);
|
|
|
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
|
{
|
|
unsigned int i;
|
|
if (fr[0].getUInt(i))
|
|
{
|
|
prim->push_back(i);
|
|
++fr;
|
|
}
|
|
}
|
|
++fr;
|
|
|
|
geom.addPrimitiveSet(prim);
|
|
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
return iteratorAdvanced;
|
|
}
|
|
|
|
bool Primitive_writeLocalData(const PrimitiveSet& prim,Output& fw)
|
|
{
|
|
|
|
switch(prim.getType())
|
|
{
|
|
case(PrimitiveSet::DrawArraysPrimitiveType):
|
|
{
|
|
const DrawArrays& cprim = static_cast<const DrawArrays&>(prim);
|
|
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.getFirst()<<" "<<cprim.getCount()<<std::endl;
|
|
return true;
|
|
}
|
|
break;
|
|
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
|
|
{
|
|
const DrawArrayLengths& cprim = static_cast<const DrawArrayLengths&>(prim);
|
|
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.getFirst()<<" "<<cprim.size()<<std::endl;
|
|
writeArray(fw,cprim.begin(),cprim.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(PrimitiveSet::DrawElementsUBytePrimitiveType):
|
|
{
|
|
const DrawElementsUByte& cprim = static_cast<const DrawElementsUByte&>(prim);
|
|
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
|
|
writeArrayAsInts(fw,cprim.begin(),cprim.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(PrimitiveSet::DrawElementsUShortPrimitiveType):
|
|
{
|
|
const DrawElementsUShort& cprim = static_cast<const DrawElementsUShort&>(prim);
|
|
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
|
|
writeArray(fw,cprim.begin(),cprim.end());
|
|
return true;
|
|
}
|
|
break;
|
|
case(PrimitiveSet::DrawElementsUIntPrimitiveType):
|
|
{
|
|
const DrawElementsUInt& cprim = static_cast<const DrawElementsUInt&>(prim);
|
|
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
|
|
writeArray(fw,cprim.begin(),cprim.end());
|
|
return true;
|
|
}
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool Geometry_writeLocalData(const Object& obj, Output& fw)
|
|
{
|
|
const Geometry& geom = static_cast<const Geometry&>(obj);
|
|
|
|
const Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList();
|
|
if (!primitives.empty())
|
|
{
|
|
fw.indent() << "PrimitiveSets "<<primitives.size()<<std::endl;
|
|
fw.indent() << "{"<<std::endl;
|
|
fw.moveIn();
|
|
for(Geometry::PrimitiveSetList::const_iterator itr=primitives.begin();
|
|
itr!=primitives.end();
|
|
++itr)
|
|
{
|
|
fw.indent();
|
|
Primitive_writeLocalData(**itr,fw);
|
|
}
|
|
fw.moveOut();
|
|
fw.indent() << "}"<<std::endl;
|
|
}
|
|
|
|
if (geom.getVertexArray())
|
|
{
|
|
// const Vec3Array& vertices = *geom.getVertexArray();
|
|
// fw.indent()<<"VertexArray "<<vertices.size()<<std::endl;
|
|
// Array_writeLocalData(fw,vertices.begin(),vertices.end(),1);
|
|
|
|
fw.indent()<<"VertexArray ";
|
|
Array_writeLocalData(*geom.getVertexArray(),fw);
|
|
|
|
}
|
|
if (geom.getVertexIndices())
|
|
{
|
|
fw.indent()<<"VertexIndices ";
|
|
Array_writeLocalData(*geom.getVertexIndices(),fw);
|
|
}
|
|
|
|
if (geom.getNormalArray())
|
|
{
|
|
|
|
fw.indent()<<"NormalBinding "<<Geometry_getBindingTypeStr(geom.getNormalBinding())<<std::endl;
|
|
|
|
// const Vec3Array& normals = *geom.getNormalArray();
|
|
// fw.indent()<<"NormalArray "<<normals.size()<<std::endl;
|
|
// Array_writeLocalData(fw,normals.begin(),normals.end(),1);
|
|
|
|
fw.indent()<<"NormalArray ";
|
|
Array_writeLocalData(*geom.getNormalArray(),fw);
|
|
|
|
}
|
|
if (geom.getNormalIndices())
|
|
{
|
|
fw.indent()<<"NormalIndices ";
|
|
Array_writeLocalData(*geom.getNormalIndices(),fw);
|
|
}
|
|
|
|
if (geom.getColorArray())
|
|
{
|
|
fw.indent()<<"ColorBinding "<<Geometry_getBindingTypeStr(geom.getColorBinding())<<std::endl;
|
|
fw.indent()<<"ColorArray ";
|
|
Array_writeLocalData(*geom.getColorArray(),fw);
|
|
}
|
|
if (geom.getColorIndices())
|
|
{
|
|
fw.indent()<<"ColorIndices ";
|
|
Array_writeLocalData(*geom.getColorIndices(),fw);
|
|
}
|
|
|
|
if (geom.getSecondaryColorArray())
|
|
{
|
|
fw.indent()<<"SecondaryColorBinding "<<Geometry_getBindingTypeStr(geom.getSecondaryColorBinding())<<std::endl;
|
|
fw.indent()<<"SecondaryColorArray ";
|
|
Array_writeLocalData(*geom.getSecondaryColorArray(),fw);
|
|
}
|
|
if (geom.getSecondaryColorIndices())
|
|
{
|
|
fw.indent()<<"SecondayColorIndices ";
|
|
Array_writeLocalData(*geom.getSecondaryColorIndices(),fw);
|
|
}
|
|
|
|
if (geom.getFogCoordArray())
|
|
{
|
|
fw.indent()<<"FogCoordBinding "<<Geometry_getBindingTypeStr(geom.getFogCoordBinding())<<std::endl;
|
|
fw.indent()<<"FogCoordArray ";
|
|
Array_writeLocalData(*geom.getFogCoordArray(),fw);
|
|
}
|
|
if (geom.getFogCoordIndices())
|
|
{
|
|
fw.indent()<<"FogCoordIndices ";
|
|
Array_writeLocalData(*geom.getFogCoordIndices(),fw);
|
|
}
|
|
|
|
const Geometry::TexCoordArrayList& tcal=geom.getTexCoordArrayList();
|
|
for(unsigned int i=0;i<tcal.size();++i)
|
|
{
|
|
if (tcal[i].first.valid())
|
|
{
|
|
fw.indent()<<"TexCoordArray "<<i<<" ";
|
|
Array_writeLocalData(*(tcal[i].first),fw);
|
|
}
|
|
if (tcal[i].second.valid())
|
|
{
|
|
fw.indent()<<"TexCoordIndices "<<i<<" ";
|
|
Array_writeLocalData(*(tcal[i].second),fw);
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Geometry_matchBindingTypeStr(const char* str,Geometry::AttributeBinding& mode)
|
|
{
|
|
if (strcmp(str,"OFF")==0) mode = Geometry::BIND_OFF;
|
|
else if (strcmp(str,"OVERALL")==0) mode = Geometry::BIND_OVERALL;
|
|
else if (strcmp(str,"PER_PRIMITIVE")==0) mode = Geometry::BIND_PER_PRIMITIVE;
|
|
else if (strcmp(str,"PER_PRIMITIVE_SET")==0) mode = Geometry::BIND_PER_PRIMITIVE_SET;
|
|
else if (strcmp(str,"PER_VERTEX")==0) mode = Geometry::BIND_PER_VERTEX;
|
|
else return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
const char* Geometry_getBindingTypeStr(Geometry::AttributeBinding mode)
|
|
{
|
|
switch(mode)
|
|
{
|
|
case (Geometry::BIND_OVERALL) : return "OVERALL";
|
|
case (Geometry::BIND_PER_PRIMITIVE) : return "PER_PRIMITIVE";
|
|
case (Geometry::BIND_PER_PRIMITIVE_SET) : return "PER_PRIMITIVE_SET";
|
|
case (Geometry::BIND_PER_VERTEX) : return "PER_VERTEX";
|
|
case (Geometry::BIND_OFF) :
|
|
default : return "OFF";
|
|
}
|
|
}
|
|
|
|
bool Geometry_matchPrimitiveModeStr(const char* str,GLenum& mode)
|
|
{
|
|
if (strcmp(str,"POINTS")==0) mode = PrimitiveSet::POINTS;
|
|
else if (strcmp(str,"LINES")==0) mode = PrimitiveSet::LINES;
|
|
else if (strcmp(str,"LINE_STRIP")==0) mode = PrimitiveSet::LINE_STRIP;
|
|
else if (strcmp(str,"LINE_LOOP")==0) mode = PrimitiveSet::LINE_LOOP;
|
|
else if (strcmp(str,"TRIANGLES")==0) mode = PrimitiveSet::TRIANGLES;
|
|
else if (strcmp(str,"TRIANGLE_STRIP")==0) mode = PrimitiveSet::TRIANGLE_STRIP;
|
|
else if (strcmp(str,"TRIANGLE_FAN")==0) mode = PrimitiveSet::TRIANGLE_FAN;
|
|
else if (strcmp(str,"QUADS")==0) mode = PrimitiveSet::QUADS;
|
|
else if (strcmp(str,"QUAD_STRIP")==0) mode = PrimitiveSet::QUAD_STRIP;
|
|
else if (strcmp(str,"POLYGON")==0) mode = PrimitiveSet::POLYGON;
|
|
else return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
const char* Geometry_getPrimitiveModeStr(GLenum mode)
|
|
{
|
|
switch(mode)
|
|
{
|
|
case (PrimitiveSet::POINTS) : return "POINTS";
|
|
case (PrimitiveSet::LINES) : return "LINES";
|
|
case (PrimitiveSet::LINE_STRIP) : return "LINE_STRIP";
|
|
case (PrimitiveSet::LINE_LOOP) : return "LINE_LOOP";
|
|
case (PrimitiveSet::TRIANGLES) : return "TRIANGLES";
|
|
case (PrimitiveSet::TRIANGLE_STRIP) : return "TRIANGLE_STRIP";
|
|
case (PrimitiveSet::TRIANGLE_FAN) : return "TRIANGLE_FAN";
|
|
case (PrimitiveSet::QUADS) : return "QUADS";
|
|
case (PrimitiveSet::QUAD_STRIP) : return "QUAD_STRIP";
|
|
case (PrimitiveSet::POLYGON) : return "POLYGON";
|
|
default : return "UnknownPrimitveType";
|
|
}
|
|
}
|