Maybe i just made a silly mistake, but i wrote a quick function to generate a indexed geometry from a non-indexed one for a test. But for some reasons it will be always wrong (a lot faces missing/wrong), while all vertices are only merged into an index.
Maybe you have some non-indexed geometry floating around to test. geometry
is the non-indexed geometry for input and out
should be a empty new THREE.BufferGeometry
instance.
Edit: And as expected it was just a silly mistake, i’ve used signed ArrayBuffers instead unsigned ones.
function indexBuffer(geometry, out) {
const vertices = {};
const list = [];
function KEY(v) {
return Math.floor( v.x * 1000 ) + '_' + Math.floor( v.y * 1000 ) + '_' + Math.floor( v.z * 1000 );
}
function VERTEX(v) {
const id = KEY(v);
if ( vertices[id] === undefined ) {
vertices[id] = list.length;
list.push(v);
}
return vertices[id];
}
const faces = geometry.faces;
const type = faces.length * 3 > 65536 ? Int32Array : Int16Array;
const array = new type(faces.length * 3);
for ( let i = 0, l = faces.length; i < l; i ++ ) {
const face = faces[i];
array[i * 3 ] = VERTEX(geometry.vertices[face.a]);
array[i * 3 + 1] = VERTEX(geometry.vertices[face.b]);
array[i * 3 + 2] = VERTEX(geometry.vertices[face.c]);
}
out.index = new THREE.BufferAttribute(array, 1);
const verticesArray = new Float32Array(list.length * 3);
for ( let i = 0, l = list.length; i < l; i ++ ) {
const vertex = list[i];
verticesArray[i * 3 ] = vertex.x;
verticesArray[i * 3 + 1] = vertex.y;
verticesArray[i * 3 + 2] = vertex.z;
}
out.attributes.position = new THREE.BufferAttribute(verticesArray, 3);
}