在Three.js中动态添加线段的顶点

12

我学会了如何在Three.js中绘制线条,但问题是需要动态添加线条的顶点。当我动态添加顶点时,场景没有更新。

我尝试过geometry.verticesNeedUpdate = true,但似乎没有起作用。

3个回答

15

编辑:现在可以使用BufferGeometrydrawcalls实现等效功能。请参见使用three.js动态绘制一条线

three.js r.71


不支持动态添加线的顶点。如Wiki所述:

您只能更新缓冲区的内容,不能调整缓冲区的大小(这非常耗费成本,基本上等同于创建新几何体)。

您可以通过预分配较大的缓冲区并保持不需要的顶点折叠/隐藏来模拟调整大小。

three.js r.55


谢谢。我想我只需要在每一帧中删除并重新添加一行...这似乎更加低效。 - K2xL
我认为WestLangley要表达的是,尝试动态地做这件事基本上和一开始创建一个全新的几何体一样低效,因此它并不比创建新几何体更高效,两者效率相同。 - Daniel Robinson
1
我通过以下代码将所有点添加到几何体中: linegeometryX.vertices.push(new THREE.Vertex(new THREE.Vector3(x, y, z))); 如何隐藏/折叠不需要的顶点? - Dipak
你需要发布一个新帖子来提出你的问题。 - WestLangley

5
我几天前也遇到了这个问题。正如WestLangley所说,你不能直接做真正的动态几何,但alteredq有一些“伪造”的策略,可以在https://github.com/mrdoob/three.js/issues/342实现所需效果。
关于你对上一个答案的评论,请不要每帧都从场景中删除并重新添加新行 - 这会(很可能)导致大量性能损失。您需要使用alteredq的两种解决方法之一。
在我的应用程序中,我像这样使用选项1:
  1. 提前创建一个THREE.Geometry对象,并使用尽可能多的顶点进行初始化(或者使用相当高数量的顶点)。 (在您想要显示它们之前,您还需要以某种方式隐藏它们 - 我将它们的位置设置为屏幕外。)

  2. 使用该几何体创建一个THREE.Line对象,并将其添加到场景中。

  3. 现在,当您想要向行中添加新点时,您必须索引到几何体对象的顶点中,找到其中最后一个未使用的顶点,并更新它 - 将坐标更改为实际坐标,并设置geometry.verticesNeedUpdate = true;(否则它会认为没有更改)。 (请参见维基上的如何进行更新。)

我仍在完善我的方法,但这至少可以让您在屏幕上绘制一条线。
three.js r55

如何防止屏幕外的点连接到您想要渲染的“真实”点? - Max Strater
Max,这已经过了一段时间了,所以我记不清楚了,但我想我把点(或连接线)的颜色改成了场景背景颜色相同的颜色。因此连接仍然存在,但是它是不可见的。 - chriskilding

2

正如WestLangley的回答所说,你不能这样做。下面是我决定使用的权宜之计:

  • 通过将geometry.vertices填充为我的线的起点,分配比我需要的更多的顶点
  • 当我想要添加新点时,将数组的内容向左移动,并在geometry.vertices的最后一个数组条目中写入新点

代码: 创建新行:

function createNewLine(startingPoint){
    var geometry = new THREE.Geometry();
    for (i=0; i<MAX_LINE_POINTS; i++){
    geometry.vertices.push(startingPoint.clone());
    }
    myLine = new THREE.Line(geometry, lineMaterial);
    myLine.geometry.dynamic = true;
    scene.add(myLine);
    render();
}

添加一个点到线上:

function addPoint(myPoint) {
    myLine.geometry.vertices.push(myLine.geometry.vertices.shift()); //shift the array
    myLine.geometry.vertices[maxLinePoints-1] = myPoint; //add the point to the end of the array
    myLine.geometry.verticesNeedUpdate = true;
    render();
}

那么你最终得到的是一条线,上面堆积了一堆点,接着是你实际想要渲染的点。 我在three.js的git仓库上提交了一个问题,寻求更简单的解决方案。 https://github.com/mrdoob/three.js/issues/4716


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接