Cannon-es.js物理引擎中物体动力控制的深度探索

本文目录

  • 前言
  • 1、cannon-es给物体施加力
    • 1.1 前置代码
    • 1.2 效果
    • 1.3 给小球施加力
      • 1. applyForce
        • 效果
      • 2. applyImpulse
        • 效果
      • 3. applyLocalImpulse
        • 效果
      • 4. applyTorque
        • 效果
      • 区别总结

前言

在三维物理引擎的世界里,Cannon-ES以其轻量级和高效能著称,为开发者提供了强大的工具来模拟现实世界中的物理现象。本指南将带您深入探索Cannon-ES中如何给物体施加不同类型的力,从而控制其动态行为。从基础的applyForce到瞬间的applyImpulse,再到局部坐标系下的applyLocalImpulse,以及改变物体旋转的applyTorque,我们将逐一解析这些方法的用法、效果及其之间的区别。
通过前置代码的搭建,您将能够快速上手并理解每个方法的基本使用方式。随后,我们将通过实际示例展示如何给小球施加不同类型的力,并观察其产生的不同效果。这不仅能帮助您理解物理引擎背后的原理,还能激发您在游戏开发、物理模拟等领域的创造力。
让我们一同踏上这段探索之旅,掌握Cannon-ES中物体动力控制的精髓,为您的项目增添更多生动与真实感。

1、cannon-es给物体施加力

1.1 前置代码

<template><canvas ref="cannonDemo" class="cannonDemo"></canvas>
</template><script setup>
import { onMounted, ref } from "vue"
import * as THREE from 'three'
import * as CANNON from 'cannon-es'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
const cannonDemo = ref('null')onMounted(() => {const cannonDemoDomWidth = cannonDemo.value.offsetWidthconst cannonDemoDomHeight = cannonDemo.value.offsetHeight// 创建场景const scene = new THREE.Scene// 创建相机const camera = new THREE.PerspectiveCamera( // 透视相机45, // 视角 角度数cannonDemoDomWidth / cannonDemoDomHeight, // 宽高比 占据屏幕0.1, // 近平面(相机最近能看到物体)1000, // 远平面(相机最远能看到物体))camera.position.set(0, 2, 30)// 创建渲染器const renderer = new THREE.WebGLRenderer({antialias: true, // 抗锯齿canvas: cannonDemo.value})// 设置设备像素比renderer.setPixelRatio(window.devicePixelRatio)// 设置画布尺寸renderer.setSize(cannonDemoDomWidth, cannonDemoDomHeight)const light = new THREE.AmbientLight(0x404040, 200); // 柔和的白光scene.add(light);let meshes = []let phyMeshes = []// 创建物理世界开始const physicsWorld = new CANNON.World()// 设置y轴重力physicsWorld.gravity.set(0, -9.82, 0)// 创建物理材料const groundMaterial = new CANNON.Material('groundMaterial')groundMaterial.friction = 1groundMaterial.restitution = 1 // 反弹系数const planeShape = new CANNON.Plane()// 创建物理地面const groundBody = new CANNON.Body({mass: 0, // 为0表示地面不受重力影响shape: planeShape,position: new CANNON.Vec3(0, 0, 0),material: groundMaterial,})groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0)physicsWorld.addBody(groundBody)// 设置球体材质const sphereMaterial = new CANNON.Material('sphereMaterial')sphereMaterial.friction = 0 // 摩擦系数sphereMaterial.restitution = 0 // 反弹系数// 创建球体刚体const sphereShape = new CANNON.Sphere(1) // 创建球体形状,并且传递半径跟threejs中的小球半径一致const sphereBody = new CANNON.Body({mass: 1,position: new CANNON.Vec3(0, 1, 0),material: sphereMaterial,shape: sphereShape})physicsWorld.addBody(sphereBody)phyMeshes.push(sphereBody)// 物理世界结束// 场景世界开始const axesHelper = new THREE.AxesHelper( 15 );scene.add( axesHelper );// 地面const plane = new THREE.Mesh(new THREE.PlaneGeometry(30, 30),new THREE.MeshBasicMaterial({wireframe: true}))plane.rotation.x = -Math.PI/2// 添加到场景中scene.add(plane)// 小球 const sphere = new THREE.Mesh(new THREE.SphereGeometry(1, 20, 10),new THREE.MeshBasicMaterial({ color: 0xff0000,wireframe: true}))scene.add(sphere)meshes.push(sphere)// 场景世界结束 const updatePhysic = () => { // 因为这是实时更新的,所以需要放到渲染循环动画animate函数中physicsWorld.step(1 / 60)for (let i = 0; i < phyMeshes.length; i++) {meshes[i].position.copy(phyMeshes[i].position)meshes[i].quaternion.copy(phyMeshes[i].quaternion)}}// 控制器const control = new OrbitControls(camera, renderer.domElement)// 开启阻尼惯性,默认值为0.05control.enableDamping = true// 渲染循环动画function animate() {// 在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)requestAnimationFrame(animate)updatePhysic()// 更新控制器。如果没在动画里加上,那必须在摄像机的变换发生任何手动改变后调用control.update()renderer.render(scene, camera)}// 执行动画animate()
})
</script>
<style scoped>
.cannonDemo {width: 100vw;height: 100vh;
}
</style>

