Three cannon-es 基础使用示例详解

 更新时间:2024年05月21日 11:45:13   作者:灵魂清零  
Cannon.js可以在多种浏览器上运行,并且支持移动设备和桌面设备,这使得开发者可以轻松地在各种平台上开发和运行物理模拟应用程序,这篇文章主要介绍了Three cannon-es 基础使用,需要的朋友可以参考下

Cannon.js的特点

1、轻量级和高性能:Cannon.js被设计为一个快速而轻便的物理引擎,代码简洁且易于理解。

2、真实的物理模拟:Cannon.js提供了一套完整的3D物理模拟功能,包括刚体碰撞、力学模拟和约束等。这使得开发者可以模拟真实世界中的物理效果。

3、灵活的约束系统:Cannon.js的约束系统非常灵活,并且支持各种类型的约束,如距离约束、弹簧约束、旋转约束等。开发者可以根据需要创建各种类型的约束。

4、基于WebGL:Cannon.js与WebGL技术结合使用,可以轻松实现在浏览器中展示3D物理效果,并且与其他WebGL应用程序进行集成。

5、跨平台兼容性:Cannon.js可以在多种浏览器上运行,并且支持移动设备和桌面设备。这使得开发者可以轻松地在各种平台上开发和运行物理模拟应用程序。

cannon-es安装和引入

可以通过npm命令行安装cannon.js模块。

npm install --save cannon-es

在html和js文件中分别引入 cannon-es,three 和 three/jsm 是引入three中的实例的

<script type="importmap">
    {
      "imports": {
        "three": "../js/three.module.js",
        "three/jsm/": "../js/jsm/",
        "cannon-es": "../node_modules/cannon-es/dist/cannon-es.js"
      }
    }
</script>

在js中全局引入

import * as Cannon from 'cannon-es'

初始工作

创建我们的3D环境,引入3D 实例。

import * as THREE from 'three'
import * as Cannon from 'cannon-es'
import { OrbitControls } from '../../js/jsm/controls/OrbitControls.js'
// 目标:物理引擎 common-es 使用
// 1. 下载引入 cannon-es 包
// 2. 准备球体,地面,灯光和阴影
// 3. 基于 cannon 创建物理世界,创建物理世界的小球(图形+材质)
// 4. 在渲染循环中更新物理世界内的球体运动轨迹,并影响到 3D 物体(核心思想)
let scene, camera, renderer, controls, ball, floor, world, sphereBody
function init() {
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
    camera.position.set(0, 0, 30)
    renderer = new THREE.WebGLRenderer({ antialias: true })
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.querySelector('#app').appendChild(renderer.domElement)
    renderer.shadowMap.enabled = true
    controls = new OrbitControls(camera, renderer.domElement)
    const axesHelper = new THREE.AxesHelper(5)
    scene.add(axesHelper)
}

一、创建准备球体。网格模型表示一个物体,需要通过几何体Geometry定义Mesh的几何外形,对于Body同样道理,你需要设置物体Body的几何形状。CannonJS定义几何体形状的API有很多种,比如比如长方体Box、球体Sphere等等

因为在场景中已经有了一个球体,现在我们需要在 Cannon.js 的 world 中也创建一个球体。我们需要使用其 Body 类,它可以自由落体并和其他 body 进行碰撞。在创建 body 之前,我们要先定义一个 shape。

//创建屋里小球
const sphereShape = new Cannon.Sphere(1)
// 创建物理小球材质
const sphereMaterial = new Cannon.Material();

二、通过Cannon.World类创建一个物理世界。定义物理世界的物理属性,比如设置重力加速度。重力加速度的属性gravity类似body的位置,是一个三维向量Vec3。重力加速度x、y、z分量值,实际开发根据自己项目和坐标系设置即可,咱们假设小球所在的场景,y轴竖直向上,这样重力就速度就是y方向负方向。

world = new Cannon.World({
   // 自由落体加速度
   gravity: new Cannon.Vec3(0, -9.8, 0)
})

