void RigTransformSoftware::operator()(RigGeometry& geom) { if (_needInit) if (!init(geom)) return; if (!geom.getSourceGeometry()) { OSG_WARN << this << " RigTransformSoftware no source geometry found on RigGeometry" << std::endl; return; } osg::Geometry& source = *geom.getSourceGeometry(); osg::Geometry& destination = geom; osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray()); osg::Vec3Array* positionDst = dynamic_cast<osg::Vec3Array*>(destination.getVertexArray()); if (positionSrc && (!positionDst || (positionDst->size() != positionSrc->size()) ) ) { if (!positionDst) { positionDst = new osg::Vec3Array; positionDst->setDataVariance(osg::Object::DYNAMIC); destination.setVertexArray(positionDst); } *positionDst = *positionSrc; } osg::Vec3Array* normalSrc = dynamic_cast<osg::Vec3Array*>(source.getNormalArray()); osg::Vec3Array* normalDst = dynamic_cast<osg::Vec3Array*>(destination.getNormalArray()); if (normalSrc && (!normalDst || (normalDst->size() != normalSrc->size()) ) ) { if (!normalDst) { normalDst = new osg::Vec3Array; normalDst->setDataVariance(osg::Object::DYNAMIC); destination.setNormalArray(normalDst); destination.setNormalBinding(osg::Geometry::BIND_PER_VERTEX); } *normalDst = *normalSrc; } if (positionDst && !positionDst->empty()) { compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &positionSrc->front(), &positionDst->front()); positionDst->dirty(); } if (normalDst && !normalDst->empty()) { computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &normalSrc->front(), &normalDst->front()); normalDst->dirty(); } }
bool RigTransformSoftware::init(RigGeometry& geom) { if (!geom.getSkeleton()) return false; BoneMapVisitor mapVisitor; geom.getSkeleton()->accept(mapVisitor); BoneMap bm = mapVisitor.getBoneMap(); initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList()); if (geom.getSourceGeometry()) geom.copyFrom(*geom.getSourceGeometry()); geom.setVertexArray(0); geom.setNormalArray(0); _needInit = false; return true; }
bool RigTransformHardware::init(RigGeometry& geom) { osg::Geometry& source = *geom.getSourceGeometry(); osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray()); if (!positionSrc) { OSG_WARN << "RigTransformHardware no vertex array in the geometry " << geom.getName() << std::endl; return false; } if (!geom.getSkeleton()) { OSG_WARN << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl; return false; } // copy shallow from source geometry to rig geom.copyFrom(source); BoneMapVisitor mapVisitor; geom.getSkeleton()->accept(mapVisitor); BoneMap bm = mapVisitor.getBoneMap(); if (!createPalette(positionSrc->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) return false; osg::ref_ptr<osg::Program> program = new osg::Program; program->setName("HardwareSkinning"); if (!_shader.valid()) _shader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); if (!_shader.valid()) { OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; return false; } // replace max matrix by the value from uniform { std::string str = _shader->getShaderSource(); std::string toreplace = std::string("MAX_MATRIX"); std::size_t start = str.find(toreplace); std::stringstream ss; ss << getMatrixPaletteUniform()->getNumElements(); str.replace(start, toreplace.size(), ss.str()); _shader->setShaderSource(str); OSG_INFO << "Shader " << str << std::endl; } int attribIndex = 11; int nbAttribs = getNumVertexAttrib(); for (int i = 0; i < nbAttribs; i++) { std::stringstream ss; ss << "boneWeight" << i; program->addBindAttribLocation(ss.str(), attribIndex + i); geom.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); OSG_INFO << "set vertex attrib " << ss.str() << std::endl; } program->addShader(_shader.get()); osg::ref_ptr<osg::StateSet> ss = geom.getOrCreateStateSet(); ss->addUniform(getMatrixPaletteUniform()); ss->addUniform(new osg::Uniform("nbBonesPerVertex", getNumBonesPerVertex())); ss->setAttributeAndModes(program.get()); _needInit = false; return true; }