vetor

new CANNON.ContactMaterial构造方法用于设置Three、物理世界两种材质碰撞的参数

const defaultContactMaterial = new CANNON.ContactMaterial(cubeMaterial, // three中的要碰撞的物体材质floorMaterial, // 物理世界的平面材质{friction: 0.4, // 摩擦力restitution: 0.6, // 弹性}
)// 将材料的关联设置添加到物理世界
world.addContactMaterial(defaultContactMaterial)

物体碰撞后的旋转效果,同下落的效果一致,copy物理引擎物体对应参数

渲染的three物体.quaternion.copy(物理世界的物体.quaternion)

物理运动过程中添加外力,可以看到视频中的下坠方向并不是原本的垂直向下,这是因为施加了一个运动到x方向300像素的外力

    物理物体.applyLocalForce(new CANNON.Vec3(300, 0, 0), // 添加的力的大小和方向new CANNON.Vec3(0, 0, 0) // 添加的力的所在的位置)

每次点击屏幕,生成一个物体(渲染物体、物理引擎物体)的封装

import * as THREE from 'three'
import { Mesh, SphereGeometry, TextureLoader } from 'three'
// 导入轨道控制器 (类)
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// 导入动画库
import gsap from 'gsap'
// 导入cannon3D引擎
import * as CANNON from "cannon-es"
console.log(CANNON);// 创建场景
const scene = new THREE.Scene()
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 300)
// 设置相机位置 x, y, z
camera.position.set(0, 0, 18)
scene.add(camera)let manyCube = []
const cubeMaterial = new THREE.MeshStandardMaterial()
const createCube = () => { // 每次点击重新生成一个立方体,包含three和物理世界的,// three几何体const cubeGeometry = new THREE.BoxGeometry(1, 1, 1)const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)cube.castShadow = truescene.add(cube)// 物理几何体const cubeShape = new CANNON.Box(new CANNON.Vec3(0.5, 0.5, 0.5)) // 宽高为1的正方体, 参数要写为宽高的一半// 设置物体材质const cubeWorldMaterial = new CANNON.Material('cube')// 创建物理世界的物体,类似于假世界的 Mesh步骤const cubeBody = new CANNON.Body({shape: cubeShape,position: new CANNON.Vec3(0, 0, 0),mass: 1, // (相互碰撞会有什么效果)material: cubeWorldMaterial, // 材质})cubeBody.applyLocalForce(new CANNON.Vec3(300, 0, 0), // 添加的力的大小和方向new CANNON.Vec3(0, 0, 0) // 添加的力的所在的位置)// 将物体添加到物理世界world.addBody(cubeBody)// 创建碰撞声音const hitSound = new Audio(require('../assets/audio/hai.mp3'))// 监听物理小球碰撞事件        function HitEvent(e) {console.log(e);const impactStrength = e.contact.getImpactVelocityAlongNormal() // 获取碰撞的强度console.log(impactStrength); // 两次碰撞,第一次8.1, 第二次1.1if (impactStrength > 2) {hitSound.currentTime = 0 // 重新从0开始播放hitSound.volume = impactStrength / 15 // 设置音量 0~1hitSound.play() // 碰撞时播放声音 }}cubeBody.addEventListener('collide', HitEvent) // 碰撞反弹了几下,就会执行几下manyCube.push({three: cube,body: cubeBody})
}// 创建物理世界
const world = new CANNON.World()
world.gravity.set(0, -9.8, 0) // 设置世界重力,y向下为负,真实世界重力加速度为9.8NMcreateCube()window.addEventListener('click', createCube)// three平面
const floor = new THREE.Mesh(new THREE.PlaneGeometry(20, 20),new THREE.MeshStandardMaterial()
)
floor.position.set(0, -5, 0)
floor.rotation.x = -Math.PI / 2
floor.receiveShadow = true
scene.add(floor)// 开启灯光, 添加环境光和平行光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)
const dirLight = new THREE.DirectionalLight(0xffffff, 0.5)
dirLight.castShadow = true
scene.add(dirLight)// 物理世界地面
const floorShape = new CANNON.Plane()
const floorBody = new CANNON.Body()
const floorMaterial = new CANNON.Material('floor') // 构建地面材质
floorBody.material = floorMaterial
floorBody.mass = 0 // 质量为0时,可以让物体保持不动,不管怎么碰撞都是不动的
floorBody.addShape(floorShape) // 添加平面模型
floorBody.position.set(0, -5, 0)
// 旋转地面的位置 (以三维向量的x轴旋转 -90度)类似于threejs中的ratation.x = ...旋转
floorBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2)
world.addBody(floorBody)// 设置两种材质碰撞的参数
const defaultContactMaterial = new CANNON.ContactMaterial(cubeMaterial, // three中的要碰撞的物体材质floorMaterial, // 物理世界的平面材质{friction: 0.4, // 摩擦力restitution: 0.6, // 弹性}
)// 将材料的关联设置添加到物理世界
world.addContactMaterial(defaultContactMaterial)// 设置事件碰撞默认材料,如果材料没有设置都用这个
world.defaultContactMaterial = defaultContactMaterial// 初始化渲染器
const renderer = new THREE.WebGLRenderer({ alpha: true })
renderer.shadowMap.enabled = true
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
// 将webgl渲染的canvas内容添加到body上
document.body.appendChild(renderer.domElement)// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
// 开启控制器阻尼,更有真实效果,有惯性(设置的同时还需要在render请求动画函数中设置update更新方法才会生效)
controls.enableDamping = true// 设置坐标轴辅助器 AxesHelper( size : Number ) 代表轴的线段长度,默认为1
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);// 设置时钟
const clock = new THREE.Clock()
const render = () => {let time = clock.getElapsedTime()let deltaTime = clock.getDelta()// 更新物理引擎世界的物体world.step(1 / 120, 0.02) // 每帧渲染120次 // 将物理世界小球位置坐标赋值给普通小球// cube.position.copy(cubeBody.position)manyCube.forEach(item => {item.three.position.copy(item.body.position)// 设置渲染的物体跟随物理的物体旋转item.three.quaternion.copy(item.body.quaternion)})controls.update()renderer.render(scene, camera)requestAnimationFrame(render) // 请求动画会给render传递一个时间,为当前请求动画帧执行的毫秒数
}
render()// 监听页面尺寸变化,更新渲染页面
window.addEventListener('resize', () => {// 更新摄像头的位置camera.aspect = window.innerWidth / window.innerHeight// 更新摄像机的投影矩阵camera.updateProjectionMatrix()// 更新渲染器renderer.setSize(window.innerWidth, window.innerHeight)// 设置渲染器的像素比renderer.setPixelRatio(window.devicePixelRatio)
})