三、使用方法.addBody()把物体添加到物理世界,物理球body添加到物理世界中,这样body就会受到物理世界加速度的影响World。

// 创建物理世界
    sphereBody = new Cannon.Body({
        shape: sphereShape,  // 物体形状
        material: sphereMaterial, // 物位材质
        position: new Cannon.Vec3(0,0,0,),
        mass: 1
    })
    // 把物理小球加入到物理世界
    world.addBody(sphereBody)

四、创建一个地面,这样就可以作为球体自由落体的参照物。

floor = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), new THREE.MeshStandardMaterial({color: 0xffff00,}));
    floor.position.set(0, -10, 0);
    floor.rotation.set(-Math.PI/2, 0, 0);
    floor.receiveShadow = true;

五、所有的实例和物体都是离不开光照的,没有光,所有的都是看不到的,所以我们是需要添加光照的。我这里就添加的环境光和灯光。

//环境光
const ambientLingth = new THREE.AmbientLight(0xffffff, 1)
//灯光
const directionLight = new THREE.DirectionalLight(0xffffff, 1)
directionLight.position.set(0, 15, 0)
directionLight.castShadow = true

六、我们需要把我们的球体、地面、环境光、灯光都添加到场景中去。

scene.add(ball)
scene.add(floor)
scene.add(ambientLingth)
scene.add(directionLight)

七、在渲染循环中更新物理世界内的球体运动轨迹,并影响到 3D 物体(核心思想)

const clock = new THREE.Clock()
function renderLoop() {
    // 4. 在渲染循环中更新物理世界内的球体运动轨迹,并影响到 3D 物体(核心思想)
    const time = clock.getDelta()
    // 物理世界不断渲染
    // 参数1:固定步长,间隔多久重绘物理世界
    // 参数2:自上次调用后要经过多长时间
    world.step(1 / 160, time)
    // 把物理世界小球最新位置更新给 3D 物体小球位置
    ball.position.copy(sphereBody.position)
    renderer.render(scene, camera)
    requestAnimationFrame(renderLoop)
}

完整代码和效果图

import * as THREE from 'three'
import * as Cannon from 'cannon-es'
import { OrbitControls } from '../../js/jsm/controls/OrbitControls.js'
// 目标:物理引擎 common-es 使用
// 1. 下载引入 cannon-es 包
// 2. 准备球体,地面,灯光和阴影
// 3. 基于 cannon 创建物理世界,创建物理世界的小球(图形+材质)
// 4. 在渲染循环中更新物理世界内的球体运动轨迹,并影响到 3D 物体(核心思想)
let scene, camera, renderer, controls, ball, floor, world, sphereBody
function init() {
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
    camera.position.set(0, 0, 30)
    renderer = new THREE.WebGLRenderer({ antialias: true })
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.querySelector('#app').appendChild(renderer.domElement)
    renderer.shadowMap.enabled = true
    controls = new OrbitControls(camera, renderer.domElement)
    const axesHelper = new THREE.AxesHelper(5)
    scene.add(axesHelper)
}
const clock = new THREE.Clock()
function renderLoop() {
    // 4. 在渲染循环中更新物理世界内的球体运动轨迹,并影响到 3D 物体(核心思想)
    const time = clock.getDelta()
    // 物理世界不断渲染
    // 参数1:固定步长,间隔多久重绘物理世界
    // 参数2:自上次调用后要经过多长时间
    world.step(1 / 160, time)
    // 把物理世界小球最新位置更新给 3D 物体小球位置
    ball.position.copy(sphereBody.position)
    renderer.render(scene, camera)
    requestAnimationFrame(renderLoop)
}
// 2. 准备球体,地面,灯光和阴影
function createBase () {
    // 球体
    ball = new THREE.Mesh(new THREE.SphereGeometry(1,32, 16), new THREE.MeshStandardMaterial({color: 0xffff00,}));
    ball.castShadow = true
    // 地面
    floor = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), new THREE.MeshStandardMaterial({color: 0xffff00,}));
    floor.position.set(0, -10, 0);
    floor.rotation.set(-Math.PI/2, 0, 0);
    floor.receiveShadow = true;
    //环境光
    const ambientLingth = new THREE.AmbientLight(0xffffff, 1)
    //灯光
    const directionLight = new THREE.DirectionalLight(0xffffff, 1)
    directionLight.position.set(0, 15, 0)
    directionLight.castShadow = true
    scene.add(ball)
    scene.add(floor)
    scene.add(ambientLingth)
    scene.add(directionLight)
}
// 3. 基于 cannon 创建物理世界
function createWorld () {
    world = new Cannon.World({
        // 自由落体加速度
        gravity: new Cannon.Vec3(0, -9.8, 0)
    })
    //创建屋里小球
    const sphereShape = new Cannon.Sphere(1)
    // 创建物理小球材质
    const sphereMaterial = new Cannon.Material();
    // 创建物理世界
    sphereBody = new Cannon.Body({
        shape: sphereShape,  // 物体形状
        material: sphereMaterial, // 物位材质
        position: new Cannon.Vec3(0,0,0,),
        mass: 1
    })
    // 把物理小球加入到物理世界
    world.addBody(sphereBody)
}
init()
createBase()
createWorld()
setTimeout(() => {
    renderLoop()
},1000)

