【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各父类作用(必须理解)
osg::Object
所有 OSG 对象的基类,提供引用计数、智能指针、克隆、命名能力。osg::Node
场景树节点基类,提供包围盒、更新回调、渲染状态基础能力。osg::Group
组节点基类,可以挂载子节点,是组合场景的基础。osg::ClipNode
继承组节点能力,自动管理裁剪平面与裁剪状态,将裁剪效果作用于所有子节点。
osg::ClipNode核心原理
ClipNode底层基于OpenGL 裁剪平面(GL_CLIP_PLANE0~5)实现:
- 创建 1~6 个裁剪平面
- 将平面参数传入 GPU
- 渲染时只保留平面正面的几何体
- 自动通过
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¢er,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())
让多个模型共用同一套裁剪状态,性能极高。
效果说明
运行后你将看到三部分模型:
- 左侧:线框模型
- 中间:动态旋转裁剪模型
- 右侧:应用了裁剪的实体模型
可以清晰看到模型内部结构,是机械、建筑、医疗可视化的标准方案。
总结
osg::ClipNode:OSG 官方标准空间裁剪节点。- 继承关系:
Object → Node → Group → ClipNode。 - 核心能力:硬件加速裁剪、动态平面、多模型共享状态。
- 使用场景:模型剖切、切面展示、区域可见、内部结构查看。
