【OSG学习笔记】Day 5: Group类与PositionAttitudeTransform类

OSG核心节点:osg::Group与PositionAttitudeTransform

OpenSceneGraph(OSG)作为高性能的跨平台3D图形引擎,其核心设计思想是场景图(Scene Graph) ------通过树形结构组织所有渲染对象,而osg::Group及其子类是构建场景图的基石。

本文将从继承关系、核心功能、代码实践三个维度,详解osg::Group类,并重点分析其重要子类PositionAttitudeTransform(PAT)的使用场景与实现逻辑。

osg::Group:场景图的"骨架"节点

1 继承关系:OSG节点体系的核心分支

osg::Group是OSG场景图中组节点的基类,其完整继承链如下:

vbnet 复制代码
osg::Referenced(引用计数基类)
    ↓
osg::Object(OSG对象基类,提供命名/克隆等基础功能)
    ↓
osg::Node(所有场景节点的根类)
    ↓
osg::Group(组节点基类)
  • 核心父类说明
    • osg::Referenced:为所有OSG对象提供线程安全的引用计数内存管理,避免手动new/delete导致的内存泄漏;
    • osg::Node:定义了场景节点的核心接口(如遍历、渲染状态、更新回调),是所有可加入场景图的对象的基类;
    • osg::Group:在osg::Node基础上扩展了子节点管理能力,是唯一能包含其他节点的核心类。

2 核心功能:场景图的"容器"

osg::Group的核心价值是管理子节点集合,它本身不包含可渲染的几何数据,仅负责组织、遍历和传递渲染状态,主要能力包括:

  1. 子节点增删查改 :提供addChild()/removeChild()/getChild()/getNumChildren()等接口,支持动态维护子节点列表;
  2. 渲染状态继承 :组节点设置的渲染状态(如纹理、材质)会自动传递给所有子节点(可通过StateSet控制);
  3. 遍历控制 :支持设置NodeVisitor遍历回调,自定义子节点的遍历逻辑(如裁剪、拣选);
  4. 线程安全 :基于osg::Referenced的线程安全设计,多线程环境下增删子节点仍能保证稳定。

3 关键特性与使用场景

  • 无数量限制 :一个osg::Group可包含任意数量的子节点(包括其他osg::Grouposg::Geode),形成多层级树形结构;
  • 场景分块管理:常用于按功能划分场景(如"地形组""模型组""特效组"),便于批量控制显隐、更新;
  • 不可渲染osg::Group本身无几何数据,若需渲染需结合osg::Geode(几何节点)使用。

PositionAttitudeTransform:节点变换的"核心工具"

PositionAttitudeTransform(简称PAT)是osg::Group的最重要子类之一,专门用于控制子节点的空间变换(位置、姿态、缩放),是OSG中实现模型位移、旋转、缩放的核心类。

1 继承关系:基于Group的变换扩展

PAT的继承链在osg::Group基础上进一步扩展:

vbnet 复制代码
osg::Referenced
    ↓
osg::Object
    ↓
osg::Node
    ↓
osg::Group
    ↓
osg::Transform(变换节点基类)
    ↓
osg::PositionAttitudeTransform
  • 关键中间类:osg::Transformosg::Transform是所有变换节点的基类,定义了"矩阵变换"的核心接口(computeLocalToWorldMatrix()/computeWorldToLocalMatrix()),但未封装具体的变换参数;
  • PositionAttitudeTransform :在osg::Transform基础上,将变换拆解为位置(Position)、姿态(Attitude)、缩放(Scale) 三个直观参数,简化了3D空间变换的使用。

2 核心功能:三维空间变换的"封装器"

PAT将复杂的矩阵变换封装为三个易用的参数,避免手动计算变换矩阵,核心参数如下:

参数 类型 作用
Position osg::Vec3 控制子节点在世界坐标系中的位置(X/Y/Z轴偏移)
Attitude osg::Quat 控制子节点的姿态(旋转),基于四元数实现无万向节死锁的3D旋转
Scale osg::Vec3 控制子节点在X/Y/Z轴上的缩放比例(1.0为原始大小,0.5为缩小一半)
Pivot Point osg::Vec3 旋转/缩放的中心点(默认是节点局部坐标系原点)

3 核心优势

  1. 直观易用:无需手动构建4×4变换矩阵,直接设置位置、旋转、缩放参数即可;
  2. 四元数旋转 :基于osg::Quat的姿态控制,避免欧拉角的万向节死锁问题;
  3. 子节点批量变换:PAT的变换会作用于所有子节点,可批量控制多个模型的空间状态;
  4. 动态更新:支持运行时修改变换参数(如动画中实时调整位置/旋转),立即生效。

代码实践:Group与PAT的综合使用

下面通过完整示例,展示如何基于osg::Group构建场景图,并通过PositionAttitudeTransform实现模型的空间变换:

源码库:osg_transform

1 完整代码

cpp 复制代码
#include <osgViewer/Viewer>
#include <osg/Group>
#include <osg/PositionAttitudeTransform>
#include <osg/Geode>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/Notify>

