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

【OSG学习笔记】Day 18: 碰撞检测与物理交互

在这里插入图片描述

物理引擎(Physics Engine)

物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。

它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚拟现实(VR)、机器人仿真 等领域。

物理引擎的核心功能
  1. 碰撞检测:判断物体是否发生碰撞或接触。
  2. 物理模拟:根据物理定律(如牛顿力学)计算物体的运动轨迹、速度、加速度等。
  3. 交互反馈:处理物体碰撞后的力学反应(如反弹、摩擦、破碎)。
  4. 约束系统:模拟物体间的连接关系(如铰链、弹簧、绳索等)。
常见物理引擎
  • Bullet:开源、跨平台,适合刚体和软体模拟,常用于游戏和仿真(OSG开发)。
  • PhysX:NVIDIA开发的商业引擎,广泛用于3A游戏(如《绝地求生》)。
  • Havok:商业引擎,支持复杂物理效果,应用于影视和游戏。
  • Box2D:2D物理引擎,适合2D游戏(如《愤怒的小鸟》)。
物理引擎的工作流程
  1. 更新物理世界:根据时间步长计算物体运动。
  2. 碰撞检测:识别所有碰撞对。
  3. 物理响应:计算碰撞后的速度、力和动量变化。
  4. 同步渲染:将物理模拟结果反映到图形界面。

刚体(Rigid Body)

刚体 是物理学中的一个理想模型,指在运动和受力过程中 形状和大小完全不变 的物体。换句话说,刚体的任意两点间的距离始终保持不变,忽略形变(如压缩、弯曲、旋转时的体积变化)。

刚体的特点
  • 无弹性形变:碰撞时能量守恒(完全弹性碰撞)或部分损失(非弹性碰撞),但形状不变。
  • 自由度:刚体在三维空间中有 6个自由度(3个平移自由度 + 3个旋转自由度)。
  • 应用场景:适用于模拟 硬物体 的运动,如石块、车辆、机械零件等。
与软体的区别
  • 软体:允许形变(如布料、液体、果冻),模拟更复杂(需考虑弹性、粘性等)。
  • 刚体:简化模型,计算效率高,适合大规模物理模拟。
刚体在物理引擎中的应用
  • 通过 质量、惯性矩、摩擦力、 restitution(恢复系数) 等参数定义物理属性。
  • 结合碰撞形状(如球体、立方体、胶囊体)进行碰撞检测,减少计算量。

物理引擎与刚体的关系

物理引擎通过算法模拟刚体的运动和交互,例如:

  • 当两个刚体碰撞时,物理引擎根据 动量守恒定律 计算碰撞后的速度和方向。
  • 利用 约束(Constraint) 限制刚体的自由度(如用铰链连接两个刚体,使其只能绕轴旋转)。

在您的学习场景中(OSG + Bullet),Bullet作为物理引擎,负责处理刚体的碰撞检测和物理模拟,而OSG负责图形渲染,两者结合实现逼真的物理交互效果(如物体掉落、碰撞反弹等)。

实战

