bool InstancesManagerImpl::_initSkinning(osg::Geometry& geom, const image_data& id ) { osg::Geometry& source = geom; osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray()); if (!positionSrc) { OSG_WARN << "InstancedAnimationManager no vertex array in the geometry " << geom.getName() << std::endl; return false; } osg::ref_ptr<osg::Program> cSkinningProg = creators::createProgram("skininst2").program; cSkinningProg->setName("SkinningShader"); const int attribIndex = cAttribSkinningBaseIndex; int nbAttribs = id.bonesWeights.size(); for (int i = 0; i < nbAttribs; i++) { osg::ref_ptr<osg::Vec4Array> array = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); const image_data::weights_t& w = id.bonesWeights[i]; for (unsigned j = 0; j < w.size(); j+=id.divisor) { array->push_back(osg::Vec4(w.at(j),w.at(j+1),w.at(j+2),w.at(j+3))); } std::stringstream ss; ss << "boneWeight" << i; cSkinningProg->addBindAttribLocation(ss.str(), attribIndex + i); geom.setVertexAttribArray(attribIndex + i, array); OSG_INFO << "set vertex attrib " << ss.str() << std::endl; } osg::ref_ptr<osg::StateSet> ss = geom.getOrCreateStateSet(); ss->addUniform(new osg::Uniform("nbBonesPerVertex", id.bonesPerVertex)); ss->setAttributeAndModes(cSkinningProg.get()); return true; }
void GeometryValidator::apply(osg::Geometry& geom) { if ( geom.getVertexArray() == 0L ) { OE_NOTICE << LC << "NULL vertex array!!\n"; return; } unsigned numVerts = geom.getVertexArray()->getNumElements(); if ( numVerts == 0 ) { OE_NOTICE << LC << "No verts!! name=" << geom.getName() << "\n"; return; } std::set<osg::BufferObject*> _vbos; osg::Geometry::ArrayList arrays; geom.getArrayList(arrays); for(unsigned i=0; i<arrays.size(); ++i) { osg::Array* a = arrays[i].get(); if ( a ) { if ( a->getBinding() == a->BIND_OVERALL && a->getNumElements() != 1 ) { OE_NOTICE << LC << "Found an array with BIND_OVERALL and size <> 1\n"; } else if ( a->getBinding() == a->BIND_PER_VERTEX && a->getNumElements() != numVerts ) { OE_NOTICE << LC << "Found BIND_PER_VERTEX with wrong number of elements (expecting " << numVerts << "; found " << a->getNumElements() << ")\n"; } _vbos.insert( a->getVertexBufferObject() ); } else { OE_NOTICE << LC << "Found a NULL array\n"; } } if ( _vbos.size() != 1 ) { OE_NOTICE << LC << "Found a Geometry that uses more than one VBO (non-optimal sharing)\n"; } const osg::Geometry::PrimitiveSetList& plist = geom.getPrimitiveSetList(); std::set<osg::BufferObject*> _ebos; for( osg::Geometry::PrimitiveSetList::const_iterator p = plist.begin(); p != plist.end(); ++p ) { osg::PrimitiveSet* pset = p->get(); osg::DrawArrays* da = dynamic_cast<osg::DrawArrays*>(pset); if ( da ) { if ( da->getFirst() >= numVerts ) { OE_NOTICE << LC << "DrawArrays: first > numVerts\n"; } if ( da->getFirst()+da->getCount() > numVerts ) { OE_NOTICE << LC << "DrawArrays: first/count out of bounds\n"; } if ( da->getCount() < 1 ) { OE_NOTICE << LC << "DrawArrays: count is zero\n"; } } bool isDe = pset->getDrawElements() != 0L; osg::DrawElementsUByte* de_byte = dynamic_cast<osg::DrawElementsUByte*>(pset); if ( de_byte ) { validateDE(de_byte, 0xFF, numVerts ); _ebos.insert( de_byte->getElementBufferObject() ); } osg::DrawElementsUShort* de_short = dynamic_cast<osg::DrawElementsUShort*>(pset); if ( de_short ) { validateDE(de_short, 0xFFFF, numVerts ); _ebos.insert( de_short->getElementBufferObject() ); } osg::DrawElementsUInt* de_int = dynamic_cast<osg::DrawElementsUInt*>(pset); if ( de_int ) { validateDE(de_int, 0xFFFFFFFF, numVerts ); _ebos.insert( de_int->getElementBufferObject() ); } if ( pset->getNumIndices() == 0 ) { OE_NOTICE << LC << "Primset: num elements = 0; class=" << pset->className() << ", name=" << pset->getName() << "\n"; } else if ( pset->getType() >= GL_TRIANGLES && pset->getNumIndices() < 3 ) { OE_NOTICE << LC << "Primset: not enough indicies for surface prim type\n"; } else if ( pset->getType() >= GL_LINE_STRIP && pset->getNumIndices() < 2 ) { OE_NOTICE << LC << "Primset: not enough indicies for linear prim type\n"; } else if ( isDe && pset->getType() == GL_LINES && pset->getNumIndices() % 2 != 0 ) { OE_NOTICE << LC << "Primset: non-even index count for GL_LINES\n"; } } if ( _ebos.size() != 1 ) { OE_NOTICE << LC << "Found a Geometry that uses more than one EBO (non-optimal sharing)\n"; } }