I would like to be able to load my gltf files with Line2/LineSegments2 as lines. when the primitive mode is GL_LINE_STRIP or GL_LINES. because i need other line widths than 1.
@donmccurdy @WestLangley Do you have ideas on how to approach this?
Sorry, this is not the place to get help. If you need help writing your app, please post your question on a help site.
I see this as a feature request since it is not possible to load gltf lines as something else than THREE.Line/THREE.LineSegments, I think the same goes for most of the other loaders.
Since Line2/LineSegments2 isn't part of the core library it's not simple to just add the option in a loader. I'd suggest trying to replace the objects after loading, e.g.
lines = [];
object.traverse( ( o ) => {
if ( o.isLine ) lines.push( o );
} );
lines.forEach( ( line ) => {
line2 = new THREE.Line2( line.geometry. line.material );
line.parent.add( line2 );
line.parent.remove( line );
line.children.forEach( ( o ) => line2.add( o ) );
} );
If that turns out not to be straightforward, we can discuss options on the forum I think.
i need other line widths than 1.
No line width in gltf core spec and the spec recommends to render points and lines as 1px size/width because of the consistency across gltf viewers.
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#point-and-line-materials
So I think fat lines should be user app specific and setting out of the loader is good as Don suggested.
@donmccurdy Yes, thanks. I was going for that solution as well. I wasn't aware that this would turn out difficult.
@takahirox i see you your point there.
The problem with GL_LINES/GL_LINE_STRIP (THREE.LineSegments/THREE.LIne) is that there is no guarantee any browser will display any other width than 1, so you should stay with 1. But this is quite an issue for higher resolution monitors (e.g. 4K or even 8K) because the lines are getting really thin there (glLineWidth = 1 meaning 1 pixel width).
So i think triangle based lines like Line2/LineSegments2 would be the way go and should be considered to be added to the core library. But that's another topic ...
We have an indexed geometry in our GLTF file representing all line segments.
This works and is basically doing what @donmccurdy suggests:
function toLineSegmentsGeometry(bufferGeometry: BufferGeometry)
{
const lg = new LineSegmentsGeometry();
const a = bufferGeometry.attributes;
if (a.position === undefined) {
return;
}
const position = a.position;
if (!(position instanceof InterleavedBufferAttribute)) {
return;
}
const data = position.data;
if (!(data instanceof InterleavedBuffer)) {
return;
}
const stride = data.stride;
const indexAttribute = bufferGeometry.index;
if (indexAttribute === null) {
return;
}
console.log(bufferGeometry);
const positions = [];
for (let index = 0; index != indexAttribute.array.length; ++index) {
const i = indexAttribute.array[index] * stride;
const x = data.array[i];
const y = data.array[i + 1];
const z = data.array[i + 2];
positions.push(x, y, z);
}
lg.setPositions(positions);
lg.userData = bufferGeometry.userData;
return lg;
}
However, I'd much rather not convert from an indexed geometry to an unindexed one, doing the much nicer:
function toLineSegmentsGeometry(bufferGeometry: BufferGeometry)
{
const lg = new LineSegmentsGeometry();
const a = bufferGeometry.attributes;
if (a.position === undefined) {
return;
}
const position = a.position;
if (!(position instanceof InterleavedBufferAttribute)) {
return;
}
lg.setAttribute("position", a.position);
lg.setIndex(bufferGeometry.index);
lg.userData = bufferGeometry.userData;
return lg;
}
But this doesn't work. I don't get any error and nothing is rendered. From BufferGeometry's documentation, I can't quite deduce what I'm doing wrong. It would be great if there were some documentation on this.
@fiesh Please ask such help questions at the forum or stackoverflow.
Most helpful comment
@fiesh Please ask such help questions at the forum or stackoverflow.