Threejs入门之二十三:Threejs中的物理引擎OimoPhysics

Threejs中的OimoPhysics插件为我们提供了一个三维的物理世界,它可以帮助我们实现物理效果(如重力、弹力、加速度、摩擦力、碰撞等),并将物理世界中运动的每一帧的位置信息都映射到我们通过Threejs创建的三维世界中,从而在三维世界中实现现实中的物理效果。下面通过一个小球下落的例子来了解下OimoPhysics插件

引入OimoPhysics插件

OimoPhysics插件位于three.js—examples—jsm—physics路径下,使用时需要先引入该插件
首先在index.html中以以下方式引入Threejs

//index.html
<body> 
  <script type="importmap">
    {
      "imports":{
        "three":"../../three.js/build/three.module.js",
        "three/addons/": "../../three.js/examples/jsm/"
      }
    }
  </script>
  <script type="module" src="./index.js"></script>
</body> 

然后在index.js中引入OimoPhysics

import { OimoPhysics } from 'three/addons/physics/OimoPhysics.js';  

创建场景、相机、渲染器等

创建三维场景,具体方式前面章节已经介绍过了,不了解的可以看其它章节,这里就不一一介绍了,只贴出代码部分

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { OimoPhysics } from 'three/addons/physics/OimoPhysics.js';  
// 定义变量
let camera, scene, renderer
let axesHelper
let hesLight, dirLight 
let controls 

// 初始化渲染器
initRenderer()
// 初始化相机
initCamera()
// 初始化场景
initScene()
// 初始化灯光
initLight() 
// 初始化辅助轴
initAxesHelper()
// 初始化轨道控制器
initControl()
// 打开阴影
enableShadow() 
// 循环执行
animate()
// 窗体重置
window.addEventListener('resize', function () {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
})
// 初始化渲染器
function initRenderer() {
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

}
// 初始化相机
function initCamera() {
  camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100)
  camera.position.set(4, 4, 4)
}
// 初始化场景
function initScene() {
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x888888)
}
// 初始化辅助轴
function initAxesHelper() {
  axesHelper = new THREE.AxesHelper(1)
  scene.add(axesHelper)
}
// 初始化灯光
function initLight() {
  //环境光
  hesLight = new THREE.HemisphereLight() //白色光
  hesLight.intensity = 0.3
  scene.add(hesLight)
  //平行光
  dirLight = new THREE.DirectionalLight() //太阳光
  dirLight.position.set(5, 5, -5)
  scene.add(dirLight)
} 
// 初始化轨道控制器
function initControl() {
  controls = new OrbitControls(camera, renderer.domElement)
}
//打开阴影
function enableShadow() {
  renderer.shadowMap.enabled = true
  dirLight.castShadow = true 
} 
// 循环执行
function animate() {
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
}

创建物体

定义变量
定义一个变量ball,用于接收一个球形物体的实例

let ball

初始化物体
编写初始化物体 initMeshes() 函数

// 初始化物体
function initMeshes() {
  ball = new THREE.Mesh(
    new THREE.SphereGeometry(0.05,32,16),
    new THREE.MeshLambertMaterial()
  )
  ball.position.set(0,2,0)
  scene.add(ball) 
}

调用初始化物体函数

// 初始化物体
initMeshes()

此时运行浏览器,发现我们创建的小球已经出现在了浏览器上
在这里插入图片描述

使用OimoPhysics物理引擎插件

OimoPhysics 提供的是一个异步函数,我们可以直接调用它
OimoPhysics 提供了一个addMesh方法,通过该方法,可以将物体添加到OimoPhysics 创建的物理世界中,addMesh有两个参数,第一个参数是我们创建的物体模型,第二个参数代表该物体是否参与物理世界的运动,默认为0,即不参与,设置为1表示参与

前面我们已经引入了 OimoPhysics 插件,这里我们来使用它实现小球下落的过程
由于其是异步函数,我们通过await在等待其执行结果
首先我们新建一个变量来接收OimoPhysics 执行的结果

let physics

创建一个 enablePhysics() 函数,并调用OimoPhysics

async function enablePhysics() {
  physics = await OimoPhysics() 
  physics.addMesh(ball) 
}

创建完成后,刷新浏览器,我们发现页面没有任何变化,这是因为我们在addMesh方法中,没有设置第二个参数,默认为0,即代表小球不参与物理世界的运动,我们把其设置为1,

async function enablePhysics() {
  physics = await OimoPhysics() 
  //physics.addMesh(ball) 
  physics.addMesh(ball,1)
}

刷新浏览器,我们看到小球有了下落的效果,但是,我们发现小球会一直下落,这不是我们想要的,
在这里插入图片描述
我们希望实现小球落到地面的效果,所以,我们还要创建一个地面
创建变量floor

let floor

在initMeshes中创建地面

 // 地面
  floor = new THREE.Mesh(
    new THREE.BoxGeometry(10,1,10),
    new THREE.ShadowMaterial({color:0x111111}) //影子的颜色

  )
  floor.position.set(0,-1,0)
  scene.add(floor)

在enablePhysics中将地面也加入到物理引擎中

async function enablePhysics() {
  physics = await OimoPhysics() 
  physics.addMesh(floor) //添加一个地面 --(第二个参数不写,表示为刚体)  
  physics.addMesh(ball,1) 
}

刷新浏览器,可以看到小球下落到地面时就不会继续下落了,实现了我们想要的效果
在这里插入图片描述
给我们添加阴影
为了使效果更真实,我们给小球添加阴影
在enableShadow()中开启地面接收阴影和小球投射阴影效果

floor.receiveShadow = true 
 ball.castShadow = true

刷新浏览器,看效果
在这里插入图片描述
好了,关于OimoPhysics插件的使用,就到这里吧,喜欢的朋友点赞关注收藏哦

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九仞山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值