AmmoPhysics 是一个异步函数,用于创建 Ammo.js 物理引擎的实例

本文介绍了AmmoPhysics,一个用于在THREE.js中创建物理引擎实例的异步函数,包括其参数、返回值以及关键方法如添加和移除场景、设置实例化网格的位置、旋转和缩放。
摘要由CSDN通过智能技术生成

demo案例
在这里插入图片描述

AmmoPhysics 是一个异步函数,用于创建 Ammo.js 物理引擎的实例。让我们逐个讲解其入参、出参、方法和属性:

入参:

  • 无入参。

出参:

  • 返回一个 Promise 对象,该 Promise 对象在解析时会提供 AmmoPhysics 实例。

方法和属性:

  • addScene(scene: THREE.Scene): void

    • 参数:
      • scene:THREE.Scene 类型的场景对象,需要将该场景添加到物理引擎中以实现物理模拟。
    • 描述:将指定的 THREE.Scene 场景对象添加到物理引擎中,以便对其中的物体进行物理模拟。
  • setMeshPosition(mesh: THREE.InstancedMesh, position: THREE.Vector3, index: number): void

    • 参数:
      • mesh:THREE.InstancedMesh 类型的实例化网格对象,表示要设置位置的网格。
      • position:THREE.Vector3 类型的位置向量,表示要设置的新位置。
      • index:数字类型,表示要设置位置的实例在网格中的索引。
    • 描述:设置实例化网格中指定索引的实例的位置。
  • setMeshRotation(mesh: THREE.InstancedMesh, quaternion: THREE.Quaternion, index: number): void

    • 参数:
      • mesh:THREE.InstancedMesh 类型的实例化网格对象,表示要设置旋转的网格。
      • quaternion:THREE.Quaternion 类型的四元数,表示要设置的新旋转。
      • index:数字类型,表示要设置旋转的实例在网格中的索引。
    • 描述:设置实例化网格中指定索引的实例的旋转。
  • setMeshScale(mesh: THREE.InstancedMesh, scale: THREE.Vector3, index: number): void

    • 参数:
      • mesh:THREE.InstancedMesh 类型的实例化网格对象,表示要设置缩放的网格。
      • scale:THREE.Vector3 类型的缩放向量,表示要设置的新缩放值。
      • index:数字类型,表示要设置缩放的实例在网格中的索引。
    • 描述:设置实例化网格中指定索引的实例的缩放值。
  • removeScene(scene: THREE.Scene): void

    • 参数:
      • scene:THREE.Scene 类型的场景对象,表示要从物理引擎中移除的场景。
    • 描述:从物理引擎中移除指定的 THREE.Scene 场景对象,停止对其中物体的物理模拟。
  • update(deltaTime: number): void

    • 参数:
      • deltaTime:数字类型,表示自上一帧以来经过的时间(以秒为单位)。
    • 描述:在每一帧中调用此方法以更新物理引擎中的物理模拟。传入的 deltaTime 参数用于控制模拟的运行速度。

demo 源码

