学习threejs,使用Physijs物理引擎

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️Physijs 物理引擎
      • 1.1.1 ☘️代码示例
      • 1.1.2 ☘️方法/属性
  • 二、🍀使用Physijs物理引擎
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用Physijs物理引擎,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️Physijs 物理引擎

Three.js 的 Physi.js 是一个基于 Physijs 的物理引擎插件,用于为 Three.js 场景添加物理模拟(如碰撞检测、重力、刚体动力学等)。

1.1.1 ☘️代码示例

// 初始化 Physi.js 场景
const scene = new Physijs.Scene();// 创建带有物理效果的立方体
const box = new Physijs.BoxMesh(new THREE.BoxGeometry(1, 1, 1),new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
scene.add(box);// 监听碰撞事件
box.addEventListener('collision', (otherObject) => {console.log('发生碰撞!', otherObject);
});// 在动画循环中更新物理
function animate() {requestAnimationFrame(animate);scene.simulate(); // 更新物理模拟renderer.render(scene, camera);
}
animate();

1.1.2 ☘️方法/属性

Physijs.Scene
创建支持物理的 Three.js 场景。

mesh.setLinearVelocity()
设置物体的线性速度(移动速度)。

mesh.setAngularVelocity()
设置物体的角速度(旋转速度)。

mesh.addEventListener()
监听碰撞事件(如 ‘collision’)。

new Physijs.BoxMesh()
创建带有长方体碰撞体的物体。

new Physijs.SphereMesh()
创建带有球体碰撞体的物体。

scene.simulate()
在渲染循环中调用,更新物理模拟。

Physijs.createMaterial(material, friction, restitution)
创建物理材质,影响摩擦力和弹性。
参数:
material:Three.js 材质(如 THREE.MeshPhongMaterial)。
friction:摩擦系数(默认 0.8)。
restitution:弹性系数(默认 0)。

二、🍀使用Physijs物理引擎

1. ☘️实现思路

  • 1、引入‘physi.js’,创建Physijs物理引擎三维场景scene,设置scene场景重力信息。
  • 2、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt,场景scene添加camera。
  • 3、创建THREE.SpotLight聚光灯光源light,设置light位置,scene场景加入light。
  • 4、加载几何模型:使用‘floor-wood.jpg’木纹贴图创建地面网格对象ground以及四周突出边框网格对象borderLeft、borderRight、borderTop、borderBottom,ground添加borderLeft、borderRight、borderTop、borderBottom。定义controls方法,内部定义addCubes方法用于添加物理碰撞立方体,定义addSpheres方法用于添加物理碰撞球体,定义clearMeshes方法用于清除添加的碰撞对象,定义碰撞物体restitution弹性形变和friction摩擦系数。定义render方法,实现ground的旋转动画。具体代码参考下面代码样例。
  • 5、加入gui控制。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html>
<style>body {margin: 0;overflow: hidden;}
</style><head><title>学习threejs,使用Physijs物理引擎</title><script type="text/javascript" src="../libs/three.js"></script><script type="text/javascript" src="../libs/stats.js"></script><script type="text/javascript" src="../libs/physi.js"></script><script type="text/javascript" src="../libs/dat.gui.js"></script><script type="text/javascript" src="../libs/chroma.js"></script><script type="text/javascript">'use strict';//任务线程Physijs.scripts.worker = '../libs/physijs_worker.js';//内部库ammo.jsPhysijs.scripts.ammo = '../libs/ammo.js';var scale = chroma.scale(['white', 'blue', 'red', 'yellow']);var initScene, render, applyForce, setMousePosition, mouse_position,ground_material, box_material,projector, renderer, render_stats, physics_stats, scene, ground, light, camera, box, boxes = [];initScene = function () {renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(window.innerWidth, window.innerHeight);renderer.setClearColor(new THREE.Color(0x000000));document.getElementById('viewport').appendChild(renderer.domElement);render_stats = new Stats();render_stats.domElement.style.position = 'absolute';render_stats.domElement.style.top = '1px';render_stats.domElement.style.zIndex = 100;document.getElementById('viewport').appendChild(render_stats.domElement);scene = new Physijs.Scene;scene.setGravity(new THREE.Vector3(0, -90, 0));camera = new THREE.PerspectiveCamera(35,window.innerWidth / window.innerHeight,1,1000);camera.position.set(80, 60, 80);camera.lookAt(scene.position);scene.add(camera);// Lightlight = new THREE.SpotLight(0xFFFFFF);light.position.set(20, 100, 50);scene.add(light);// Materialsground_material = Physijs.createMaterial(new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('../assets/textures/general/floor-wood.jpg')}),.9,.6);ground_material.map.wrapS = ground_material.map.wrapT = THREE.RepeatWrapping;ground_material.map.repeat.set(4, 8);// Groundground = new Physijs.BoxMesh(new THREE.BoxGeometry(60, 1, 130),ground_material,0);ground.receiveShadow = true;var borderLeft = new Physijs.BoxMesh(new THREE.BoxGeometry(2, 6, 130),ground_material,0);borderLeft.position.x = -31;borderLeft.position.y = 2;ground.add(borderLeft);var borderRight = new Physijs.BoxMesh(new THREE.BoxGeometry(2, 6, 130),ground_material,0);borderRight.position.x = 31;borderRight.position.y = 2;ground.add(borderRight);var borderBottom = new Physijs.BoxMesh(new THREE.BoxGeometry(64, 6, 2),ground_material,0);borderBottom.position.z = 65;borderBottom.position.y = 2;ground.add(borderBottom);var borderTop = new Physijs.BoxMesh(new THREE.BoxGeometry(64, 6, 2),ground_material,0);borderTop.position.z = -65;borderTop.position.y = 2;ground.add(borderTop)scene.add(ground);var meshes = [];var controls = new function () {//参数 restitution(弹性形变)和friction(摩擦系数)this.cubeRestitution = 0.4;this.cubeFriction = 0.4;this.sphereRestitution = 0.9;this.sphereFriction = 0.1;this.clearMeshes = function () {meshes.forEach(function (e) {scene.remove(e);});meshes = [];};this.addSpheres = function () {var colorSphere = scale(Math.random()).hex();for (var i = 0; i < 5; i++) {box = new Physijs.SphereMesh(new THREE.SphereGeometry(2, 20),Physijs.createMaterial(new THREE.MeshPhongMaterial({color: colorSphere,opacity: 0.8,transparent: truecontrols.sphereFriction,controls.sphereRestitution));box.position.set(Math.random() * 50 - 25,20 + Math.random() * 5,Math.random() * 50 - 25);meshes.push(box);scene.add(box);}};this.addCubes = function () {var colorBox = scale(Math.random()).hex();for (var i = 0; i < 5; i++) {box = new Physijs.BoxMesh(new THREE.BoxGeometry(4, 4, 4),Physijs.createMaterial(new THREE.MeshPhongMaterial({color: colorBox,opacity: 0.8,transparent: truecontrols.cubeFriction,controls.cubeRestitution));box.position.set(Math.random() * 50 - 25,20 + Math.random() * 5,Math.random() * 50 - 25);box.rotation.set(Math.random() * Math.PI * 2,Math.random() * Math.PI * 2,Math.random() * Math.PI * 2);meshes.push(box);scene.add(box);}}};var gui = new dat.GUI();gui.add(controls, 'cubeRestitution', 0, 1);gui.add(controls, 'cubeFriction', 0, 1);gui.add(controls, 'sphereRestitution', 0, 1);gui.add(controls, 'sphereFriction', 0, 1);gui.add(controls, 'addCubes');gui.add(controls, 'addSpheres');gui.add(controls, 'clearMeshes');requestAnimationFrame(render);scene.simulate();};var stepX;var direction = 1;render = function () {requestAnimationFrame(render);renderer.render(scene, camera);render_stats.update();ground.rotation.x += 0.002 * direction;if (ground.rotation.x < -0.4) direction = 1;if (ground.rotation.x > 0.4) direction = -1;ground.__dirtyRotation = true;scene.simulate(undefined, 1);};window.onload = initScene;</script>
</head><body>
<div id="viewport"></div>
</body></html>

效果如下:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARCGIS PRO DSK 选择坐标系控件(CoordinateSystemsControl )的调用

在WPF窗体上使用 xml&#xff1a;加入空间命名引用 xmlns:mapping"clr-namespace:ArcGIS.Desktop.Mapping.Controls;assemblyArcGIS.Desktop.Mapping" 在控件区域加入&#xff1a; <mapping:CoordinateSystemsControl x:Name"CoordinateSystemsControl&q…

LangGraph(三)——添加记忆

目录 1. 创建MemorySaver检查指针2. 构建并编译Graph3. 与聊天机器人互动4. 问一个后续问题5. 检查State参考 1. 创建MemorySaver检查指针 创建MemorySaver检查指针&#xff1a; from langgraph.checkpoint.memory import MemorySavermemory MemorySaver()这是位于内存中的检…

深入理解Mysql

BufferPool和Changebuffer是如何加快读写速度的? BufferPool 在Mysql启动的时候 Mysql会申请连续的空间来存储BufferPool 每个页16kb 当控制块不足以存储信息的时候就会向后申请一个新的页 每个控制块都对应了一个缓存页 控制块占chunk的百分之5左右 LRU链表 Changebuffer …

Python核心编程深度解析:作用域、递归与匿名函数的工程实践

引言 Python作为现代编程语言的代表&#xff0c;其作用域管理、递归算法和匿名函数机制是构建高质量代码的核心要素。本文基于Python 3.11环境&#xff0c;结合工业级开发实践&#xff0c;深入探讨变量作用域的内在逻辑、递归算法的优化策略以及匿名函数的高效应用&#xff0c…

《用MATLAB玩转游戏开发》贪吃蛇的百变玩法:从命令行到AI对战

《用MATLAB玩转游戏开发&#xff1a;从零开始打造你的数字乐园》基础篇&#xff08;2D图形交互&#xff09;-&#x1f40d; 贪吃蛇的百变玩法&#xff1a;从命令行到AI对战 &#x1f3ae; 欢迎来到这篇MATLAB贪吃蛇编程全攻略&#xff01;本文将带你从零开始&#xff0c;一步步…

Android平台FFmpeg音视频开发深度指南

一、FFmpeg在Android开发中的核心价值 FFmpeg作为业界领先的多媒体处理框架&#xff0c;在Android音视频开发中扮演着至关重要的角色。它提供了&#xff1a; 跨平台支持&#xff1a;统一的API处理各种音视频格式完整功能链&#xff1a;从解码、编码到滤镜处理的全套解决方案灵…

AI大模型驱动的智能座舱研发体系重构

随着AI大模型&#xff08;如LLM、多模态模型&#xff09;的快速发展&#xff0c;传统智能座舱研发流程面临巨大挑战。传统座舱研发以需求驱动、功能固定、架构封闭为特点&#xff0c;而AI大模型的引入使得座舱系统向自主决策、动态适应、持续进化的方向发展。 因此思考并提出一…

Day20 常见降维算法分析

一、常见的降维算法 LDA线性判别PCA主成分分析t-sne降维 二、降维算法原理 2.1 LDA 线性判别 原理 &#xff1a;LDA&#xff08;Linear Discriminant Analysis&#xff09;线性判别分析是一种有监督的降维方法。它的目标是找到一个投影方向&#xff0c;使得不同类别的数据在…

Python----机器学习(模型评估:准确率、损失函数值、精确度、召回率、F1分数、混淆矩阵、ROC曲线和AUC值、Top-k精度)

一、模型评估 1. 准确率&#xff08;Accuracy&#xff09;&#xff1a;这是最基本的评估指标之一&#xff0c;表示模型在测试集上正确 分类样本的比例。对于分类任务而言&#xff0c;准确率是衡量模型性能的直观标准。 2. 损失函数值&#xff08;Loss&#xff09;&#xff1…

cdn 是什么?

内容分发网络&#xff0c;Content Delivery Network 介绍 CDN&#xff08;Content Delivery Network&#xff09;是一种将内容分发到靠近用户的边缘服务器&#xff0c;以加速访问速度、减少延迟、降低源站压力的网络系统。 CDN 把网站的静态资源&#xff08;如 HTML、JS、CSS、…

BUCK基本原理学习总结-20250509

一、电感伏秒平衡特性 处于稳定状态的电感,开关导通时间(电流上升段)的伏秒数须与开关关断(电流下降段)时的伏秒数在数值上相等,尽管两者符号相反。这也表示,绘出电感电压对时间的曲线,导通时段曲线的面积必须等于关断时段曲线的面积。 二、BUCK的基本概念和原理 基…

【K8S系列】Kubernetes常用 命令

以下为的 Kubernetes 超全常用命令文档&#xff0c;涵盖集群管理、资源操作、调试排错等核心场景&#xff0c;结合示例与解析&#xff0c; 高效运维 Kubernetes 环境。 一、集群与节点管理 1. 集群信息查看 查看集群基本信息kubectl cluster-info # 显示API Server、DNS等核…

【Django】REST 常用类

ModelSerializer serializers.ModelSerializer 是 Django REST framework&#xff08;DRF&#xff09;里的一个强大工具&#xff0c;它能极大简化序列化和反序列化 Django 模型实例的流程。下面从多个方面详细介绍它&#xff1a; 1. 基本概念 序列化是把 Django 模型实例转化…

GuassDB如何创建兼容MySQL语法的数据库

GaussDB简介 GaussDB是由华为推出的一款全面支持OLTP和OLAP的分布式关系型数据库管理系统。它采用了分布式架构和高可靠性设计&#xff0c;可以满足大规模数据存储和处理的需求。GaussDB具有高性能、高可靠性和可扩展性等特点&#xff0c;适用于各种复杂的业务场景&#xff0c…

【无标题】I/O复用(epoll)三者区别▲

一、SOCKET-IO复用技术 定义&#xff1a;SOCKET - IO复用技术是一种高效处理多个套接字&#xff08;socket&#xff09;的手段&#xff0c;能让单个线程同时监听多个文件描述符&#xff08;如套接字&#xff09;上的I/O事件&#xff08;像可读、可写、异常&#xff09;&#x…

spring中的@Qualifier注解详解

1. 核心作用 Qualifier是Spring框架中用于解决依赖注入歧义性的关键注解。当容器中存在多个相同类型的Bean时&#xff0c;Autowired默认按类型自动装配会抛出NoUniqueBeanDefinitionException异常&#xff0c;此时通过Qualifier指定Bean的唯一标识符&#xff08;名称或自定义限…

Python爬虫实战:获取文学网站四大名著并保存到本地

一、引言 1.1 研究背景 中国古典四大名著承载着深厚的文化底蕴,是中华民族的宝贵精神财富。在互联网时代,网络文学资源虽丰富多样,但存在分散、质量参差不齐等问题 。部分文学网站存在访问限制、资源缺失等情况,用户难以便捷获取完整、高质量的经典著作内容。开发专业的爬…

【一】浏览器的copy as fetch和copy as bash的区别

浏览器的copy as fetch和copy as bash的区别 位置&#xff1a;devTools->network->请求列表右键 copy as fetch fetch("https://www.kuaishou.com/graphql", {"headers": {"accept": "*/*","accept-language": &qu…

渠道销售简历模板范文

模板信息 简历范文名称&#xff1a;渠道销售简历模板范文&#xff0c;所属行业&#xff1a;其他 | 职位&#xff0c;模板编号&#xff1a;KRZ3J3 专业的个人简历模板&#xff0c;逻辑清晰&#xff0c;排版简洁美观&#xff0c;让你的个人简历显得更专业&#xff0c;找到好工作…

Java大数据可视化在城市空气质量监测与污染溯源中的应用:GIS与实时数据流的技术融合

随着城市化进程加速&#xff0c;空气质量监测与污染溯源成为智慧城市建设的核心议题。传统监测手段受限于数据离散性、分析滞后性及可视化能力不足&#xff0c;难以支撑实时决策。2025年4月27日发布的《Java大数据可视化在城市空气质量监测与污染溯源中的应用》一文&#xff0c…