【C++】Bullet3代码存档
之前试了一下Bullet3物理引擎,但在linux上编译失败,于是放弃了。令我不满的还有另外一个原因,下载的发行包竟然有500M。C++的Bullet3代码根本用不了,大部分教程实际都是用的老版本。而且此项目还整了python版本,各种蹭人工智能的热度,感觉后面的维护者越来越不靠谱了。
于是我准备换用ode引擎,下面对bullet3的简单使用记录一下。
一、配置
# bullet3
# 3实际上没有教程,似乎已经弃坑(这里使用2的版本)
# https://github.com/bulletphysics/bullet3/issues/4002
include_directories(${CMAKE_SOURCE_DIR}/third/bullet3/src)
target_link_libraries(${PROJECT_NAME} PRIVATE LinearMath)
target_link_libraries(${PROJECT_NAME} PRIVATE BulletCollision)
target_link_libraries(${PROJECT_NAME} PRIVATE BulletDynamics)
在CMakePresets.json里需要加入以下变量到cacheVariables,关闭其他东西的构建:
"BUILD_EXTRAS": false,
"BUILD_UNIT_TESTS": false
二、使用
/**
* @file dl_physics.h
* @brief 3d物理,基于Bullet3
*
*
* @version 1.0
* @author lveyou
* @date 22-10-28
*
* @note
*/
#pragma once#include <vector>#include <btBulletDynamicsCommon.h>#include "dl_type.h"
#include "math/dl_transform.h"
#include "dl_time.h"
#include "dl_rigid_body.h"//Extras / BulletMultiThreaded 拥有多线程版本 碰撞调度和 解算器namespace dl
{inline btVector3 toBtVector3(const Position3& v)
{return btVector3(v[0], v[1], v[2]);
}class RigidBodyImp
{
public:btRigidBody* _rigidBody;btMotionState* _motion;//运动状态,可选 动态物体才有size_t _idShape;//形状id
};class Physics
{
public:btDefaultCollisionConfiguration* _collConfig;//碰撞配置btCollisionDispatcher* _collDispatcher;//碰撞调度btBroadphaseInterface* _broadphase;//broad-phasebtSequentialImpulseConstraintSolver* _solver;//解算器btDiscreteDynamicsWorld* _world;//世界std::vector<btCollisionShape*> _allShape;//所有形状Physics(){_collConfig = new btDefaultCollisionConfiguration;_collDispatcher = new btCollisionDispatcher(_collConfig);_broadphase = new btDbvtBroadphase;_solver = new btSequentialImpulseConstraintSolver;_world = new btDiscreteDynamicsWorld(_collDispatcher, _broadphase, _solver, _collConfig);_world->setGravity(btVector3(0, 0, -Numbers::GRAVITY));btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1));_allShape.push_back(shape);}/*** @brief 创建刚体* @param[in] shape_id 形状id* @param[in] trans 变换* @param[in] mass 质量* @retval 失败返回nullptr*/RigidBody* CreateRigidBody(size_t shape_id, Transform* trans, Float mass){if (shape_id >= _allShape.size()){log_err0("shape id越界!");return nullptr;}RigidBody* ret = new RigidBody;RigidBodyImp* body = ret->GetImp();//形状body->_idShape = shape_id;btCollisionShape* shape = _allShape[shape_id];//运动状态btTransform bt_trans;bt_trans.setIdentity();Position3 pos = trans->GetTranslation();bt_trans.setOrigin(toBtVector3(pos));body->_motion = new btDefaultMotionState(bt_trans);//质量和惯性btScalar bt_mass{ mass };btVector3 local_inertia(0, 0, 0);if (bt_mass)shape->calculateLocalInertia(bt_mass, local_inertia);//创建刚体body->_rigidBody = new btRigidBody(bt_mass, body->_motion, shape);//加入世界_world->addRigidBody(body->_rigidBody);return ret;}//! 创建默认刚体RigidBody* CreateRigidBodyDefault(Transform* trans){return CreateRigidBody(0, trans, 1);}//! 创建形状 boxsize_t CreateShapeBox(const Position3& box){size_t id = _allShape.size();btCollisionShape* shape = new btBoxShape(toBtVector3(box));_allShape.push_back(shape);return id;}void Update(){_world->stepSimulation(g_time->GetDelta());//更新位置/*for (int j = _world->getNumCollisionObjects() - 1; j >= 0; j--){btCollisionObject* obj = _world->getCollisionObjectArray()[j];btRigidBody* body = btRigidBody::upcast(obj);btTransform trans;if (body && body->getMotionState()){body->getMotionState()->getWorldTransform(trans);}else{trans = obj->getWorldTransform();}trans.getOpenGLMatrix()printf("world pos object %d = %f,%f,%f\n", j, float(trans.getOrigin().getX()), float(trans.getOrigin().getY()), float(trans.getOrigin().getZ()));}*/}void UpdateRigidBody(RigidBodyImp* body, Transform* trans){btTransform bt_trans;btRigidBody* bt_body = body->_rigidBody;if (bt_body->getMotionState()){bt_body->getMotionState()->getWorldTransform(bt_trans);}else{bt_trans = bt_body->getWorldTransform();}const btVector3& pos = bt_trans.getOrigin();trans->SetTranslation({pos.getX(), pos.getY(), pos.getZ()});}~Physics(){//反向删除for (int i = _world->getNumCollisionObjects() - 1; i >= 0; --i){btCollisionObject* obj = _world->getCollisionObjectArray()[i];btRigidBody* body = btRigidBody::upcast(obj);if (body && body->getMotionState()){delete body->getMotionState();}_world->removeCollisionObject(obj);delete obj;}for (auto& iter : _allShape){delete iter;}delete _world;delete _solver;delete _broadphase;delete _collDispatcher;delete _collConfig;}
};extern Physics* g_physics;}
相关文章:
【C++】Bullet3代码存档
之前试了一下Bullet3物理引擎,但在linux上编译失败,于是放弃了。令我不满的还有另外一个原因,下载的发行包竟然有500M。C的Bullet3代码根本用不了,大部分教程实际都是用的老版本。而且此项目还整了python版本,各种蹭人…...