1.2 效果

请添加图片描述
可以看到我们的场景中有一个线框小球。

1.3 给小球施加力

在cannon-es这个3D物理引擎中,applyForce、applyImpulse、applyLocalImpulse和applyTorque是用于控制刚体动态行为的重要方法。它们各自具有不同的用途、参数使用方式和效果。以下是这四个方法的详细解释、区别以及参数使用方法的说明:

1. applyForce

  • 作用applyForce方法用于在刚体上施加一个持续的力。这个力会按照物理学的原理(F=ma)逐渐改变刚体的速度和运动状态。

  • 参数

    • force:一个CANNON.Vec3向量,表示要施加的力的大小和方向。
    • worldPoint(可选):一个CANNON.Vec3向量,表示力作用在刚体上的世界坐标系中的点。如果不提供此参数,则默认作用在刚体的质心上。
  • 使用示例

      const force = new CANNON.Vec3(50, 0, 0); // 在X轴上施加一个100单位的力sphereBody.applyForce(force, new CANNON.Vec3(0, -1, 0)); // 将力作用在刚体的当前位置
    

    力作用在小球的正中心底部,它就会形成回旋向前进

    效果

    请添加图片描述

2. applyImpulse

  • 作用applyImpulse方法用于在刚体上施加一个瞬间的冲量。这个冲量会直接影响刚体的速度,使其立即获得一个速度增量。
  • 参数
    • impulse:一个CANNON.Vec3向量,表示要施加的冲量的大小和方向。
    • worldPoint(可选):与applyForce相同,表示冲量作用在刚体上的世界坐标系中的点。
  • 使用示例
      const impulse = new CANNON.Vec3(5, 0, 0); // 在x轴上施加一个5单位的冲量sphereBody.applyImpulse(impulse, sphereBody.position); // 将冲量作用在刚体的当前位置
    
    效果
    请添加图片描述

3. applyLocalImpulse

  • 作用applyLocalImpulse方法与applyImpulse类似,也是用于施加瞬间的冲量,但不同之处在于它接受的是局部坐标系下的冲量向量。
  • 参数
    • localImpulse:一个CANNON.Vec3向量,表示在刚体局部坐标系中要施加的冲量的大小和方向。
    • localPoint(可选):一个CANNON.Vec3向量,表示冲量作用在刚体上的局部坐标系中的点。如果不提供此参数,则默认作用在刚体的局部质心上。
  • 使用示例
        const localImpulse = new CANNON.Vec3(0, 0, 9); // 在刚体局部坐标系的Z轴上施加一个9单位的冲量sphereBody.applyLocalImpulse(localImpulse, new CANNON.Vec3()); // 默认作用在局部质心上
    
    效果
    请添加图片描述

