Cannon-es.js之Distance Constrait模拟布料

news2024/12/26 0:43:13

本文目录

  • 前言
  • 1、Particle
  • 2、前置代码准备
    • 2.1 代码
    • 2.2 效果
  • 3、使用距离约束模拟布料
    • 3.1 代码
    • 3.2 效果

前言

在现代Web开发中,实现逼真的物理效果对于提升用户体验至关重要。Cannon-es.js,作为Cannon.jsES6模块版本,凭借其轻量级、高性能和易于集成的特点,在WebGL环境中进行物理模拟时备受青睐。本文将深入探讨Cannon-es.js在模拟物理效果方面的应用,包括Particle(粒子)的基本使用、前置代码准备,以及如何使用距离约束来模拟布料效果。
粒子系统在游戏开发、动画制作以及物理模拟等领域有着广泛的应用。通过Cannon-es.js,我们可以轻松创建和管理粒子,实现各种复杂的物理效果。此外,距离约束作为一种强大的物理约束类型,允许我们模拟物体之间的连接关系,这在模拟布料、绳索等柔性物体时尤为有用。
在接下来的内容中,我们将详细介绍如何准备前置代码,如何使用Cannon-es.js创建粒子,并通过距离约束来模拟布料效果。希望通过本文的探讨,读者能够掌握Cannon-es.js在物理模拟方面的基本技巧,并在自己的项目中实现更加复杂和逼真的物理效果。

1、Particle

cannon-es(一个轻量级的JavaScript物理引擎,用于处理刚体动力学模拟)中,Particle(粒子)并不是传统意义上的三维几何体(如球体、立方体等),而是一个没有形状、大小或旋转属性的质量点。粒子主要用于模拟点质量的行为,如重力作用下的自由落体、碰撞检测中的接触点,或者作为更复杂刚体的一部分(例如,通过约束将多个粒子连接在一起以形成软体物理效果)。
Particlecannon-es中是一个特殊的Body类型,它只具有位置(position)、速度(velocity)和力(force)等属性,而没有形状(shape)和惯性(inertia)等刚体通常具有的属性。由于粒子没有形状,因此它们不会直接参与碰撞检测中的边界计算;相反,它们通常通过与其他粒子或刚体的接触点来间接参与碰撞。
cannon-es中创建一个Particle通常涉及以下步骤:

  1. 创建一个CANNON.Body实例,但将其形状(shape)属性设置为null或省略(因为粒子没有形状)。
  2. 设置粒子的质量(mass)。
  3. (可选)设置粒子的初始位置(position)和速度(velocity)。

2、前置代码准备

2.1 代码

<template>
    <canvas ref="cannonDemo" class="cannonDemo">
    </canvas>
</template>

<script setup>
import { onMounted, ref } from "vue"
import * as THREE from 'three'
import * as CANNON from 'cannon-es'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
const cannonDemo = ref('null')

onMounted(() => {
    const cannonDemoDomWidth = cannonDemo.value.offsetWidth
    const cannonDemoDomHeight = cannonDemo.value.offsetHeight

    // 创建场景
    const scene = new THREE.Scene
    // 创建相机
    const camera = new THREE.PerspectiveCamera( // 透视相机
        45, // 视角 角度数
        cannonDemoDomWidth / cannonDemoDomHeight, // 宽高比 占据屏幕
        0.1, // 近平面(相机最近能看到物体)
        1000, // 远平面(相机最远能看到物体)
    )
    camera.position.set(0, 2, 70)
    // 创建渲染器
    const renderer = new THREE.WebGLRenderer({
        antialias: true, // 抗锯齿
        canvas: cannonDemo.value
    })
    // 设置设备像素比
    renderer.setPixelRatio(window.devicePixelRatio)
    // 设置画布尺寸
    renderer.setSize(cannonDemoDomWidth, cannonDemoDomHeight)

    const light = new THREE.AmbientLight(0x404040, 200); // 柔和的白光
    scene.add(light);


    let meshes = []
    let phyMeshes = []
    const physicsWorld = new CANNON.World()
    // 设置y轴重力
    physicsWorld.gravity.set(0, -9.82, 0)

    const rows = 15
    const cols = 15
    const sphereGeometry = new THREE.SphereGeometry(0.2, 16, 16)
    const sphereMaterial = new THREE.MeshBasicMaterial({color: 0xff0000})
    const particleShape = new CANNON.Particle()
    let bodies = {}
    for(let i = 0; i < cols; i++) {
       for(let j = 0; j < rows; j++) {
        // 物理世界
        const particleBody = new CANNON.Body({
            mass: 0.5,
            position: new CANNON.Vec3(i - cols * 0.5, 10, j - rows * 0.5),
            shape: particleShape
        })
        bodies[`${i}-${j}`] = particleBody
        physicsWorld.addBody(particleBody)
        phyMeshes.push(particleBody)

        // 渲染世界
        const sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial)
        sphereMesh.position.set(i - cols * 0.5, 10, j - rows * 0.5)
        meshes.push(sphereMesh)
        scene.add(sphereMesh)
       }
    }
    const axesHelper = new THREE.AxesHelper(30);
    scene.add(axesHelper);

    const updatePhysic = () => { // 因为这是实时更新的,所以需要放到渲染循环动画animate函数中
        physicsWorld.step(1 / 60)
        for (let i = 0; i < phyMeshes.length; i++) {
            meshes[i].position.copy(phyMeshes[i].position)
            meshes[i].quaternion.copy(phyMeshes[i].quaternion)
        }
    }

    // 控制器
    const control = new OrbitControls(camera, renderer.domElement)
    // 开启阻尼惯性,默认值为0.05
    control.enableDamping = true

    // 渲染循环动画
    function animate() {
        // 在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)
        requestAnimationFrame(animate)
        updatePhysic()
        // 更新控制器。如果没在动画里加上,那必须在摄像机的变换发生任何手动改变后调用
        control.update()
        renderer.render(scene, camera)
    }

    // 执行动画
    animate()
})