<!DOCTYPE html>
<html lang="en">
<head>
	<title>three.js physics - ammo.js instancing</title>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
	<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>

	<div id="info">
		<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> physics - ammo.js instancing
	</div>

	<script src="jsm/libs/ammo.wasm.js"></script>

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

	<script type="module">

		import * as THREE from 'three'; // 导入 three.js 库
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 导入 OrbitControls 控制器
		import { AmmoPhysics } from 'three/addons/physics/AmmoPhysics.js'; // 导入 AmmoPhysics 物理引擎
		import Stats from 'three/addons/libs/stats.module.js'; // 导入性能统计库

		let camera, scene, renderer, stats; // 声明相机、场景、渲染器和性能统计对象
		let physics, position; // 声明物理引擎和位置向量

		let boxes, spheres; // 声明盒子和球体对象

		init(); // 调用初始化函数

		async function init() {

			physics = await AmmoPhysics(); // 等待物理引擎加载完毕
			position = new THREE.Vector3(); // 创建一个位置向量

			//

			camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); // 创建透视相机
			camera.position.set(-1, 1.5, 2); // 设置相机位置
			camera.lookAt(0, 0.5, 0); // 设置相机焦点

			scene = new THREE.Scene(); // 创建场景
			scene.background = new THREE.Color(0x666666); // 设置场景背景颜色

			const hemiLight = new THREE.HemisphereLight(); // 创建半球光源
			scene.add(hemiLight); // 将半球光源添加到场景中

			const dirLight = new THREE.DirectionalLight(0xffffff, 3); // 创建定向光源
			dirLight.position.set(5, 5, 5); // 设置光源位置
			dirLight.castShadow = true; // 光源产生阴影
			dirLight.shadow.camera.zoom = 2; // 设置阴影相机缩放比例
			scene.add(dirLight); // 将定向光源添加到场景中

			const floor = new THREE.Mesh( // 创建地面
				new THREE.BoxGeometry(10, 5, 10), // 地面几何体
				new THREE.ShadowMaterial({ color: 0x444444 }) // 地面材质
			);
			floor.position.y = -2.5; // 设置地面位置
			floor.receiveShadow = true; // 地面接收阴影
			floor.userData.physics = { mass: 0 }; // 设置地面的物理属性
			scene.add(floor); // 将地面添加到场景中

			//

			const material = new THREE.MeshLambertMaterial(); // 创建兰伯特材质

			const matrix = new THREE.Matrix4(); // 创建变换矩阵
			const color = new THREE.Color(); // 创建颜色对象

			// Boxes

			const geometryBox = new THREE.BoxGeometry(0.075, 0.075, 0.075); // 创建盒子几何体
			boxes = new THREE.InstancedMesh(geometryBox, material, 400); // 创建盒子实例化网格
			boxes.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // 设置实例矩阵的使用方式,每帧更新
			boxes.castShadow = true; // 盒子投射阴影
			boxes.receiveShadow = true; // 盒子接收阴影
			boxes.userData.physics = { mass: 1 }; // 设置盒子的物理属性
			scene.add(boxes); // 将盒子添加到场景中

			for (let i = 0; i < boxes.count; i++) { // 遍历每个盒子实例

				matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); // 设置盒子的随机位置
				boxes.setMatrixAt(i, matrix); // 设置盒子的变换矩阵
				boxes.setColorAt(i, color.setHex(0xffffff * Math.random())); // 设置盒子的随机颜色

			}

			// Spheres

			const geometrySphere = new THREE.IcosahedronGeometry(0.05, 4); // 创建球体几何体
			spheres = new THREE.InstancedMesh(geometrySphere, material, 400); // 创建球体实例化网格
			spheres.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // 设置实例矩阵的使用方式,每帧更新
			spheres.castShadow = true; // 球体投射阴影
			spheres.receiveShadow = true; // 球体接收阴影
			spheres.userData.physics = { mass: 1 }; // 设置球体的物理属性
			scene.add(spheres); // 将球体添加到场景中

			for (let i = 0; i < spheres.count; i++) { // 遍历每个球体实例

				matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); // 设置球体的随机位置
				spheres.setMatrixAt(i, matrix); // 设置球体的变换矩阵
				spheres.setColorAt(i, color.setHex(0xffffff * Math.random())); // 设置球体的随机颜色

			}

			physics.addScene(scene); // 将场景添加到物理引擎中

			//

			renderer = new THREE.WebGLRenderer({ antialias: true }); // 创建 WebGL 渲染器
			renderer.setPixel

Ratio(window.devicePixelRatio); // 设置像素比例
			renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染器尺寸
			renderer.shadowMap.enabled = true; // 启用阴影
			document.body.appendChild(renderer.domElement); // 将渲染器元素添加到文档中

			stats = new Stats(); // 创建性能统计对象
			document.body.appendChild(stats.dom); // 将性能统计元素添加到文档中

			//

			const controls = new OrbitControls(camera, renderer.domElement); // 创建轨道控制器
			controls.target.y = 0.5; // 设置控制器焦点
			controls.update(); // 更新控制器

			animate(); // 调用动画函数

			setInterval(() => {

				let index = Math.floor(Math.random() * boxes.count); // 随机获取盒子索引

				position.set(0, Math.random() + 1, 0); // 设置随机位置
				physics.setMeshPosition(boxes, position, index); // 设置盒子位置

				//

				index = Math.floor(Math.random() * spheres.count); // 随机获取球体索引

				position.set(0, Math.random() + 1, 0); // 设置随机位置
				physics.setMeshPosition(spheres, position, index); // 设置球体位置

			}, 1000 / 60); // 每 1/60 秒执行一次

		}

		function animate() {

			requestAnimationFrame(animate); // 请求动画帧

			renderer.render(scene, camera); // 渲染场景

			stats.update(); // 更新性能统计

		}

	</script>
</body>
</html>

本内容来源于小豆包,想要更多内容请跳转小豆包 》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小豆包3D世界

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

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

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

打赏作者

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

抵扣说明:

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

余额充值