Mir*_*ror 7 javascript math geometry three.js
在我的项目中,我有一个球员环游世界。地球不仅是一个球体,而且还有山脉和山谷,因此我需要玩家的z位置进行更改。为此,我从玩家的位置向单个物体(地球)发出光线,然后得到它们相交的点并相应地更改玩家的位置。我只是在播放器移动时发出光线,而不是在每一帧上发出光线。
对于复杂的对象,它需要永远的时间。具有约1m个多边形(面)(1024x512分段球面)的对象大约需要200毫秒。光线投射会投射到每个人的脸上吗?
有没有传统的快速方法可以在三个过程中实现这一目标,例如某种加速结构(八叉树?盒装(无射线投射)方法?
var dir = g_Game.earthPosition.clone();
var startPoint = g_Game.cubePlayer.position.clone();
var directionVector = dir.sub(startPoint.multiplyScalar(10));
g_Game.raycaster.set(startPoint, directionVector.clone().normalize());
var t1 = new Date().getTime();
var rayIntersects = g_Game.raycaster.intersectObject(g_Game.earth, true);
if (rayIntersects[0]) {
var dist = rayIntersects[0].point.distanceTo(g_Game.earthPosition);
dist = Math.round(dist * 100 + Number.EPSILON) / 100;
g_Player.DistanceFromCenter = dist + 5;
}
var t2 = new Date().getTime();
console.log(t2-t1);
Run Code Online (Sandbox Code Playgroud)
先感谢您
不要使用three.js Raycaster。
考虑提供以下内容的Ray.js:function intersectTriangle(a, b, c, backfaceCulling, target)
建议的优化:
玩家是否从某些已知位置开始?您必须知道他的初始身高吗?无需进行光线投射(或仅进行一次全网格慢速交集)
玩家是否以小步移动?下一次光线投射很可能与以前相交。
优化#1?记住前一张脸,并先进行光线投射。
优化#2?建立一个缓存,以便在给定一个面部idx的情况下,您可以在O(1)时间内检索相邻的面部。
如果您的星球不是实时生成的,则可以从文件中加载此缓存。
因此,按照我的方法,您可以从缓存和raycast 1-6面执行O(1)读取操作。
赢得!
我认为您应该将地球的高度图预先渲染为纹理,前提是您的地形不是动态的。将所有内容读取到一个类型化的数组中,然后只要播放器移动,您只需将其坐标反向投影到该纹理中,对其进行查询,偏移和相乘即可,您应该在O(1)时间内得到所需的内容。
如何生成该高度图取决于您。实际上,如果您有一个凹凸不平的地球,那么您可能应该首先从高度图开始,然后在顶点着色器中使用它来渲染地球(输入球完美平滑)。然后你可以使用相同的高度地图来查询玩家的ž。
对于复杂的对象,它需要永远的时间。具有约1m个多边形(面)(1024x512分段球面)的对象大约需要200毫秒。光线投射会投射到每个人的脸上吗?
开箱即用THREE.js 会在对网格执行光线投射时检查每个三角形,并且THREE.js 中没有内置加速结构。
不过,我已经与其他人一起研究了3个网眼bvh软件包(github,npm),以帮助解决此问题,这可能有助于您达到所需的速度。使用方法如下:
import * as THREE from 'three';
import { MeshBVH, acceleratedRaycast } from 'three-mesh-bvh';
THREE.Mesh.prototype.raycast = acceleratedRaycast;
// ... initialize the scene...
globeMesh.geometry.boundsTree = new MeshBVH(globeMesh.geometry);
// ... initialize raycaster...
// Optional. Improves the performance of the raycast
// if you only need the first collision
raycaster.firstHitOnly = true;
const intersects = raycaster.intersectObject(globeMesh, true);
// do something with the intersections
Run Code Online (Sandbox Code Playgroud)
自述文件中提到了一些注意事项,因此请记住这些注意事项(修改了网格索引,仅支持非动画化的BufferGeometry等)。还有一些内存优化可以完成,但是有一些可调整的选项可以帮助您进行调整。
我很想听听这对您的运作方式!也可以就如何改进该软件包的问题发表反馈意见。希望有帮助!