void RigTransformHardware::operator()(RigGeometry& geom)
{
    if (_needInit)
        if (!init(geom))
            return;
    computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry());
}
Example #2
0
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();
    }
}
Example #3
0
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;
}