弘扬“两弹一星”精神,勇攀科学技术高峰——道本科技商业大学党日活动圆满落幕
2023年8月2日,道本科技与商业大学携手举办了一场主题为“弘扬‘两弹一星’精神,勇攀科学技术高峰”的党日活动。本次活动旨在了解党领导下的中国核工业发展历程,传承和弘扬“两弹一星”精神,同时展示道本科技创新产品,…...
Java中创建对象的几种方式
背景 面试的时候有些面试官喜欢问这些, 这里简单记录一下. 常见方式 方式1: new XXXX(); 使用new关键字:这是最常见的创建对象的方式,使用new关键字后面跟上类名和参数列表(如果有),可以调用类的构造方法来创建对象…...

Python(三)
诚信像一面镜子,一旦打破,你的人格就会出现裂痕。 存在短路的情景 谢谢观看 Python(三)...

android 如何分析应用的内存(十五)——Visual Studio Code 调试Android应用
android 如何分析应用的内存(十五)——Visual Studio Code 调试Android 应用 在上一篇文章介绍了jdb调试java应用 接下来介绍用UI界面调试java应用,达到同jdb一样的效果。 同样的UI界面有很多选择,如Eclipse,Android …...

宁波银行最新内推码 MK4913
宁波银行最新内推码 MK4913 内推码: MK4913 内推二维码 : 网申路径: 网页端:登录宁波银行招聘官网: https://zhaopin.nbcb.com.cn 选择【校园招聘】-【招聘岗位】手机端:关注【宁波银行招聘】公众号&a…...

postgresql|数据库|MySQL数据库向postgresql数据库迁移的工具pgloader的部署和初步使用
前言: MySQL数据库和postgresql数据库之间的差异并不多,这里的差异指的是对SQL语言的支持两者并不大,但底层的东西差异是非常多的,例如,MySQL的innodb引擎概念,数据库用户管理,这些和postgresq…...

【Python从小白到高手】---函数基础
个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【Python小白从入门到精通】🎈 本专栏旨在分享学习Python的一点学习心得,欢迎大家在评论区讨论💌 目录…...

