void apply(osg::Geometry& geom) { geom.setUseDisplayList(false); if (!_manualVertexAliasing) return; osg::notify(osg::NOTICE)<<"Found geometry "<<&geom<<std::endl; if (geom.getVertexArray()) { setVertexAttrib(geom, _vertexAlias, geom.getVertexArray(), false, osg::Array::BIND_PER_VERTEX); geom.setVertexArray(0); } if (geom.getNormalArray()) { setVertexAttrib(geom, _normalAlias, geom.getNormalArray(), true); geom.setNormalArray(0); } if (geom.getColorArray()) { setVertexAttrib(geom, _colorAlias, geom.getColorArray(), false); geom.setColorArray(0); } if (geom.getSecondaryColorArray()) { setVertexAttrib(geom, _secondaryColorAlias, geom.getSecondaryColorArray(), false); geom.setSecondaryColorArray(0); } if (geom.getFogCoordArray()) { // should we normalize the FogCoord array? Don't think so... setVertexAttrib(geom, _fogCoordAlias, geom.getFogCoordArray(), false); geom.setFogCoordArray(0); } unsigned int maxNumTexCoords = geom.getNumTexCoordArrays(); if (maxNumTexCoords>8) { osg::notify(osg::NOTICE)<<"Warning: Ignoring "<<maxNumTexCoords-8<<" texture coordinate arrays, only 8 are currently supported in vertex attribute conversion code."<<std::endl; maxNumTexCoords = 8; } for(unsigned int i=0; i<maxNumTexCoords; ++i) { if (geom.getTexCoordArray(i)) { setVertexAttrib(geom, _texCoordAlias[i], geom.getTexCoordArray(i), false, osg::Array::BIND_PER_VERTEX); geom.setTexCoordArray(i,0); } else { osg::notify(osg::NOTICE)<<"Found empty TexCoordArray("<<i<<")"<<std::endl; } } }
void RigGeometry::copyFrom(osg::Geometry& from) { bool copyToSelf = (this==&from); osg::Geometry& target = *this; if (!copyToSelf) target.setStateSet(from.getStateSet()); // copy over primitive sets. if (!copyToSelf) target.getPrimitiveSetList() = from.getPrimitiveSetList(); if (from.getVertexArray()) { if (!copyToSelf) target.setVertexArray(from.getVertexArray()); } if (from.getNormalArray()) { if (!copyToSelf) target.setNormalArray(from.getNormalArray()); } if (from.getColorArray()) { if (!copyToSelf) target.setColorArray(from.getColorArray()); } if (from.getSecondaryColorArray()) { if (!copyToSelf) target.setSecondaryColorArray(from.getSecondaryColorArray()); } if (from.getFogCoordArray()) { if (!copyToSelf) target.setFogCoordArray(from.getFogCoordArray()); } for(unsigned int ti=0;ti<from.getNumTexCoordArrays();++ti) { if (from.getTexCoordArray(ti)) { if (!copyToSelf) target.setTexCoordArray(ti,from.getTexCoordArray(ti)); } } osg::Geometry::ArrayList& arrayList = from.getVertexAttribArrayList(); for(unsigned int vi=0;vi< arrayList.size();++vi) { osg::Array* array = arrayList[vi].get(); if (array) { if (!copyToSelf) target.setVertexAttribArray(vi,array); } } }
VertexAttribComparitor(osg::Geometry& geometry) { add(geometry.getVertexArray()); add(geometry.getNormalArray()); add(geometry.getColorArray()); add(geometry.getSecondaryColorArray()); add(geometry.getFogCoordArray()); unsigned int i; for(i=0;i<geometry.getNumTexCoordArrays();++i) { add(geometry.getTexCoordArray(i)); } for(i=0;i<geometry.getNumVertexAttribArrays();++i) { add(geometry.getVertexAttribArray(i)); } }
void Tessellator::retessellatePolygons(osg::Geometry &geom) { #ifdef OSG_GLU_AVAILABLE // turn the contour list into primitives, a little like Tessellator does but more generally osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray()); if (!vertices || vertices->empty() || geom.getPrimitiveSetList().empty()) return; // we currently don't handle geometry which use indices... if (geom.getVertexIndices() || geom.getNormalIndices() || geom.getColorIndices() || geom.getSecondaryColorIndices() || geom.getFogCoordIndices()) return; // not even text coord indices don't handle geometry which use indices... for(unsigned int unit=0;unit<geom.getNumTexCoordArrays();++unit) { if (geom.getTexCoordIndices(unit)) return; } if (_ttype==TESS_TYPE_POLYGONS || _ttype==TESS_TYPE_DRAWABLE) _numberVerts=0; // 09.04.04 GWM reset Tessellator // the reset is needed by the flt loader which reuses a Tessellator for triangulating polygons. // as such it might be reset by other loaders/developers in future. _index=0; // reset the counter for indexed vertices _extraPrimitives = 0; if (!_numberVerts) { _numberVerts=geom.getVertexArray()->getNumElements(); // save the contours for complex (winding rule) tessellations _Contours=geom.getPrimitiveSetList(); } // now cut out vertex attributes added on any previous tessellation reduceArray(geom.getVertexArray(), _numberVerts); reduceArray(geom.getColorArray(), _numberVerts); reduceArray(geom.getNormalArray(), _numberVerts); reduceArray(geom.getFogCoordArray(), _numberVerts); for(unsigned int unit1=0;unit1<geom.getNumTexCoordArrays();++unit1) { reduceArray(geom.getTexCoordArray(unit1), _numberVerts); } // remove the existing primitives. unsigned int nprimsetoriginal= geom.getNumPrimitiveSets(); if (nprimsetoriginal) geom.removePrimitiveSet(0, nprimsetoriginal); // the main difference from osgUtil::Tessellator for Geometry sets of multiple contours is that the begin/end tessellation // occurs around the whole set of contours. if (_ttype==TESS_TYPE_GEOMETRY) { beginTessellation(); gluTessProperty(_tobj, GLU_TESS_WINDING_RULE, _wtype); gluTessProperty(_tobj, GLU_TESS_BOUNDARY_ONLY , _boundaryOnly); } // process all the contours into the Tessellator int noContours = _Contours.size(); int currentPrimitive = 0; for(int primNo=0;primNo<noContours;++primNo) { osg::ref_ptr<osg::PrimitiveSet> primitive = _Contours[primNo].get(); if (_ttype==TESS_TYPE_POLYGONS || _ttype==TESS_TYPE_DRAWABLE) { // this recovers the 'old' tessellation which just retessellates single polygons. if (primitive->getMode()==osg::PrimitiveSet::POLYGON || _ttype==TESS_TYPE_DRAWABLE) { if (primitive->getType()==osg::PrimitiveSet::DrawArrayLengthsPrimitiveType) { osg::DrawArrayLengths* drawArrayLengths = static_cast<osg::DrawArrayLengths*>(primitive.get()); unsigned int first = drawArrayLengths->getFirst(); for(osg::DrawArrayLengths::iterator itr=drawArrayLengths->begin(); itr!=drawArrayLengths->end(); ++itr) { beginTessellation(); unsigned int last = first + *itr; addContour(primitive->getMode(),first,last,vertices); first = last; endTessellation(); collectTessellation(geom, currentPrimitive); currentPrimitive++; } } else { if (primitive->getNumIndices()>3) { // April 2005 gwm only retessellate "complex" polygons beginTessellation(); addContour(primitive.get(), vertices); endTessellation(); collectTessellation(geom, currentPrimitive); currentPrimitive++; } else { // April 2005 gwm triangles don't need to be retessellated geom.addPrimitiveSet(primitive.get()); } } } else { // copy the contour primitive as it is not being tessellated geom.addPrimitiveSet(primitive.get()); } } else { if (primitive->getMode()==osg::PrimitiveSet::POLYGON || primitive->getMode()==osg::PrimitiveSet::QUADS || primitive->getMode()==osg::PrimitiveSet::TRIANGLES || primitive->getMode()==osg::PrimitiveSet::LINE_LOOP || primitive->getMode()==osg::PrimitiveSet::QUAD_STRIP || primitive->getMode()==osg::PrimitiveSet::TRIANGLE_FAN || primitive->getMode()==osg::PrimitiveSet::TRIANGLE_STRIP) { addContour(primitive.get(), vertices); } else { // copy the contour primitive as it is not being tessellated // in this case points, lines or line_strip geom.addPrimitiveSet(primitive.get()); } } } if (_ttype==TESS_TYPE_GEOMETRY) { endTessellation(); collectTessellation(geom, 0); } #endif }