</script>
<style scoped>
.cannonDemo {
    width: 100vw;
    height: 100vh;
}
</style>

2.2 效果

请添加图片描述


3、使用距离约束模拟布料

3.1 代码

在上面的基础添加距离约束代码:

    for(let i = 0; i < cols; i++) {
        for(let j = 0; j < rows; j++) {
            const body = bodies[`${i}-${j}`]
            if (i > 0) {
                const body2 = bodies[`${i - 1}-${j}`]
                const constraint = new CANNON.DistanceConstraint(body, body2, 0.4)
                physicsWorld.addConstraint(constraint)
            }
            if (j > 0) {
                const body2 = bodies[`${i}-${j - 1}`]
                const constraint = new CANNON.DistanceConstraint(body, body2, 0.4)
                physicsWorld.addConstraint(constraint)
            }
        }
    }

3.2 效果

请添加图片描述

在学习的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

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

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

相关文章

selenium测试框架快速搭建详解

一、介绍 Selenium目前主流的web自动化测试框架&#xff1b;支持多种编程语言Java、pythan、go、js等&#xff1b;selenium 提供一系列的api 供我们使用&#xff0c;因此在web测试时我们要点页面中的某一个按钮&#xff0c;那么我们只需要获取页面&#xff0c;然后根据id或者n…

拯救华为秘盒M310

这个盒子当年宣传得比较厉害&#xff0c; 当时确实也没有什么可选的&#xff0c;当年是高价入的,这个盒子有二切一的hdmi切换功能&#xff0c; 这点从今天来看&#xff0c; 都是一个亮点 华为秘盒M310是一款小巧但功能强大的网络机顶盒。它搭载了基于安卓系统的操作平台&#x…

序列化方式四——Hessian

介绍 Hessian是一个轻量级的、基于HTTP的RPC&#xff08;远程过程调用&#xff09;框架&#xff0c;由Resin开源提供。它使用一个简单的、基于二进制的协议来序列化对象&#xff0c;并通过HTTP进行传输。Hessian的设计目标是提供一种高效、可靠且易于使用的远程服务调用机制。…

算法分析——《二分查找》

&#x1f6e9;《二分查找》 &#x1f3a8;题目描述&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 …

厦门大龄自闭症寄宿学校:为孩子们提供全方位关怀和教育

在自闭症儿童的教育与关怀领域&#xff0c;厦门大龄自闭症寄宿学校以其专业性和全面性&#xff0c;为众多家庭提供了宝贵的支持与帮助。而在中国南方的广州&#xff0c;也有一所同样致力于自闭症儿童全方位关怀与教育的机构——星贝育园自闭症儿童寄宿制学校。星贝育园以其独特…

为什么要自定义异常

背景 我们在阅读各类源码时&#xff0c;会注意到几乎各个功能包中&#xff0c;都包含有自定义的异常&#xff1b;那有没有想过&#xff0c;JDK的源码中&#xff0c;已经定义了各种异常体系&#xff0c;为啥后续的一些依赖Jar包中&#xff0c;还要自定义异常呢&#xff1f; 下面…

Java应用程序的服务器有哪些?

1.Tomcat、Jetty 和 JBoss 区别&#xff1f; Apache Tomcat、Jetty 和 JBoss都是用于部署Java应用程序的服务器&#xff0c;它们都支持Servlet、JSP和其他Java EE&#xff08;现在称为Jakarta EE&#xff09;技术。尽管它们有一些相似的功能&#xff0c;但它们之间还是存在一些…

二叉树相关oj题(Java)