postman----传参格式(json格式、表单格式)
本文主要讲解postman使用post请求方法的2中传参方式:json格式、表单格式 首先了解下,postman进行接口测试,必须条件是: ♥请求地址 ♥请求协议 ♥请求方式 ♥请求头 ♥参数 json格式 先看一下接口文档,根据接口文档&…...

Uni-Dock:GPU 分子对接使用教程
github文件下载: git clone https://github.com/dptech-corp/Uni-Dock.git cd Uni-Dock/example/screening_test wget https://github.com/dptech-corp/Uni-Dock/releases/download/1.0.0/unidock 将此文件加入到全局变量中 chmod x unidock sudo mv unidock /…...

【Python】数据分析+数据挖掘——掌握Python和Pandas中的单元格替换操作
1. 前言 数据处理和清洗是数据分析和机器学习中至关重要的步骤。在数据处理过程中,我们经常需要对数据集进行清洗和转换,其中单元格替换是一个常用的技术。Python作为一种功能强大且灵活的编程语言,为数据处理提供了丰富的工具和库。Pandas库…...

Godot 4 源码分析 - 增加格式化字符串功能
Godot 4的主要字符串类型为String,已经设计得比较完善了,但有一个问题,格式化这块没怎么考虑。 String中有一个format函数,但这个函数只有两个参数,这咋用? String String::format(const Variant &va…...

C#中XML文档与Treeview控件操作的数据同步
在前文《C#使用XML和Treeview结合实现复杂数据采集功能》中,使用Treeview展示了XML的数据,问题是如果在Treeview上进行了操作,怎样同步更改XML数据的内容呢? 这个问题看似简单,实现起来有一点小麻烦。 要实现的操作功能…...

【Java Web基础】mvn命令、Maven的安装与配置
本文极大程度上来自Maven安装(超详解),但是担心安的过程中遇到什么不一样的问题,顺便加深印象,所以还是打算自己弄一篇。 目录 第一步:Download Maven第二步:解压与安装2.1 解压2.2 安装 第一步:Download …...

加强Web应用程序安全:防止SQL注入
数据库在Web应用程序中存储和组织数据时起着至关重要的作用,它是存储用户信息、内容和其他应用程序数据的中央存储库。而数据库实现了高效的数据检索、操作和管理,使Web应用程序能够向用户提供动态和个性化的内容。然而,数据库和网络应用程序…...

【云原生】k8s中Contrainer 生命周期回调/策略/指针学习
个人主页:征服bug-CSDN博客 kubernetes专栏:kubernetes_征服bug的博客-CSDN博客 目录 1 容器生命周期 2 容器生命周期回调/事件/钩子 3 容器重启策略 4 自定义容器启动命令 5 容器探针 1 容器生命周期 Kubernetes 会跟踪 Pod 中每个容器的状态&am…...

electron+vue3全家桶+vite项目搭建【25】使用electron-updater自动更新应用
文章目录 引入实现效果实现步骤引入依赖配置electron-buidler文件封装版本升级工具类主进程调用版本更新校验渲染进程封装方法调用 测试版本更新 引入 demo项目地址 electron-updater官网 我们不可能每次发布新的版本都让用户去手动下载安装最新的包,而是应用可以…...

SQL 表别名 和 列别名
列表名 列表名之后 order by 可以用别名 也可以用原名, where 中不能用别名的 SQL语句执行顺序: from–>where–>group by -->having — >select --> order 第一步:from语句,选择要操作的表。 第二步࿱…...
面试之快速学习c++11-函数模版的默认模版参数,可变模版,tuple
//学习地址: http://c.biancheng.net/view/3730.html 函数模版的默认模版参数 在 C98/03 标准中,类模板可以有默认的模板参数,如下: template <typename T, typename U int, U N 0> struct TestTemplateStruct {};但是…...

Visual Studio Code 常见的配置、常用好用插件以及【vsCode 开发相应项目推荐安装的插件】
一、VsCode 常见的配置 1、取消更新 把插件的更新也一起取消了 2、设置编码为utf-8:默认就是了,不用设置了 3、设置常用的开发字体:Consolas, 默认就是了,不用设置了 字体对开发也很重要,不同字体,字母形…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...