4. applyTorque

  • 作用applyTorque方法用于在刚体上施加一个力矩,使其产生旋转。这个力矩会改变刚体的角速度和旋转方向。
  • 参数
    • torqueCANNON.Vec3,表示要施加的力矩的大小和方向。力矩的方向遵循右手定则,即右手四指从力矩的起点指向终点,大拇指的方向即为力矩的旋转方向。
  • 使用示例
      const torque = new CANNON.Vec3(0, 0, 100); // 在Z轴上施加一个使刚体绕Z轴旋转的力矩sphereBody.applyTorque(torque); // 施加力矩
    
    效果
    请添加图片描述

区别总结

方法作用特点参数
applyForce施加持续的力渐进改变速度force(必需),worldPoint(可选)
applyImpulse施加瞬间的冲量立即改变速度impulse(必需),worldPoint(可选)
applyLocalImpulse施加瞬间的冲量(局部坐标系)立即改变速度,冲量在局部坐标系中定义localImpulse(必需),localPoint(可选)
applyTorque施加力矩改变角速度和旋转方向torque(必需)

在使用这些方法时,需要注意以下几点:

  • 力的方向和大小、冲量的大小和方向、力矩的大小和方向都是通过CANNON.Vec3向量来指定的,该向量包含X、Y、Z三个分量。
  • 力的作用点和冲量的作用点可以是刚体上的任意点,但如果不指定,则默认作用在刚体的质心上。对于力矩,它总是绕刚体的质心旋转,因为力矩的作用点默认是质心。
  • 施加力、冲量或力矩后,刚体的运动状态会相应地发生变化,包括速度、角速度等。
  • 在使用applyLocalImpulse时,需要确保提供的冲量向量是在刚体的局部坐标系中定义的。如果刚体发生了旋转,那么局部坐标系也会随之变化。

在学习的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1547255.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

使用docker形式部署prometheus+alertmanager+钉钉告警

一、拉取所需要的镜像 docker pull prom/node-exporter docker pull grafana/grafana docker pull prom/prometheus docker pull prom/alertmanager 其中 prom/node-exporter&#xff1a;用于收集主机系统信息和指标的 grafana/grafana&#xff1a;是一个用于可视化和分…

NRF21540—低功耗蓝牙,蓝牙mesh、Thread和Zigbee和2.4 GHz私有协议范围扩展射频前端模块

nRF21540是一款射频前端模块(FEM)&#xff0c;可用于改善短距离无线产品的传输范围和连接鲁棒性。作为一款辅助性设备&#xff0c;nRF21540是一种“即插即用型”的无线传输范围扩展器&#xff0c;可与nRF52和nRF53系列的高级多协议无线SoC搭配使用&#xff0c;所需的外部器件数…

11. Map和Set

一、二叉搜索树 1. 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根…

解析 Pencils Protocol 价值逻辑,$DAPP为何是本轮的Alpha资产?

本轮市场周期中&#xff0c;DeFi市场已经长期处于边缘位置&#xff0c;老牌蓝筹DeFi通证仍旧能维持高市值但币价增长&#xff0c;而很多新生代DeFi项目创新不足难以推动叙事的发展&#xff0c;面向市场后难有亮眼表现&#xff0c;DeFi市场再难寻Alpha投资机会。 而随着Pencils …

C语言指针系列1——初识指针

祛魅&#xff1a;其实指针这块儿并不难&#xff0c;有人说难只是因为基础到进阶没有处理好&#xff0c;大家要好好跟着一步一步学习&#xff0c;今天我们先来认识一下指针 指针定义&#xff1a;指针就是内存地址&#xff0c;指针变量是用来存放内存地址的变量&#xff0c;在同一…

在Windows系统上安装的 Boost C++ 库

步骤一 https://www.boost.org/users/history/version_1_86_0.html 下载Boost库文件: 步骤二 安装: https://www.boost.org/doc/libs/1_52_0/doc/html/bbv2/installation.html 点击运行.\bootstrap.bat脚本在当前目录的powershell中执行:./b2 install --prefixPREFIX 然后…

【必看】2024国赛选题分布情况分析及数模国赛答辩指南~答辩不走弯路

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 紧张刺激的数模国赛已经过去一段时间&#xff0c;各赛区的成绩发布也在陆续进…

springboot+satoken实现刷新token(值变化)

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 springbootsatoken实现刷新token satoken是什么&#xff1f;支持什么&#xff1f;为什么需要&…

