当前位置: 首页 > wzjs >正文

常熟有哪些网站建设公司个人网站被黑了

常熟有哪些网站建设公司,个人网站被黑了,c 怎么做网站开发,苏州网站制作聚尚网络目录引言基本概念和原理实现过程总结参考引言 在游戏开发、3D 仿真和物理引擎中,碰撞检测(Collision Detection)是一个核心问题。当场景中有成千上万的物体时,如何高效判断“谁撞上了谁”?如果简单粗暴地遍历所有物体…

目录

  • 引言
  • 基本概念和原理
  • 实现过程
  • 总结
  • 参考

引言

在游戏开发、3D 仿真和物理引擎中,碰撞检测(Collision Detection)是一个核心问题。当场景中有成千上万的物体时,如何高效判断“谁撞上了谁”?如果简单粗暴地遍历所有物体两两检测,计算复杂度会高达 O(n²),性能直接爆炸!💥

这时,八叉树(Octree) 闪亮登场✨——它通过 空间分割 技术,将 3D 世界递归划分成小块,只检测 可能发生碰撞的物体,让计算复杂度骤降至 O(n log n),甚至更低!

本文将带你深入八叉树的原理,手把手实现一个高效的碰撞检测系统!

基本概念和原理

  1. 相机控制系统

(1)相机类型选择:
PerspectiveCamera(透视相机)适合第一/第三人称视角,参数:fov, aspect, near, far

  // 相机(透视)const camera = new THREE.PerspectiveCamera(75, //视角window.innerWidth / window.innerHeight, //aspect视锥长宽比0.1, //near10000 //far);camera.rotation.order = "YXZ"; //默认旋转顺序是 'XYZ',设置相机旋转的顺序的属性。这个属性指定了欧拉角(Euler angles)的旋转顺序camera.lookAt(0, 0, 0);camera.position.set(0, 1, 5);scene.add(camera);

(2)相机控制器:
PointerLockControls(指针锁定控制器) 精准的鼠标输入(无加速/边界限制),完全的移动逻辑控制权(可插入碰撞检测),更低的性能开销(无内置惯性计算),若项目需要真实的物理碰撞或竞技级FPS体验,自定义 PointerLockControls 是唯一选择

为什么选择 PointerLockControls实现第一人称视角碰撞检测而不是直接使用FirstPersonControls?
①PointerLockControls直接捕获鼠标输入,消除光标移动范围限制,实现无间断的视角旋转(适合FPS游戏),而FirstPersonControls依赖鼠标相对移动事件,无法完全隐藏系统光标,降低沉浸感。
②PointerLockControls与物理引擎/碰撞检测无缝集成,可自由扩展 update 逻辑,在每一帧计算移动前先检测碰撞(如射线检测或物理引擎查询)。FirstPersonControls 的封闭性,移动逻辑内置且不可干预,无法关闭自动的水平矫正(不适合需要自由旋转的场景)强制覆盖其 update 方法,可能破坏内部状态机。

需求PointerLockControlsFirstPersonControlsOrbitControls
核心用途FPS游戏/仿真简易第一人称浏览3D模型观察/场景调试
鼠标控制✅ 锁定指针,无光标干扰⚠️ 受系统光标限制,无法实现无光标✅ 自由旋转/缩放(光标可见)
键盘控制需手动添加键盘移动和鼠标旋转默认支持WASD移动和鼠标旋转键盘只能控制左右俯仰,鼠标左点击旋转,右点击拖拽,围绕目标物体,target只能在一个小区域
视角限制✅ 可限制俯仰角(如±90°)⚠️ 固定限制✅ 可限制旋转范围/缩放距离
物理引擎集成✅ 直接同步物理体位置❌ 难以与物理体同步❌ 完全独立,无物理交互
自定义碰撞响应✅ 自由扩展检测逻辑❌ 移动逻辑不可干预❌ 固定交互逻辑
移动平滑性⚠️ 需手动实现阻尼✅ 内置惯性/阻尼✅ 内置平滑旋转/缩放
UI兼容性❌ 需额外处理UI交互(指针锁定)⚠️ 需隐藏光标✅ 完美兼容UI(光标自由移动)
典型场景FPS射击游戏,VR行走模拟3D博物馆浏览,简单场景漫游模型展示,开发者调试场景
  1. 射线(Raycaster)

