Hello Michael,
On 11/14/2011 08:59 AM, Michael Raab wrote:
there seem to be some problems inside the geometry functions. Here are the
first (that I can reproduce easily):
it sounds like you have code to reproduce these problems, any chance you
can share it so we don't have to go and reinvent a reproducer?
1.) osg::calcFaceNormals(geo) seems to forget to clear old normals from the
index mapping, which means the number of indices grows with each call of
osg::calcFaceNormals (by the number of normals); IndexMapping size grows by 1
with each calcfaceNormals() call
can you give the attached patch a try?
2.) osg::calcVertexTangents() creates not enough tangents and binormals, e.g.
for a simple plane only 3 tangents are created...
Ok, I haven't looked at this one yet (so everyone feel free to send a
patch... ;) ). Thanks for the bug reports.
Cheers,
Carsten
Index: Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp,v
retrieving revision 1.75
diff -u -r1.75 OSGGeoFunctions.cpp
--- Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp 12 Oct 2011 08:57:24 -0000 1.75
+++ Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp 14 Nov 2011 18:09:08 -0000
@@ -754,8 +754,8 @@
OSG_SYSTEMLIB_DLLMAPPING void OSG::calcFaceNormals(GeometryPtr geo)
{
- if(geo->getPositions() == NullFC ||
- geo->getPositions()->size() == 0)
+ if(geo->getPositions() == NullFC ||
+ geo->getPositions()->size() == 0 )
{
FINFO(("Geo without positions in calcFaceNormals()\n"));
return;
@@ -765,7 +765,6 @@
GeoNormalsPtr newNormals = GeoNormals3f::create();
Vec3f normal;
- FaceIterator faceIter = geo->beginFaces();
GeoIndicesPtr oldIndex = geo->getIndices();
if(oldIndex != NullFC)
@@ -774,10 +773,32 @@
if(geo->getMFIndexMapping()->size() > 0)
{
//MULTI INDEXED
- beginEditCP(newIndex);
+ MFUInt16 &oldIndexMap = *geo->editMFIndexMapping();
+ UInt32 oldIMSize = oldIndexMap.size();
+ UInt32 newIMSize = oldIndexMap.size();
+ Int16 oldNIdx = geo->calcMappingIndex(Geometry::MapNormal);
+ Int16 newNIdx = -1;
+
+ if(oldNIdx < 0)
+ {
+ // no pre-existing normals, add new index for normals
+ newNIdx = oldIndexMap.size();
+ newIMSize = oldIMSize + 1;
+ }
+ else if(geo->getIndexMapping(oldNIdx) != Geometry::MapNormal)
+ {
+ // index for normal also indexes other property,
+ // add new index only for normals
+ newNIdx = oldIndexMap.size();
+ newIMSize = oldIMSize + 1;
+ }
+ else
+ {
+ // normals indexed with unique index, reuse it
+ newNIdx = oldNIdx;
+ }
- MFUInt16 &oldIndexMap = (*geo->editMFIndexMapping());
- UInt32 oldIMSize = oldIndexMap.size();
+ beginEditCP(newIndex);
for(UInt32 i = 0; i < oldIndex->getSize() / oldIMSize; ++i)
{
for(UInt32 k = 0; k < oldIMSize; ++k)
@@ -785,12 +806,18 @@
newIndex->push_back(oldIndex->getValue(i * oldIMSize + k));
}
- newIndex->push_back(0); //placeholder for normal index
+ if(newIMSize != oldIMSize)
+ {
+ // placeholder for new normal
+ newIndex->push_back(0);
+ }
}
+ FaceIterator faceIter = geo->beginFaces();
+ FaceIterator faceEnd = geo->endFaces ();
+
beginEditCP(newNormals);
- for(UInt32 faceCnt = 0; faceIter != geo->endFaces();
- ++faceIter, ++faceCnt)
+ for(UInt32 faceCnt = 0; faceIter != faceEnd; ++faceIter, ++faceCnt)
{
if(faceIter.getLength() == 3)
{
@@ -830,22 +857,21 @@
{
case GL_TRIANGLE_STRIP:
base = faceIter.getIndexIndex(2); //get last point's position in index field
- newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
+ newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
break;
case GL_TRIANGLE_FAN:
base = faceIter.getIndexIndex(2); //get last point's position in index field
- newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
+ newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
break;
case GL_QUAD_STRIP:
base = faceIter.getIndexIndex(3); //get last point's position in index field
- newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
+ newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
break;
default:
for(UInt32 i = 0; i < faceIter.getLength(); ++i)
{
base = faceIter.getIndexIndex(i);
- newIndex->setValue(faceCnt,
- base + (base / oldIMSize) + oldIMSize);
+ newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
}
break;
}
@@ -855,17 +881,22 @@
endEditCP(newIndex);
beginEditCP(geo);
+ geo->setNormals(newNormals);
+ geo->setIndices(newIndex);
- Int16 ni;
- ni = geo->calcMappingIndex(Geometry::MapNormal);
- if(ni != -1)
+ if(oldNIdx < 0)
{
- oldIndexMap[ni] = oldIndexMap[ni] &~Geometry::MapNormal;
+ // no pre-existing normals, add new mapping
+ oldIndexMap.push_back(Geometry::MapNormal);
+ }
+ else if(oldIMSize != newIMSize)
+ {
+ // normal index was used to index other property as well,
+ // unshare them
+ oldIndexMap[oldNIdx] &= ~Geometry::MapNormal;
+ oldIndexMap.push_back(Geometry::MapNormal);
}
- oldIndexMap.push_back(Geometry::MapNormal);
- geo->setNormals(newNormals);
- geo->setIndices(newIndex);
endEditCP(geo);
return;
}
@@ -874,7 +905,11 @@
//SINGLE INDEXED or NON INDEXED
//UInt32 pointCnt = 0;
newNormals->resize(geo->getPositions()->getSize());
- for(; faceIter != geo->endFaces(); ++faceIter)
+
+ FaceIterator faceIter = geo->beginFaces();
+ FaceIterator faceEnd = geo->endFaces ();
+
+ for(; faceIter != faceEnd; ++faceIter)
{
if(faceIter.getLength() == 3)
{
------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users