到此这篇关于Three cannon-es 基础使用的文章就介绍到这了,更多相关Three cannon-es 使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • layUI布局使用教程

    layUI布局使用教程

    layui属于轻量级框架,简单美化.是用于开发后端模式,它在服务端页面上有非常好的效果,这篇文章主要介绍了layUI布局使用教程,需要的朋友可以参考下
    2022-09-09
  • 微信小程序 数据缓存实现方法详解

    微信小程序 数据缓存实现方法详解

    这篇文章主要介绍了微信小程序 数据缓存实现方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • IE6弹出“已终止操作”的解决办法

    IE6弹出“已终止操作”的解决办法

    导致这个问题产生的原因,一般是因为js(一个比较复杂的js)写在body里面,在body元素加载完之前调用出现问题。显然,解决该问题的方法就是将这一段js放在body元素解析完毕之后。
    2010-11-11
  • html的DOM中Event对象onblur事件用法实例

    html的DOM中Event对象onblur事件用法实例

    这篇文章主要介绍了html的DOM中Event对象onblur事件用法,实例分析了onblur事件的使用范围与对应的javascript使用技巧,需要的朋友可以参考下
    2015-01-01
  • 微信小程序在text文本实现多种字体样式

    微信小程序在text文本实现多种字体样式

    这篇文章主要介绍了微信小程序在text文本实现多种字体样式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • js 页面刷新location.reload和location.replace的区别小结

    js 页面刷新location.reload和location.replace的区别小结

    在实际应用的时候,重新刷新页面的时候,我们通常使用: location.reload() 或者是 history.go(0) 来做。下面有一些相关的内容,大家看完了就会有更多的收获。
    2009-12-12
  • 在js中判断checkboxlist(.net控件客户端id)是否有选中

    在js中判断checkboxlist(.net控件客户端id)是否有选中

    添加或修改内容时,需要对关键数据进行判空处理,checkboxlist是否有选择项如何使用js判断实现,接下来为大家详细介绍下实现方法,感兴趣的朋友可以参考下哈
    2013-04-04
  • JavaScript 命名空间 使用介绍

    JavaScript 命名空间 使用介绍

    使用JavaScript实现命名空间就没有这么舒服了,Javascript只有函数作用域,什么块儿啊、神马文件啊统统都认为是一个命名空间的,有时候因为一些重名问题导致的错误让人莫名其妙,难以调试解决
    2013-08-08
  • JS实现动态星空背景效果

    JS实现动态星空背景效果

    这篇文章主要为大家详细介绍了JS实现动态星空背景效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • js实现无刷新监听URL的变化示例代码详解

    js实现无刷新监听URL的变化示例代码详解

    这篇文章主要介绍了js如何无刷新监听URL的变化,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06

最新评论