Raycaster 是用于 射线检测(Raycasting) 的核心类,其本质是从 3D 空间中的一个点向特定方向发射一条无限延伸的虚拟射线,检测该射线与场景中物体的交点。六个核心使用场景第一人称视角的碰撞检测、鼠标拾取(3D物体选择)、地面高度检测(角色站立/楼梯攀爬)、武器子弹命中检测、视线检测(AI敌人感知)、动态遮挡剔除(性能优化)

	//射线由 起点(origin) 和 方向(direction) 定义const raycaster = new THREE.Raycaster(origin, direction);const intersects = raycaster.intersectObjects(this.scene.children); //返回交叉部分数组[ { distance, point, face, faceIndex, object }, ... ]/*distance —— 射线投射原点和相交部分之间的距离。point —— 相交部分的点(世界坐标)face —— 相交的面faceIndex —— 相交的面的索引object —— 相交的物体uv —— 相交部分的点的UV坐标。uv1 —— 相交部分的点的第二组UV坐标normal - 交点处的内插法向量instanceId – 与InstancedMesh物体相交时的instance索引*/
  1. 八叉树(Octree)

是一种 空间分割数据结构,用于高效管理 3D 空间中的物体。它通过递归地将立方体空间划分为 8 个子立方体(称为“节点”或“象限”),每个子立方体可继续分割,直到满足终止条件(如深度限制或物体数量阈值)。

  • 分层结构:树状组织,根节点代表整个空间,叶节点存储实际物体。
  • 动态适应:根据物体分布自动调整分割粒度。
  • 快速查询:利用空间位置跳过无关区域,优化碰撞检测、射线检测等操作。

为什么用八叉树?
在 3D 场景中,直接遍历所有物体进行碰撞检测的复杂度为 O(n²),而八叉树可将其降至 O(n log n) 或更低。典型应用场景包括:
①碰撞检测:快速筛选可能相交的物体对。
②射线检测:仅检测射线途径的节点内的物体。
③视锥剔除:只渲染相机可见区域的物体。
④动态场景管理:如游戏中的粒子系统、物理引擎。

(2)胶囊体(Capsule)
本质是碰撞几何体,由两个半球和一个圆柱组成的数学模型,用于简化角色或物体的碰撞形状。用于替代复杂网格碰撞体,提供更高效且自然的碰撞检测(尤其适合角色控制器)

  1. 平滑移动余阻尼

使用线性插值(LERP)实现平滑过渡

const currentPosition = new THREE.Vector3().copy(startPosition);
const lerpFactor = 0.1; // 插值系数 (0~1,值越大过渡越快)
currentPosition.lerp(targetPosition, lerpFactor);

应用缓动函数(easing functions)改善手感

let damping = Math.exp(-4 * deltaTime) - 1; //阻尼,随着deltaTime指数增加damping越小(减去 1。这可能是为了调整阻尼值的范围)
if (!this.onFloor) {this.playerVelocity.y -= this.gravity * deltaTime;damping *= 0.1;
}
this.playerVelocity.addScaledVector(this.playerVelocity, damping);
const deltaPosition = this.playerVelocity.clone().multiplyScalar(deltaTime);
this.capsule.translate(deltaPosition);

实现过程

  1. 加载模型和胶囊把场景分解成一些节点 this.octree.fromGraphNode(this.modelObj)
    // 加载模型,并渲染到画布上loadGLTF(this.modelUrl).then((object: any) => {this.modelObj = object.scene;console.log(this.modelObj); // 返回组对象Groupthis.scene.add(this.modelObj);// 遍历场景中的所有几何体数据this.modelObj.traverse((child: any) => {if (child.isMesh) {child.castShadow = true;child.receiveShadow = true;}});//八叉树this.octree = new Octree();this.octree.fromGraphNode(this.modelObj); // 通过Octree对象来构建节点// OctreeHelper// const helper = new OctreeHelper(this.octree);// helper.visible = true;// this.scene.add(helper);});
  1. 把胶囊体的位置传给网格对象,进行运动交互
  //player类中的部分方法init() {//胶囊体,用于碰撞检测,Capsule不是一个几何体//this.capsule位置方向大小设置很重要,this.height要将其底部与场景中其他几何体的基准线对齐this.capsule = new Capsule(new THREE.Vector3(0, this.radius, 0), //第一个端点new THREE.Vector3(0, this.height + this.radius, 0), //第二个端点this.radius //半径);this.mesh = new THREE.Mesh(new THREE.CapsuleGeometry(this.radius, this.height),new THREE.MeshNormalMaterial());this.mesh.rotation.order = "YXZ";this.scene.add(this.mesh);this.sync();this.addkeyBoard();}sync() {const end = this.capsule.end.clone();end.y -= this.radius;this.mesh.position.copy(end);}
  1. 进行碰撞检测,模拟物理效果

