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

【OSG学习笔记】Day 15: 路径动画与相机漫游

请添加图片描述
本章来学习下漫游相机。

路径动画与相机漫游

本届内容比较简单,其实就是实现物体的运动和相机的运动

当然这两个要一起执行。

贝塞尔曲线

贝塞尔曲线(Bézier curve)是一种在计算机图形学、动画制作、工业设计等领域广泛应用的参数曲线,它由法国工程师皮埃尔・贝塞尔(Pierre Bézier)在 20 世纪 60 年代为汽车工业设计而提出。

大致类似这样:

在这里插入图片描述

通过控制一些点来定义整个曲线。

实战

使用OpenSceneGraph(OSG)实现沿贝塞尔曲线移动模型以及录制相机路径的示例代码。

代码实现了在OSG中创建一个模型,并让它沿着贝塞尔曲线移动,同时也记录相机的路径。

#include <osg/Group>
#include <osg/Node>
#include <osg/Geometry>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osg/MatrixTransform>
#include <osg/AnimationPath>
#include <osg/Quat>
#include <iostream>
#include <vector>// 计算贝塞尔曲线上的点
osg::Vec3 bezierPoint(const std::vector<osg::Vec3>& controlPoints, double t) {int n = controlPoints.size() - 1;osg::Vec3 result(0.0, 0.0, 0.0);for (int i = 0; i <= n; ++i) {double binomial = 1.0;for (int j = 0; j < i; ++j) {binomial *= (n - j) / (i - j);}binomial *= pow(1 - t, n - i) * pow(t, i);result += binomial * controlPoints[i];}return result;
}int main() {// 创建一个场景组osg::ref_ptr<osg::Group> root = new osg::Group;// 创建一个简单的模型(这里以一个立方体为例)osg::ref_ptr<osg::Geometry> geom = osg::createTexturedCubeGeometry(osg::Vec3(0, 0, 0), 1.0);osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(geom);root->addChild(geode);// 贝塞尔曲线的控制点std::vector<osg::Vec3> controlPoints = {osg::Vec3(-5, 0, 0),osg::Vec3(-2, 5, 0),osg::Vec3(2, -5, 0),osg::Vec3(5, 0, 0)};// 创建动画路径osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath;animationPath->setLoopMode(osg::AnimationPath::LOOP);// 采样贝塞尔曲线生成动画路径的关键帧const int numSamples = 100;for (int i = 0; i < numSamples; ++i) {double t = static_cast<double>(i) / (numSamples - 1);osg::Vec3 position = bezierPoint(controlPoints, t);osg::Quat orientation; // 这里简单设置为无旋转osg::Vec3 scale(1, 1, 1);osg::AnimationPath::ControlPoint cp(static_cast<double>(i) * 0.1, position, orientation, scale);animationPath->insert(cp);}// 创建一个矩阵变换节点来应用动画路径osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;mt->addChild(geode);osg::ref_ptr<osg::AnimationPathCallback> callback = new osg::AnimationPathCallback(animationPath);mt->setUpdateCallback(callback);root->addChild(mt);// 创建相机路径记录器osg::ref_ptr<osg::Group> cameraPathGroup = new osg::Group;osg::ref_ptr<osg::Vec3Array> cameraPathVertices = new osg::Vec3Array;osg::ref_ptr<osg::Geometry> cameraPathGeom = new osg::Geometry;cameraPathGeom->setVertexArray(cameraPathVertices);osg::ref_ptr<osg::Geode> cameraPathGeode = new osg::Geode;cameraPathGeode->addDrawable(cameraPathGeom);cameraPathGroup->addChild(cameraPathGeode);root->addChild(cameraPathGroup);// 创建查看器osgViewer::Viewer viewer;viewer.setSceneData(root);viewer.setCameraManipulator(new osgGA::TrackballManipulator);// 记录相机路径bool recording = false;osg::Vec3 lastCameraPosition;viewer.setCameraManipulator(new osgGA::TrackballManipulator);viewer.realize();while (!viewer.done()) {osg::Matrix cameraMatrix = viewer.getCamera()->getViewMatrix();osg::Vec3 cameraPosition = osg::Vec3(cameraMatrix.getTrans());if (recording) {cameraPathVertices->push_back(cameraPosition);osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, cameraPathVertices->size());cameraPathGeom->setDrawArray(drawArrays);}// 简单的按键控制记录开始和结束const osgGA::GUIEventAdapter& ea = viewer.getEventQueue()->getCurrentEvent();if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN && ea.getKey() == osgGA::GUIEventAdapter::KEY_R) {recording =!recording;if (recording) {lastCameraPosition = cameraPosition;}}viewer.frame();}return 0;
}

执行效果

在这里插入图片描述
ok,今天就到这里。明天继续!

在这里插入图片描述

http://www.xdnf.cn/news/862939.html

相关文章:

  • 海康网络摄像头实时取帧转Opencv数组格式(h,w,3),已实现python、C#
  • [C]C语言日志系统宏技巧解析
  • 让视觉基础模型(VFMs)像大语言模型(LLMs)一样“会思考”​
  • 3D视觉重构工业智造:解码迁移科技如何用“硬核之眼“重塑生产节拍
  • SOLIDWORKS 2025教育版提供了丰富的自学资源
  • LabVIEW与Modbus/TCP温湿度监控系统
  • 扫地机产品--材质传感器算法开发与虚拟示波器
  • R语言基础| 下载、安装
  • Elasticsearch中的文档(Document)介绍
  • 代码随想录算法训练营第60期第五十七天打卡
  • Elasticsearch从安装到实战、kibana安装以及自定义IK分词器/集成整合SpringBoot详细的教程(二)
  • 第八部分:阶段项目 6:构建 React 前端应用
  • 华为OD机试_2025 B卷_区间交集(Python,100分)(附详细解题思路)
  • ann算法的种类有哪些,之间的区别,各自的适用场景
  • 每日算法刷题Day22 6.4:leetcode二分答案3道题,用时1h30min
  • 如何在 HTML 中添加按钮
  • 信号与系统汇总
  • Flutter、React Native 项目如何搞定 iOS 上架?从构建 IPA 到上传 App Store 的实战流程全解析
  • RabbitMQ 在解决数据库高并发问题中的定位和核心机制
  • Transformer-BiLSTM、Transformer、CNN-BiLSTM、BiLSTM、CNN五模型时序预测
  • 设计模式-外观模式
  • Java 中 ArrayList、Vector、LinkedList 的核心区别与应用场景
  • 高速ADC数据格式与JESD204B IP数据格式映射关系
  • 数智破局·生态共生:重构全球制造新引擎 2025 WOD制造业数字化博览会即将在沪盛大启幕
  • LINUX64 FTP 1; rsync inotify.sh脚本说明
  • 银行用户评分规则 深度学习
  • 使用 Ansys Q3D 进行电容提取
  • 【android bluetooth 协议分析 14】【HFP详解 1】【案例一: 手机侧显示来电,但车机侧没有显示来电: 讲解AT+CLCC命令】
  • 分析Web3下数据保护的创新模式
  • MVCC理解