内网穿透的应用-Windows系统安装SeaFile并实现远程访问本地共享文件资料详细教程

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 下载安装3.2 Cpolar注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4.公网访问测试5.结语 1. 前言 本文主要为大家介绍&#xff0c;如何使用两个简单软件…

【Kotlin 集合概述】可变参数vararg、中缀函数infix以及解构声明(二十)

导读大纲 1.1 使用集合: vararg、infix 调用和解构声明1.1.1 扩展 Java 集合 API1.1.2 vararg: 接受任意数量参数的函数1.1.3 处理pairs: Infix 调用和解构声明 1.1 使用集合: vararg、infix 调用和解构声明 本节将介绍 Kotlin 标准库中用于处理集合的一些函数 同时,还介绍一些…

Vue3+Element-UI Plus登录静态页

<script setup> import {reactive, ref} from "vue";const formRefref() const formModelreactive({username:,password: }) const formRulesreactive({username:[{required:true,message:请输入账号,trigger:blur}],password:[{required:true,message:请输入密…

阳光精机第一大客户双刃剑效应:关联交易引关注,产能利用率忽高忽低

《港湾商业观察》杨丹妮 8月27日&#xff0c;北交所向无锡阳光精机股份有限公司&#xff08;以下简称&#xff1a;阳光精机&#xff09;下发第二轮审核问询函&#xff0c;此前阳光精机于2023年12月29日递表北交所。 阳光精机公司主要生产精密主轴、主辊、弧形导轨等机床功能部…

【数据结构】AVL树相关知识详细梳理

1. AVL树的概念 AVL的全称是Adelson-Velsky-Landis&#xff0c;其名称来源于其发明者Adelson、Velsky和Landis&#xff0c; 是平衡二叉树搜索树。 它的出现是由于二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找…

常见的TTL,RS232,RS485,IIC,SPI,UART之间的联系和区别

简单总结 图片来源 RS232,RS485可参考&#xff0c;IIC&#xff0c;SPI,UART可参考 烧录程序中常听到的一句话就是USB转TTL&#xff0c;但严格来说算是USB传输数据的协议转换成TTL&#xff08;Transistor-Transistor Logic&#xff09;协议传输数据。首先&#xff0c;usb是常见…

15、网络安全合规由来与要素

数据来源&#xff1a;1.网络安全合规由来与要素_哔哩哔哩_bilibili 合规由来 合规&#xff08;Compliance&#xff09;&#xff1a;指服从、顺从和遵从的行为&#xff0c;强调使公司的经营活动与法律、监管及内部规则保持一致。合规涉及公司适应法律法规及社会规范等规则的经营…

[附源码]在线音乐系统+SpringBoot+Vue前后端分离

今天带来一款优秀的项目&#xff1a;在线音乐系统源码 。 系统采用的流行的前后端分离结构&#xff0c;内含功能包括 "管理后台"&#xff0c;“用户端”&#xff0c;“评论系统”&#xff0c;“歌手&#xff0c;歌曲管理”&#xff0c;“用户系统”,"统计"…

bugku-头等舱

根据题目提示&#xff0c;查看请求头试一下&#xff0c; 得到flag&#xff0c;直接提交

【JavaScript】LeetCode:56-60

文章目录 56 路径总和Ⅲ57 二叉树的最近公共祖先58 二叉树中的最大路径59 岛屿数量60 腐烂的橘子 56 路径总和Ⅲ 递归遍历每个节点所有可能的路径。pathSum()&#xff1a;返回所有节点满足条件的路径数目&#xff0c;traversal()&#xff1a;返回当前遍历节点满足条件的路径数目…

CloudMusic:免费听歌

本文所涉及所有资源均在 传知代码平台可获取。 目录 概述 演示效果 视频演示 图片展示 核心逻辑 获取歌曲图片 提取搜索结果 使用方式 部署方式 Docker部署1 构建镜像 Web站点部署2 附件下载 概述 CloudMusic是一款全网歌曲免费听的web项目&#xff0c;无需任何数据库&#x…

19、网络安全合规复盘

数据来源&#xff1a;5.网络安全合规复盘_哔哩哔哩_bilibili