在Octree对象中,我们可以通过capsuleIntersect方法来捕获Capsule胶囊体与所构建了八叉树节点的场景是否进行了碰撞,检测方式如下:const result = this.octree.capsuleIntersect(this.capsule);

  • depth: 碰撞的深度,可以理解为物体和场景中相机的比例
  • normal:碰撞的法线向量,可以理解为碰撞的方向
  handleCollider() {//检查场景空间和胶囊的碰撞const result = this.octree.capsuleIntersect(this.capsule);this.onFloor = false;if (result) {const { normal, depth } = result;this.onFloor = normal.y > 0;if (!this.onFloor) {this.speedVel.addScaledVector(result.normal, -result.normal.dot(this.speedVel));} else {this.time = 0;this.speedVel.y = 0;}this.capsule.translate(normal.multiplyScalar(depth));//实现不同平面的行走,镜头可以向下或向上移动一定距离}}
  1. 移动镜头,通过键盘和鼠标操控镜头移动旋转实现浏览场景的基本操作

(1)PointerLockControls指针控制器+鼠标控制旋转视角

// 添加相机控件-指针
this.controls = new PointerLockControls(this.camera, this.canvas);
this.controls.lock();  // 锁定鼠标到画布,隐藏光标, 注:Tween操作需要在this.controls.lock()之前
this.controls.unlock();  //释放鼠标,恢复光标//鼠标控制
addMouseEvent() {let mouseX;let mouseY;document.onmousedown = (event) => {event.preventDefault();mouseX = event.pageX;mouseY = event.pageY;};document.onmousemove = (event) => {libraryState.isDraging = true;event.preventDefault();if (mouseX && mouseY) {var deltaX = event.pageX - mouseX;var deltaY = event.pageY - mouseY;mouseX = event.pageX;mouseY = event.pageY;// 根据触摸事件的移动量调整相机的角度this.camera.rotation.y -= deltaX * 0.003; //左右旋转this.camera.rotation.x -= deltaY * 0.003; //俯仰旋转}};document.onmouseup = (event) => {event.preventDefault();if (libraryState.viewing) return;mouseX = null;mouseY = null;};}

(2)键盘事件移动方向

在requestAnimationFrame方法种执行keyControls和updatePlayer

监听键盘事件修改方向向量playerVelocity → 根据碰撞检测handleCollider计算出胶囊体capsule最新位置 → 同步更新胶囊和相机位置

  keyControls(deltaTime) {const speedDelta = deltaTime * (this.onFloor ? 25 : 8);if (this.keyStates["KeyW"]) {this.playerVelocity.add(this.getForwardVector().multiplyScalar(speedDelta));}if (this.keyStates["KeyS"]) {this.playerVelocity.add(this.getForwardVector().multiplyScalar(-speedDelta));}if (this.keyStates["KeyA"]) {this.playerVelocity.add(this.getSideVector().multiplyScalar(-speedDelta));}if (this.keyStates["KeyD"]) {this.playerVelocity.add(this.getSideVector().multiplyScalar(speedDelta));}if (this.onFloor) {if (this.keyStates["Space"]) {this.playerVelocity.y = 5;}}}async updatePlayer(deltaTime: number) {let damping = Math.exp(-4 * deltaTime) - 1;//随着deltaTime指数增加damping越小(减去 1。这可能是为了调整阻尼值的范围)if (!this.onFloor) {this.playerVelocity.y -= this.gravity * deltaTime;damping *= 0.1;}this.playerVelocity.addScaledVector(this.playerVelocity, damping);const deltaPosition = this.playerVelocity.clone().multiplyScalar(deltaTime);this.capsule.translate(deltaPosition);this.handleCollider(); //碰撞检测this.sync(); //同步mesh胶囊this.check(); //回归中心点// 同步到缩略图上this.handleMiniMapMove();this.handleMiniMapRoate();}sync() {// 同步胶囊和相机位置const end = this.capsule.end.clone();// end.y -= this.radiusthis.mesh.position.copy(end);this.camera.position.copy(end);}

效果图如下:
请添加图片描述

总结

八叉树是一种高效空间索引工具,减少需处理的物体数量,适合动态场景的碰撞检测。胶囊体比复杂网格的碰撞计算快10-100倍,胶囊体+射线组 平衡精度与性能,是角色控制的黄金组合。简单场景用纯八叉树,复杂交互需集成 Cannon.js。

参考

  1. 基于three.js实现第一人称的碰撞检测
  2. threejs官方fps示例

文章转载自:

http://qk8jpOS2.mhrzd.cn
http://EmuwllsU.mhrzd.cn
http://b7IdUClS.mhrzd.cn
http://FItTnZ0F.mhrzd.cn
http://bM4lFkcC.mhrzd.cn
http://CTnofYKC.mhrzd.cn
http://Aa1b1Rce.mhrzd.cn
http://8qqD5c9D.mhrzd.cn
http://hZeOiOLu.mhrzd.cn
http://mIslL1ci.mhrzd.cn
http://7LoM0L4t.mhrzd.cn
http://bsa1DI5p.mhrzd.cn
http://oE03UO5a.mhrzd.cn
http://0VhE8nzz.mhrzd.cn
http://7tHYTEtN.mhrzd.cn
http://1g3do3dA.mhrzd.cn
http://EyS6iq6v.mhrzd.cn
http://AAC1QanE.mhrzd.cn
http://6kBNXCqL.mhrzd.cn
http://MEU88Lwn.mhrzd.cn
http://EgCZtkM8.mhrzd.cn
http://FpFWDQwv.mhrzd.cn
http://ymQEbmum.mhrzd.cn
http://u3W0i7Ly.mhrzd.cn
http://MUT7CZVd.mhrzd.cn
http://ULac2yX1.mhrzd.cn
http://tk4jVGyU.mhrzd.cn
http://acBWmKMY.mhrzd.cn
http://Zo7BvRxN.mhrzd.cn
http://PQtiYrOj.mhrzd.cn
http://www.dtcms.com/wzjs/663272.html

相关文章:

  • 包头网站建设公司哪家好做网站推广用优化还是竞价
  • 大网站成本免费在线观看电影大全
  • php源码下载网站沈阳关键字优化公司
  • 买2g 空间做下载网站wordpress媒体文件
  • 网站怎么做更新吗天水有做网站的地方吗
  • 如何开淘宝店并运营店铺seo优化网站优化排名
  • 餐馆效果图网站游戏开发大亨内购破解版
  • 品牌网站建设黑白H狼昆明优秀网站
  • 深圳做品牌网站wordpress注册邮箱验证
  • 建站优化信息推广多个wordpress站点同步
  • cms搭建网站汝阳县住房与城乡建设局建局网站
  • 深圳网站制作公司售后韶关网站建设公司
  • 毕业设计做啥网站好搜索推广代运营
  • 服装企业网站策划书优化网站的公司哪家好
  • seo推广营销网站制作网站软件都在什么公司
  • 郑州陆港开发建设有限公司网站专业网站建设市场分析
  • 扬中网站建设公司黄骅市官网
  • 维护一个网站的安全seo外链优化
  • 珠江新城网站建设群晖wordpress外网访问
  • 做医疗器械网站wordpress柒零贰
  • 易语言网站批量注册怎么做网站建设可视化
  • 郑州优化网站关键词wordpress 导航函数
  • 网站开发网站开个淘宝店做网站设计好吗
  • 网络建站如何建成深圳福田做网站公司哪家好
  • 吉安网站制作公司排名一家公司做两个网站吗
  • 服务号网站建设在哪个网站上可以学做衣服
  • 网站解决方案电商网站模板
  • 山西住房与城乡建设厅定额网站网站模板免费推荐
  • 手机网站设计案例c2c电子商务网站
  • 微信网站建设费记什么科目管理软件属于什么软件