我们正在尝试构建“编辑句柄”,允许用户通过拖动8个位置(4个角+4个边缘)中的一个来调整(投影)平面的大小。 这个大小调整应该只在拖动方向上缩放/拉伸曲面,因此三个.js的默认缩放机制不会这样做,因为它同时在两个相反的方向上缩放,如{{3 }}
我已经阅读并尝试了很多,特别是这两个帖子:
接下来我最终得到了这个
// preparing to resize into -x direction aka "left edge"
// moving the geometry center to the right edge
mesh.geometry.translate(width/2, 0, 0);
mesh.geometry.scale(scaleX, 1, 1);
// moving the geometry center back to the middle
// as more resizing might happen, into another direction, as per comment here:
// https://stackoverflow.com/questions/26817717#comment74469004_26818522
mesh.geometry.translate(-(width/2 * scaleX), 0, 0);
结果不是我所期望的: 缩放再次发生在两个相反的方向上,因此平移相互抵消 - 所以当原点的中心/原点位于右边缘或者我的结尾存在误解时,不会发生缩放。
另一方面,这很好用
mesh.scale.set(scaleX, 1, 1);
mesh.position.x = (-width / 2);
但是一遍又一遍地重置网格的位置真的很麻烦 - 我还以为我已经读过缩放网格的效果不太好,因为这个转换是为每一帧重新应用的(虽然可能会出错:{ {3}}),同时将基础几何体的变换烘焙到数据中。
我也看了Scaling a geometry in one direction with top as reference in threejs的来源,但因为它不按我们想要的方式工作,因为我还没有完全掌握四元数的概念,它在我身上迷失了。
所以我的问题是:有没有办法在不校正网格位置的情况下进行单向调整大小?
答案 0 :(得分:1)
正如您所发现的,您有两种方法可以解决此问题。
geometry
。Mesh
并调整其中心位置。首先,让我们讨论一下我不推荐的选项1,原因我稍后会说清楚。
要在单个方向上线性缩放几何体,您仍需要沿缩放方向移动所有顶点。因此,对于每个顶点,您需要根据顶点将要接收的缩放量计算其新位置(最靠近缩放侧的顶点移动最多,中间的顶点移动一半,顶部移动到另一侧的顶点)缩放几乎没有移动)。如果你正在进行实时缩放,那可能是很多计算。
现在考虑选项2:您更改整个网格的矩阵(包括其新位置)。而已。矩阵被发送到GPU,后者处理其余的。我相信你知道,GPU非常擅长数学(包括矩阵数学),而JavaScript则不太好,或者至少要慢得多。执行矩阵操作对GPU来说无关紧要。
更不用说,在变换矩阵到位的情况下,您始终可以获得顶点的世界位置:
vertexCopy.set(myMesh.geometry.attributes.position.getX(index),
myMesh.geometry.attributes.position.getY(index).
myMesh.geometry.attributes.position.getZ(index));
myMesh.localToWorld(vertexCopy);
<强>梗概:强>
如果有的话,操纵几何体比操纵变换矩阵更多“hacky”。这就像你告诉系统如何绘制一个正方形的每个像素,当你可以简单地告诉它画一个正方形时。
更新几何图形的计算成本很高。即使之后基本上“烘焙”顶点,下一次操作也会触发更多计算。
更新网格的矩阵很简单,并且将计算复杂性卸载到GPU,这对处理该信息没有任何问题。
欢迎您选择符合您要求的任何方法,但根据您提供的信息,我非常推荐选项2.
第三个想法:
你可能会使用Morph Targets来达到你想要的效果,但我对它们没有多少经验。 Here's an example of cube being deformed by morphing.你需要影响多个变形目标以达到你想要的效果,但它仍然可能比操纵几何更好,因为变形操作将在GPU上完成。