osg动态修改坐标

class CoordUpdateCallback : public osg::NodeCallback
{
public:

    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        if (nv->getFrameStamp())
        {

            osg::Geode* geode = node->asGeode();
            osg::Geometry* geom = geode->getDrawable(0)->asGeometry();
            // 获取坐标数组
            osg::Array* tmp = geom->getVertexArray();
            osg::Vec2Array* coorArray = (osg::Vec2Array*) tmp;
            auto it = coorArray->begin();
            for (; it < coorArray->end(); it++)
            {
                // 动起来
                it->x() += 100;
            }
            geom->setVertexArray(coorArray);

        }
    }

};

int main
{
    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
    osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
    v->push_back(osg::Vec3(0, -6378137, 0));
    v->push_back(osg::Vec3(0, -2 * 6378137, 0));
    geom->setVertexArray(v.get());
    osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;
    c->push_back(osg::Vec4(.92f, .92f, .71f, 1.f));
    geom->setColorArray(c.get());
    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 2));
    osg::ref_ptr <osg::Geode> geode = new osg::Geode;
    geode->addDrawable(geom.get());
    geode->setUpdateCallback(new CoordUpdateCallback());//设置更新

    root->addChild(geode.get());
    osgViewer::Viewer viewer;
    viewer.setSceneData(root);
    viewer.run()
}

通过设置public osg::NodeCallback,重写operate()达到修改点的坐标直接修改位置。

### 获取 OSG 点云选点坐标的实现方法 在 OpenSceneGraph (OSG) 中,当处理点云数据并希望获取特定选点的坐标时,通常会遇到一些挑战。由于点云节点的独特性质,在某些情况下无法直接通过屏幕点击事件构建求交器来定位具体点的位置[^1]。 以下是针对此问题的一种解决方案: #### 使用自定义回调函数捕获点云交互 为了更精确地捕捉到点云中的某个点位置,可以采用以下策略: 创建一个专门用于检测鼠标点击事件的机制,并将其绑定至场景图上的点云节点上。每当发生鼠标点击操作时,触发该机制计算实际被击中的三维空间坐标值。 ```cpp #include <osg/NodeCallback> #include <osgViewer/View> #include <osgGA/GUIEventHandler> class PointCloudPicker : public osgGA::GUIEventHandler { public: bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&) override; }; bool PointCloudPicker::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&) { if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) { double mouseX = static_cast<double>(ea.getX()); double mouseY = static_cast<double>(ea.getY()); // 创建拾取线对象 osgUtil::LineSegmentIntersector* picker = new osgUtil::LineSegmentIntersector(osgUtil::IntersectionVisitor::COMPUTE_LOCAL_INTERSECTION, mouseX, mouseY); // 设置视口范围内的拾取区域大小 osgUtil::IntersectionVisitor iv(picker); // 执行相交测试 viewer->getCamera()->accept(iv); const std::vector<osgUtil::LineSegmentIntersector::Intersection>& intersections = picker->getIntersections(); if (!intersections.empty()) { osg::Vec3d pointWorldCoordinates = intersections.front().worldIntersectPoint; // 输出所选点的世界坐标系下的位置 std::cout << "Selected Point Coordinates: (" << pointWorldCoordinates.x() << ", " << pointWorldCoordinates.y() << ", " << pointWorldCoordinates.z() << ")" << std::endl; } delete picker; return true; } return false; } ``` 上述代码片段展示了如何利用 `osgUtil::LineSegmentIntersector` 类型来进行射线投射以找到最近距离处的目标几何体及其对应顶点的具体世界坐标。 另外需要注意的是,如果目标仅限于单个点而非整个模型,则可能还需要进一步调整算法逻辑以便更加精准匹配所需条件。 #### 调整相机投影矩阵提高精度 有时因透视失真或其他因素影响导致最终结果不够理想化,这时可以通过修改摄像机参数或者应用其他技术手段优化这一过程。例如改变近裁剪面的距离、增大远裁剪平面数值等措施均有助于改善此类状况下产生的误差现象。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值