一. 检查两颗树是否相同。OJ链接 这里我们考虑两种情况: 1.结构上 2.节点值上 当上面两种情况同时遍历时: 1.如果两颗树的节点都不为空,就判断值 2.如果两棵树种一棵树的节点为空另一棵树的节点不为空,则这两颗肯定不是相同的树 整体来看:要判断两棵树是否相同,得判断根,然后判…

SQLite数据库迁移与备份技术详解

目录 引言 SQLite数据库迁移 迁移概述 迁移步骤 1. 创建目标数据库系统 2. 导出SQLite数据库数据 3. 导入数据到目标数据库 4. 验证数据迁移 迁移注意事项 SQLite数据库定期备份 备份的重要性 备份方法 1. 使用VACUUM命令 2. 使用ATTACH DATABASE和PRAGMA语句 3.…

这些211热度不高,毕业年薪20-40万!自动化考研择校

这些211学校&#xff0c;今年热度不高&#xff0c;就业还意外的好&#xff0c;一定不要错过&#xff01;搭配历年数据&#xff0c;供大家参考~ 目录 ① 华东理工大学 ② 东华大学 ③ 江南大学 ④ 安徽大学 ① 华东理工大学 复试线招生人数 控制学科等级为B&#xff0c;上…

Qt QIntValidator详解

一、介绍 QIntValidator是Qt框架中用于验证整数输入的验证器类。它可以限制用户输入的整数范围&#xff0c;确保输入的整数在指定的范围内。通过QIntValidator&#xff0c;可以轻松地实现整数输入的有效性和范围限制。 二、 常用方法 QIntValidator(QObject *parent Q_NULLPT…

Python编码系列—Python设计模式的选择与权衡:打造高效代码架构

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

SigmaStudio中部分滤波器算法有效性频谱分析

一、各类滤波器参数如下图设置 1.1、输入源白噪音经过如下算法处理后Notch\Band Pass\Band Stop&#xff0c;如下频谱分析图 1.2、输入源白噪音经过low pass后处理前后的频谱分析如如下 二、Notch滤波器配置图&#xff0c;如下 2.1、两串联、五个串联和未串联的Notch对白噪音…

券商股大涨,至少17家券商已入局AI人工智能金融大模型

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 最近&#xff0c;券商股价的大涨成为了财经…

鲜花配送小程序开发制作方案

鲜花配送小程序系统通过用户端、商家端和配送员端的协同工作&#xff0c;确保鲜花能够在指定时间内送达&#xff0c;提升用户满意度和忠诚度。 目标用户 个人消费者&#xff1a;生日、纪念日、节日等特殊场合送花的人群。 企业客户&#xff1a;需要定期为办公场所或活动提供花…

低至1元/小时:国庆七天,30元通关《黑神话:悟空》!

目录 前言 一、云游戏解决方案的引入 二、服务的核心亮点及性价比 1、高清画质体验 2、广泛的手柄支持 3、隐私与安全性 4、直播推流优势 5、游戏快速启动 6、价格优惠 &#xff08;1&#xff09;新用户专享&#xff0c;低至1元/时&#xff01; &#xff08;2&#…

利用C++优化Chrome浏览器的启动速度

Chrome浏览器是全球使用最广泛的网络浏览器之一&#xff0c;但有时候它的启动速度可能会让人感到不满。为了解决这个问题&#xff0c;我们可以使用C进行一些优化。本文将介绍如何通过关闭预加载功能、设置允许弹出窗口和为网页添加快捷方式来加快Chrome浏览器的启动速度。 &am…

谨防火灾!电瓶车检测算法助力城市/小区/园区多场景安全管理精细化、智能化

随着人工智能技术的快速发展&#xff0c;AI智能分析网关V4在电瓶车检测领域的应用日益广泛。这一技术通过深度学习、计算机视觉等先进算法&#xff0c;实现了对电瓶车及其相关行为的智能识别和分析&#xff0c;为电瓶车的管理和应用提供了强大的技术支持。 一、电瓶车检测算法…

python为姓名注音实战案例

有如下数据&#xff0c;需要对名字注音。 数据样例&#xff1a;&#x1f447; 一、实现过程 前提条件&#xff1a;由于会用到pypinyin库&#xff0c;所以一定得提前安装。 pip install pypinyin1、详细代码&#xff1a; from pypinyin import pinyin, Style# 输入数据 names…

Unreal 对象、属性同步流程

文章目录 类型同步初始化创建 FObjectReplicator创建 FRepLayout、Cmd、ShadowOffset创建 FRepChangedPropertyTracker、FRepState创建 FReplicationChangelistMgr、FRepChangelistState、ShadowBuffer 属性同步属性变化检测查找变化属性&#xff0c;写入ShadowMemory发送数据 …