Reputation: 875
I've got a THREE.LineSegments
object, and I want to change the number of vertices dynamically. When I modify the geometry vertices array, though, any lines with vertices that were removed just stay put.
Is there a way to remove vertices after the geometry has been created?
e.g., Below I'm taking a LineSegments
object with 3 segments, and trying to change it later to have only 2 segments. The last line segment remains.
var scene,
renderer,
camera;
var line;
initScene();
initLine();
setInterval(update, 500);
function initScene() {
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000),
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
camera.position.z = 5;
scene.add(camera);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function initLine() {
var verts = [
randomV3(),
randomV3(),
randomV3(),
randomV3()
];
var geom = new THREE.Geometry();
geom.vertices = [
verts[0], verts[1],
verts[1], verts[2],
verts[2], verts[3]
];
line = new THREE.LineSegments(geom, new THREE.LineBasicMaterial({
color: 0xff00ff,
linewidth: 3
}));
scene.add(line);
renderer.render(scene, camera);
}
function update() {
var verts = [
randomV3(),
randomV3(),
randomV3()
];
line.geometry.vertices = [
verts[0], verts[1],
verts[1], verts[2]
];
line.geometry.verticesNeedUpdate = true;
renderer.render(scene, camera);
}
function randomV3() {
return new THREE.Vector3(
(Math.random() * 4) - 2,
(Math.random() * 4) - 2,
0
)
}
body {
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script>
Upvotes: 4
Views: 1400
Reputation: 31026
One approach to solve this problem is to dispose the old geometry and then create a new one like so:
line.geometry.dispose();
line.geometry = new THREE.Geometry();
line.geometry.vertices = [
verts[0], verts[1],
verts[1], verts[2]
];
This approach is demonstrated in the following fiddle. However, consider to use THREE.BufferGeometry
in order to have a more future-proof solution (THREE.Geometry
will not be renderable at some point anymore). Here is a fiddle with the same code but with THREE.BufferGeometry
.
Instead of disposing the geometry, you could also create a THREE.BufferGeometry
with enough buffer space so it can represent the biggest line object in your application. This approach is necessary since you can't resize buffers, only update their contents. The details are explained in this guide:
https://threejs.org/docs/index.html#manual/en/introduction/How-to-update-things
BTW: Setting linewidth
has no effect when rendering line primitives in three.js
. The always have the width of 1 pixel.
three.js R103
Upvotes: 4