// 创建一个带PAT变换的模型节点
osg::ref_ptr<osg::Node> createTransformedModel(const std::string& modelPath, 
                                               const osg::Vec3& pos, 
                                               const osg::Vec3& scale,
                                               const osg::Quat& attitude)
{
    // 1. 加载模型(返回osg::Node,可能是Group/Geode)
    osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(modelPath);
    if (!model)
    {
        osg::notify(osg::FATAL) << "模型加载失败:" << modelPath << std::endl;
        return nullptr;
    }

    // 2. 创建PAT变换节点
    osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();
    pat->setPosition(pos);         // 设置位置
    pat->setScale(scale);          // 设置缩放
    pat->setAttitude(attitude);    // 设置旋转姿态

    // 3. 将模型添加为PAT的子节点(变换作用于模型)
    pat->addChild(model.get());

    return pat;
}

int main()
{
    // 1. 创建场景根节点(osg::Group)
    osg::ref_ptr<osg::Group> root = new osg::Group();
    root->setName("SceneRoot"); // 设置节点名称(osg::Object的能力)

    // 2. 定义变换参数
    osg::Vec3 pos1(-10.0f, 0.0f, 0.0f);  // 左侧模型位置
    osg::Vec3 scale1(0.5f, 0.5f, 0.5f);  // 缩小为0.5倍
    osg::Quat rot1(0.0f, osg::Vec3(0, 1, 0)); // 无旋转(绕Y轴0度)

    osg::Vec3 pos2(10.0f, 0.0f, 0.0f);   // 右侧模型位置
    osg::Vec3 scale2(1.0f, 1.0f, 1.0f);  // 原始大小
    osg::Quat rot2(osg::PI/2, osg::Vec3(0, 1, 0)); // 绕Y轴旋转90度

    // 3. 创建两个带不同变换的模型节点
    osg::ref_ptr<osg::Node> model1 = createTransformedModel("cow.osg", pos1, scale1, rot1);
    osg::ref_ptr<osg::Node> model2 = createTransformedModel("cow.osg", pos2, scale2, rot2);

    if (model1 && model2)
    {
        // 4. 将变换节点添加到根节点(osg::Group的核心能力)
        root->addChild(model1.get());
        root->addChild(model2.get());
    }

    // 5. 优化场景图(提升渲染性能)
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());

    // 6. 创建Viewer并运行
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    viewer->setSceneData(root.get());
    viewer->realize(); // 初始化窗口
    return viewer->run(); // 启动渲染循环
}

2 代码解析

  1. 场景结构: 示例中场景图的树形结构为: root (osg::Group) ├─ PAT1 (PositionAttitudeTransform) │ └─ cow.osg (模型节点) └─ PAT2 (PositionAttitudeTransform) └─ cow.osg (模型节点) 同一个模型被两个PAT节点包裹,实现不同的空间变换,且共享模型数据(OSG引用计数自动管理)。

  2. 核心API说明

    • setPosition(osg::Vec3(x,y,z)):设置PAT节点的世界位置,子节点会跟随位移;
    • setScale(osg::Vec3(x,y,z)):沿X/Y/Z轴独立缩放,示例中model1缩小为0.5倍;
    • setAttitude(osg::Quat(angle, axis)):基于四元数旋转,osg::PI/2表示90度,osg::Vec3(0,1,0)表示绕Y轴旋转;
    • root->addChild()osg::Group的核心接口,将变换后的节点加入场景根节点。
  3. 运行效果: 程序运行后会显示两个牛模型:

    • 左侧牛:位置X=-10,缩放0.5倍,无旋转;
    • 右侧牛:位置X=10,原始大小,绕Y轴旋转90度。

总结

  1. osg::Group 是OSG场景图的"骨架",核心作用是组织子节点,本身不可渲染,但支持渲染状态继承和批量控制,是构建复杂场景的基础;
  2. PositionAttitudeTransformosg::Group的核心子类,封装了3D空间变换的核心逻辑,通过位置、姿态、缩放三个参数简化了矩阵变换的使用,是实现模型位移/旋转/缩放的首选工具;
  3. 继承关系的设计体现了OSG的模块化思想:Referenced管内存、Node管节点基础能力、Group管子节点管理、Transform管变换、PAT管具体的空间变换参数,层层封装,兼顾易用性和扩展性。

掌握osg::GroupPositionAttitudeTransform的使用,是构建OSG场景图的核心基础,在此之上可进一步扩展到更复杂的变换(如MatrixTransform)、节点回调(如UpdateCallback)等高级功能。

相关推荐
酬勤-人间道2 天前
自研软件模型处理全流程|个人开发经验分享
c++·经验分享·计算机·计算机图形学·桩号·开挖·回填
波哥学开发10 天前
🎯 Canvas 箭头绘制算法(附完整源码)
前端·计算机图形学
ht巷子1 个月前
光照模型:Gouraud模型
c++·计算机图形学·opengl
ht巷子1 个月前
光照模型:Phong模型
c++·计算机图形学·opengl
charlie1145141912 个月前
计算机图形学速通指南笔记(0)
c++·笔记·软件工程·计算机图形学·工程实践
狐572 个月前
2026-01-05期末复习-计算机图形学计算题
计算机图形学·期末复习
2503_946971863 个月前
【AGI/Multi-Agent】2026年度AGI情感对齐与多智能体协同渗透基准索引 (Benchmark Index)
人工智能·网络安全·数据集·计算机图形学·多智能体
爱思德学术3 个月前
中国计算机学会(CCF)推荐学术会议-B(计算机图形学与多媒体):I3D 2026
3d·计算机图形学·虚拟现实
AndrewHZ3 个月前
【图像处理基石】光线追踪(Ray Tracing)算法入门
图像处理·人工智能·算法·计算机视觉·计算机图形学·光线追踪·渲染技术