利用osg 实现机械手运动阴影效果

 1,运动前 添加阴影,运动后 等待几秒钟 删除阴影

2,

void RobotWidgget::drawOneShadow()
{
    if(!pRobot)
        return;

    //缓存的node模型节点
    int index = 0;

    osg::ref_ptr<osg::Group> group = new osg::Group;
    // 记录上一个转换节点
    osg::Matrix lastMat = (*pRobot->getRobotJoints().begin())->getMatrix();
    for (auto pJointMatrixform : pRobot->getRobotJoints()) {
        osg::ref_ptr<osg::Node> copyNode = nullptr;
        if (index < pRobot->getRobotJoints().size()) {
            copyNode = pRobot->getRobotJoints()[index]->getModel();
        }

        // 获取世界坐标系下的旋转矩阵
        osg::Matrix curMat = pJointMatrixform->getMatrix();
        // 但是我们想让这个坐标系是相对于上一个坐标系, 因此需要映射,所以左乘矩阵
        // osg矩阵相乘与矩阵理论刚好相反, 这里相当于是左乘
        if (index > 0) {
            curMat = curMat * lastMat;
            lastMat = curMat;
        }
        index++;

        // 为curMat新建一个转换节点
        osg::ref_ptr<osg::MatrixTransform> copyMatrixTransform = new osg::MatrixTransform(curMat);
        copyMatrixTransform->addChild(copyNode);
        group->addChild(copyMatrixTransform);
    }

    // 设置透明度
    osg::ref_ptr<osg::StateSet> state = group->getOrCreateStateSet();
    // 关闭灯光
    state->setMode(GL_LIGHTING,osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED);
    // 打开混合融合模式
    state->setMode(GL_BLEND,osg::StateAttribute::ON);
    state->setMode(GL_DEPTH_TEST,osg::StateAttribute::ON);
    state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
    // 使用BlendFunc实现透明效果
    osg::ref_ptr<osg::BlendColor> bc =new osg::BlendColor(osg::Vec4(1.0,1.0,1.0,0.0));
    osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc();
    state->setAttributeAndModes(bf,osg::StateAttribute::ON);
    state->setAttributeAndModes(bc,osg::StateAttribute::ON);
    bf->setSource(osg::BlendFunc::CONSTANT_ALPHA);
    bf->setDestination(osg::BlendFunc::ONE_MINUS_CONSTANT_ALPHA);
    bc->setConstantColor(osg::Vec4(1, 1, 1, 0.2));

    // 起个名字到后面好删除它
    group->setName("shadow");
    pRoot->addChild(group);

}

void RobotWidgget::removeShadow()
{
    FindNodeWithName findNodeName("shadow");
    for (int i = 0; i < 10; ++i) {
        pRoot->accept(findNodeName);
        pRoot->removeChild(findNodeName.getNode());
    }
}

 参考:六轴机器人仿真软件: 基于Qt平台、Osg渲染引擎开发的六轴机器人离线编程软件

猜你喜欢

转载自blog.csdn.net/weixin_38416696/article/details/127507646