#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osgGA/TrackballManipulator>
#include <osg/PositionAttitudeTransform>// Bullet物理引擎头文件
#include <btBulletDynamicsCommon.h>// OSG与Bullet转换工具
osg::Matrix bulletToOsg(const btTransform& transform) {osg::Matrix matrix;btScalar elements[16];transform.getOpenGLMatrix(elements);matrix.set(elements);return matrix;
}class PhysicsUpdateCallback : public osg::NodeCallback {
public:PhysicsUpdateCallback(btDynamicsWorld* world, std::map<btRigidBody*, osg::ref_ptr<osg::MatrixTransform>>& bodyNodeMap): _world(world), _bodyNodeMap(bodyNodeMap) {}virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {// 更新物理世界_world->stepSimulation(1.0f/60.0f, 10);// 更新OSG场景图中的物体位置for (auto& pair : _bodyNodeMap) {btRigidBody* body = pair.first;osg::MatrixTransform* transformNode = pair.second.get();btTransform trans;body->getMotionState()->getWorldTransform(trans);transformNode->setMatrix(bulletToOsg(trans));}traverse(node, nv);}private:btDynamicsWorld* _world;std::map<btRigidBody*, osg::ref_ptr<osg::MatrixTransform>>& _bodyNodeMap;
};int main() {// 初始化OSG查看器osgViewer::Viewer viewer;viewer.setCameraManipulator(new osgGA::TrackballManipulator);// 创建根节点osg::ref_ptr<osg::Group> root = new osg::Group;// ===== Bullet物理引擎初始化 =====// 创建碰撞检测配置和调度器btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);// 创建叠代约束求解器btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;// 创建宽广阶段碰撞检测算法btDbvtBroadphase* overlappingPairCache = new btDbvtBroadphase();// 创建动力学世界btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);// 设置重力dynamicsWorld->setGravity(btVector3(0, 0, -9.81));// ===== 创建物理对象和OSG场景 =====std::map<btRigidBody*, osg::ref_ptr<osg::MatrixTransform>> bodyNodeMap;// 1. 创建地面// OSG部分osg::ref_ptr<osg::Box> groundShape = new osg::Box(osg::Vec3(0, 0, -1), 20, 20, 1);osg::ref_ptr<osg::ShapeDrawable> groundDrawable = new osg::ShapeDrawable(groundShape);osg::ref_ptr<osg::Geode> groundGeode = new osg::Geode;groundGeode->addDrawable(groundDrawable);osg::ref_ptr<osg::MatrixTransform> groundTransform = new osg::MatrixTransform;groundTransform->addChild(groundGeode);root->addChild(groundTransform);// Bullet部分btCollisionShape* groundShapeBullet = new btBoxShape(btVector3(10, 10, 0.5));btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, -1)));btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, groundShapeBullet, btVector3(0, 0, 0));btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);dynamicsWorld->addRigidBody(groundRigidBody);// 记录地面刚体与OSG节点的映射bodyNodeMap[groundRigidBody] = groundTransform;// 2. 创建球体// OSG部分osg::ref_ptr<osg::Sphere> sphereShape = new osg::Sphere(osg::Vec3(0, 0, 5), 1.0);osg::ref_ptr<osg::ShapeDrawable> sphereDrawable = new osg::ShapeDrawable(sphereShape);osg::ref_ptr<osg::Geode> sphereGeode = new osg::Geode;sphereGeode->addDrawable(sphereDrawable);osg::ref_ptr<osg::MatrixTransform> sphereTransform = new osg::MatrixTransform;sphereTransform->addChild(sphereGeode);root->addChild(sphereTransform);// Bullet部分btCollisionShape* sphereShapeBullet = new btSphereShape(1.0);btDefaultMotionState* sphereMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 5)));btScalar mass = 1.0;btVector3 sphereInertia(0, 0, 0);sphereShapeBullet->calculateLocalInertia(mass, sphereInertia);btRigidBody::btRigidBodyConstructionInfo sphereRigidBodyCI(mass, sphereMotionState, sphereShapeBullet, sphereInertia);btRigidBody* sphereRigidBody = new btRigidBody(sphereRigidBodyCI);dynamicsWorld->addRigidBody(sphereRigidBody);// 记录球体刚体与OSG节点的映射bodyNodeMap[sphereRigidBody] = sphereTransform;// 3. 创建立方体// OSG部分osg::ref_ptr<osg::Box> boxShape = new osg::Box(osg::Vec3(3, 0, 3), 1.0);osg::ref_ptr<osg::ShapeDrawable> boxDrawable = new osg::ShapeDrawable(boxShape);osg::ref_ptr<osg::Geode> boxGeode = new osg::Geode;boxGeode->addDrawable(boxDrawable);osg::ref_ptr<osg::MatrixTransform> boxTransform = new osg::MatrixTransform;boxTransform->addChild(boxGeode);root->addChild(boxTransform);// Bullet部分btCollisionShape* boxShapeBullet = new btBoxShape(btVector3(1.0, 1.0, 1.0));btDefaultMotionState* boxMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(3, 0, 3)));btRigidBody::btRigidBodyConstructionInfo boxRigidBodyCI(2.0, boxMotionState, boxShapeBullet, sphereInertia);btRigidBody* boxRigidBody = new btRigidBody(boxRigidBodyCI);dynamicsWorld->addRigidBody(boxRigidBody);// 记录立方体刚体与OSG节点的映射bodyNodeMap[boxRigidBody] = boxTransform;// 添加物理更新回调osg::ref_ptr<PhysicsUpdateCallback> physicsCallback = new PhysicsUpdateCallback(dynamicsWorld, bodyNodeMap);root->setUpdateCallback(physicsCallback);// 设置场景数据并运行查看器viewer.setSceneData(root);return viewer.run();
}    

运行效果

在这里插入图片描述

在这里插入图片描述

相关文章:

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...