EDIT: Solved, found a similar issue here and adopted OP’s strategy (set the rest of the array to the most recent controller position every frame. Still not sure how setDrawRange even worked, per that comment. Leaving this here for posterity!)
Working code:
for (var i = this.currentPos; i < MAX_POINTS * 3; i++) {
this.positions[i * 3] = position.x;
this.positions[i * 3 + 1] = position.y;
this.positions[i * 3 + 2] = position.z;
}
this.currentPos++;
this.line.setBufferArray(this.positions);
}
Hi everyone,
I’m working with threejs-meshline (Ryan King’s fork of @thespite’s pretty notable lib) trying to create a brush for Tilt Brush-type painting in WebXR. The code is currently working, but performs pretty horribly (in contrast to regular lines, which work fine; however, we need a “brush-like” line width). I’ve been through the weeds of how to approach updating the geometry and have settled on:
-
Creating an initial
Float32Array
calledthis.positions
of size (MAX_POINTS *3
) (whereMAX_POINTS
is 100, 1000, 10000 - doesn’t seem to impact perf at those ranges), and adrawCount
counter that’ll update every frame and set the range to that counter, basically updating the latest controller position vector in the array and drawing a line to it. -
Creating a new
MeshLine()
object andsetGeometry
ing said array -
On Update (/rAF), if controller trigger is pressed, update said array as such:
DrawLine(position) {
this.positions[this.drawCount * 3] = position.x;
this.positions[this.drawCount * 3 + 1] = position.y;
this.positions[this.drawCount * 3 + 2] = position.z;
this.drawCount++;
this.line.setBufferArray(this.positions);
this.line.setDrawRange(0, this.drawCount);
}
where setBufferArray looks like this:
MeshLine.prototype.setBufferArray = function(ba, wcb) {
this._bufferArray = ba
this.widthCallback = wcb || this.widthCallback
this.positions = []
this.counters = []
for (var j = 0; j < ba.length; j += 3) {
var c = j / ba.length
this.positions.push(ba[j], ba[j + 1], ba[j + 2])
this.positions.push(ba[j], ba[j + 1], ba[j + 2])
this.counters.push(c)
this.counters.push(c)
}
this.process()
}
here’s what it looks like. Unamazing…
As I’d mentioned, this happens extremely slowly on a very good machine (i7, 32GB Ram, 2070RTX…).
I’m wondering what the most optimized way to dynamically create meshlines is, given that I’m already working with Float32Arrays and MeshLines (which inherit from BufferGeometry). I’ve taken a look at the fat lines example but unless I’m wrong, it doesn’t lend itself to dynamic position updating at runtime. I might give it another go, but at this point I’ve been dealing with this long enough to seek help.
The current code is here.
Any/all pointers very welcome. Thank you in advance!