Three.js物理引擎与物体的相互作用——关联材质对摩擦力弹性影响、物体运动方式、作用力相关相关推荐

  1. cocos2d - JS 物理引擎 - chipmunk

    物理引擎 - chipmunk : 生成物理世界 : 第一步 : 新建项目打开 project.json 将chipmunk模块导入 . "modules" : ["co ...

  2. JS物理引擎p2.js中文文档

    本文复制于Github p2.js项目的中文维基页面,鉴于国内访问Github网速不稳定,特粘贴到CSDN,促进知识更快传播,也希望有能力者继续完善此文档. 以下是原文,更新内容请查阅Github p ...

  3. 【Canvas】HTML5游戏开发的基本流程+P2.js物理引擎实战开发

    <HTML5游戏开发的基本流程> * 1. HTML5的简述 * 2. HTML5游戏开发所需的环境与工具 * 2.1. 开发环境 * 2.1.1. 浏览器 * 2.1.2. 开发语言 * ...

  4. 一篇上手LayaAir的3D物理引擎

    昨天,我们分享了一篇2D物理文档<LayaAirIDE的可视化2D物理使用文档>. 今天,我们针对LayaAir引擎的初学者,以及对物理引擎使用不熟悉的开发者,再来分享一篇3D物理文档,本 ...

  5. cocos2dx-3.x物理引擎Box2D介绍

    原文:https://www.cnblogs.com/yyxt/p/4561410.html 理引擎 Cocos2d-x引擎内置了两种物理引擎,它们分别是Box2D和Chipmunk,都是非常优秀的2 ...

  6. Cocos2d-x学习笔记(十五)--------物理引擎

    物理引擎 Cocos2d-x引擎内置了两种物理引擎,它们分别是Box2D和Chipmunk,都是非常优秀的2D物理引擎,而且x引擎将它们都内置在SDK中.Box2D使用较为广泛,在这里选择Box2D来 ...

  7. Cocos2dx物理引擎碰撞检测总结

     通常在游戏简单逻辑判断和模拟真实的物理世界时,我们只需要在定时器中判断游戏中各个精灵的条件是否满足判断条件就可以了.例如,在飞机大战中,判断我方子弹和敌机是否发生碰撞一般在定时器中通过敌机所在位 ...

  8. cocos2dx3.x物理引擎的碰撞检测

    这两天看了下,所以当个笔记,转载自:点击打开链接 通常在游戏简单逻辑判断和模拟真实的物理世界时,我们只需要在定时器中判断游戏中各个精灵的条件是否满足判断条件就可以了.例如,在飞机大战中,判断我方子弹和 ...

  9. 使用物理引擎进行碰撞检测

    通常在游戏简单逻辑判断和模拟真实的物理世界时,我们只需要在定时器中判断游戏中各个精灵的条件是否满足判断条件就可以了.例如,在飞机大战中,判断我方子弹和敌机是否发生碰撞一般在定时器中通过敌机所在位置的矩 ...

最新文章

  1. 超图Cesium量算
  2. 关于web应用程序的安全验证
  3. java 取余_JAVA面试解析(有赞)
  4. Redhat 设置cntlm代理步骤
  5. Eclipse如何关闭在RUN/DEBUG时弹出窗口?
  6. 如何设置dedecms自定义表单必填项?
  7. AWS CSAA -- 04 AWS Object Storage and CDN - S3 Glacier and CloudFront(二)
  8. 借贷记账思考2015.12.28
  9. apkg格式怎么打开_jpg怎么转换成pdf?再不学就晚了
  10. ansys在求解过程中死机关机的解决办法
  11. 罗技无线网卡linux,Linux(Ubuntu)装罗技LMS避坑指南
  12. SpringBoot项目使用@Value读取配置文件application.yml的值
  13. H5标签 video标签的使用
  14. dubbo教程总结(springboot+dubbo)
  15. BOOTMGR is missing 简单方案
  16. python单引号打不出来_python里单引号怎么打
  17. yum换源/QQ安装
  18. Node.js学习笔记9-将Node应用部署到Docker
  19. 百田游戏策划笔试回忆
  20. jmeter实现websocket聊天室功能

热门文章

  1. APD保护电路优化设计
  2. 多面体及欧拉公式及广义欧拉公式
  3. 基于朴素贝叶斯和LSTM的两种新闻文本分类方法
  4. centos7.6 服务器搭建Java环境(若依--srs)
  5. 计算机二类中文核心期刊,我国科学院计算机网络信息中心在学研究生年终考核奖评定办法(试行).doc...
  6. 某些有趣的API接口(2)
  7. iOS开发 检测网络是否真正可用(真正可以访问互联网)
  8. C语言计算数列1+(1+2)+...+(1+2+...n)的值
  9. 2022-2028全球与中国变压器测试服务市场现状及未来发展趋势
  10. 计量经济学计算机实验,《计量经济学》上机实验答案.doc