当前位置: 首页 > news >正文

【OSG学习笔记】Day 23: ClipNode(动态裁剪)

osg::ClipNode

在 OpenSceneGraph(OSG)三维开发中,模型动态裁剪是可视化、剖切、内部结构展示的核心功能。

osg::ClipNode正是 OSG 提供的专用裁剪节点,可以轻松实现模型剖切、区域可见性控制、动态切面等高级渲染效果。

本文将从继承关系、核心原理、使用方法、完整代码示例四个维度,带你彻底掌握osg::ClipNode


什么是osg::ClipNode

osg::ClipNode是 OSG 中专门用于裁剪空间渲染的节点类。
它通过定义裁剪平面(ClipPlane),对场景中的几何体进行“切割”,只保留平面一侧的可见部分,常用于:

  • 模型剖切视图
  • 动态切面展示内部结构
  • 区域可见性过滤
  • 医学影像、机械模型、建筑模型剖面展示

一句话总结:
ClipNode = 场景的“空间切割器”,通过平面控制模型哪些部分可见。


osg::ClipNode完整继承关系

ClipNode属于 OSG 场景树节点体系,继承链非常清晰:

osg::Object ↓ osg::Node ↓ osg::Group ↓ osg::ClipNode

各父类作用(必须理解)

  1. osg::Object
    所有 OSG 对象的基类,提供引用计数、智能指针、克隆、命名能力。

  2. osg::Node
    场景树节点基类,提供包围盒、更新回调、渲染状态基础能力。

  3. osg::Group
    组节点基类,可以挂载子节点,是组合场景的基础。

  4. osg::ClipNode
    继承组节点能力,自动管理裁剪平面与裁剪状态,将裁剪效果作用于所有子节点。


osg::ClipNode核心原理

ClipNode底层基于OpenGL 裁剪平面(GL_CLIP_PLANE0~5)实现:

  1. 创建 1~6 个裁剪平面
  2. 将平面参数传入 GPU
  3. 渲染时只保留平面正面的几何体
  4. 自动通过StateSet管理裁剪开关与状态

它最大的优势:

  • 不用修改模型数据
  • 性能极高(GPU 硬件裁剪)
  • 可动态移动/旋转平面
  • 可嵌套、可组合、可继承

osg::ClipNode常用 API

// 创建盒式裁剪(自动生成6个面,形成包围盒裁剪)voidcreateClipBox(constBoundingBox&bbox);// 添加/移除裁剪平面voidaddClipPlane(ClipPlane*p);voidremoveClipPlane(unsignedinti);// 获取/设置裁剪状态StateSet*getStateSet();// 启用/禁用自身拣选(避免裁剪平面被意外剔除)voidsetCullingActive(false);

完整实战代码

以下代码基于标准 OSG 工程,实现:

  • 动态旋转裁剪
  • 线框渲染
  • 实体+裁剪对比显示
#include<osg/Group>#include<osg/StateSet>#include<osg/PolygonMode>#include<osg/MatrixTransform>#include<osg/ClipNode>#include<osg/ClipPlane>#include<osg/BoundingSphere>#include<osg/BoundingBox>#include<osg/NodeCallback>#include<osgDB/ReadFile>#include<osgViewer/Viewer>#include<osgUtil/Optimizer>#include<iostream>// 动态旋转回调:让裁剪平面持续旋转,实现动态剖切classClipRotateCallback:publicosg::NodeCallback{public:ClipRotateCallback(constosg::Vec3d&center,constosg::Vec3&axis,floatspeed):_center(center),_axis(axis),_speed(speed),_time(0.0),_lastTime(0.0){}virtualvoidoperator()(osg::Node*node,osg::NodeVisitor*nv){osg::MatrixTransform*mt=dynamic_cast<osg::MatrixTransform*>(node);if(mt&&nv){doubledelta=nv->getFrameStamp()->getReferenceTime()-_lastTime;_time+=delta;_lastTime=nv->getFrameStamp()->getReferenceTime();// 旋转矩阵osg::Quatquat(osg::DegreesToRadians(_speed*_time),_axis);mt->setMatrix(osg::Matrix::translate(_center)*osg::Matrix::rotate(quat)*osg::Matrix::translate(-_center));}traverse(node,nv);}private:osg::Vec3d _center;osg::Vec3 _axis;float_speed;double_time;double_lastTime;};// 创建裁剪场景osg::ref_ptr<osg::Node>createClipScene(osg::ref_ptr<osg::Node>model){osg::ref_ptr<osg::Group>root=newosg::Group();// ====================== 1. 线框模式 ======================osg::ref_ptr<osg::StateSet>ssWire=newosg::StateSet();osg::ref_ptr<osg::PolygonMode>pm=newosg::PolygonMode();pm->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);ssWire->setAttributeAndModes(pm,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);osg::ref_ptr<osg::Group>wireFrame=newosg::Group();wireFrame->setStateSet(ssWire);wireFrame->addChild(model);root->addChild(wireFrame);// ====================== 2. 动态裁剪节点 ======================osg::ref_ptr<osg::MatrixTransform>animTrans=newosg::MatrixTransform();animTrans->setUpdateCallback(newClipRotateCallback(model->getBound().center(),osg::Vec3(0,0,1),// 旋转轴45.0f// 旋转速度));// 创建 ClipNodeosg::ref_ptr<osg::ClipNode>clipNode=newosg::ClipNode();osg::BoundingBox box;box.expandBy(model->getBound());clipNode->createClipBox(box);// 自动生成6个裁剪面clipNode->setCullingActive(false);// 禁止剔除,保证裁剪生效animTrans->addChild(clipNode);clipNode->addChild(model);root->addChild(animTrans);// ====================== 3. 应用裁剪效果到实体模型 ======================osg::ref_ptr<osg::Group>clippedModel=newosg::Group();clippedModel->setStateSet(clipNode->getStateSet());clippedModel->addChild(model);root->addChild(clippedModel);returnroot;}intmain(){osgViewer::Viewer viewer;osg::ref_ptr<osg::Node>model=osgDB::readNodeFile("cessna.osg");if(!model){std::cout<<"模型加载失败!"<<std::endl;return-1;}osg::ref_ptr<osg::Node>scene=createClipScene(model);viewer.setSceneData(scene);returnviewer.run();}


代码核心逻辑讲解

1. 动态裁剪回调

让裁剪平面自动旋转,实现模型动态剖切效果。

2.createClipBox

自动根据模型包围盒生成6个裁剪平面,形成盒式裁剪。

3.setCullingActive(false)

非常关键:
禁止裁剪节点被视锥体裁掉,保证裁剪平面永远生效。

4. 裁剪状态共享

clippedModel->setStateSet(clipNode->getStateSet())
让多个模型共用同一套裁剪状态,性能极高


效果说明

运行后你将看到三部分模型:

  1. 左侧:线框模型
  2. 中间:动态旋转裁剪模型
  3. 右侧:应用了裁剪的实体模型

可以清晰看到模型内部结构,是机械、建筑、医疗可视化的标准方案。


总结

  • osg::ClipNode:OSG 官方标准空间裁剪节点
  • 继承关系Object → Node → Group → ClipNode
  • 核心能力:硬件加速裁剪、动态平面、多模型共享状态。
  • 使用场景:模型剖切、切面展示、区域可见、内部结构查看。

http://www.jsqmd.com/news/563355/

相关文章:

  • 嵌入式系统中SipHash轻量级哈希实现与优化
  • 告别联网依赖!手把手教你用Vosk在Unity中实现离线语音控制(2024最新版)
  • 搜索引擎学习笔记-概要
  • 污泥沉降比检测方法研究
  • MySQL和Oracle有啥区别 编程新手入门指南
  • 创新实训第一周总结
  • VCAD2022压力容器专用CAD插件|兼容全版本AutoCAD|化工设计绘图高效利器
  • XUnity.AutoTranslator:如何为Unity游戏构建高效的多语言本地化系统
  • 教你把歌曲原声调小的5个技巧!简单又好用 赶紧收藏
  • HarmonyOS6 ArkTS ListItem设置划出组件
  • 嵌入式NTP客户端库:高精度时间同步与自动时区管理
  • 自学嵌入式第一天
  • 多行业适配螺杆泵及泵送系统供应商:进口螺杆泵配件、锂电池专用螺杆泵、食品级螺杆泵、高压螺杆泵、不锈钢螺杆泵、加药螺杆泵选择指南 - 优质品牌商家
  • WooCommerce 高级报告与统计 – 订单、产品与客户报告 WordPress插件SQL注入[ CVE-2026-24993 ]
  • 3D Slicer新手必看:如何用窗宽窗位优化CT图像显示效果(附VTK对比)
  • 4个关键步骤:用vscode-ai-toolkit实现智能应用开发全流程
  • MC备份1
  • Sentaurus实战解析:SiC NMOS仿真中的关键参数设置与优化
  • 2026年比较好的呼市原车漆补漆实力车行推荐 - 品牌宣传支持者
  • Tomato-Novel-Downloader:你的终极番茄小说离线阅读解决方案
  • 管道巡检软体机器人 YOLOv8 模型部署全流程(PT→ONNX→昇腾OM)
  • 从对话到执行:一文读懂AI Coding Agent的底层原理
  • 质量块-阻尼器-弹簧系统H的鲁棒控制:次最优、Loopshaping与μ综合dk迭代设计案例
  • 数据增广翻车现场实录:我的模型准确率为什么反而下降了?附PyTorch调试避坑指南
  • 3大突破策略:Bypass Paywalls Clean 2024全场景应用指南
  • APK Studio核心功能解析:深入理解反编译与重编译流程
  • 2026电力盖板及玻璃钢制品优选营顺高性价比服务:玻璃钢电缆沟盖板/玻璃钢罐体/玻璃钢运输罐/电缆沟盖板/酸碱罐/选择指南 - 优质品牌商家
  • PyTorch模型部署实战:FP16 vs FP32 vs TF32 vs INT8性能对比与选择指南
  • 从6颗MLCC到高通滤波器:解码耳机输出耦合电容的取舍艺术
  • 从Dhrystone到SPEC:聊聊那些年我们跑过的“分”,以及为什么现在不能全信它