0
votes

I'm having trouble with removing duplicate vertices from a SphereGeomerty. I want to get rid of the seam on side of the geometry, because it don't align well if I update the vertex positions.

Problem is that I can't create a new geometry with a filtered vertex position list, I get an

[.Offscreen-For-WebGL-000001B883B499D0]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0

error.

More strange, if I put back the original vertex list to the bufferGeometry nothing is rendered, but the error is gone:

let positions = sphere.attributes.position.array;
filteredGeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );

I'm filtering vertices like this:

function removeDuplicateVertices(vertices) {
    var positionLookup = [];
    var final = [];

    for( let i = 0; i < vertices.length-3; i += 3 ) {
        var index = vertices[i] + vertices[i + 1] + vertices[i + 2];

        if( positionLookup.indexOf( index ) == -1 ) {
            positionLookup.push( index );
            final.push(vertices[i])
            final.push(vertices[i+1])
            final.push(vertices[i+2])
        }
    }
    return final;
}
1

1 Answers

1
votes

The SphereBufferGeometry uses an index-attribute. So the vertices-array doesn't store triangles directly but just the points. The triangles are constructed from the additional index-attribute which contains three indices into the position-attribute for each triangle. If you modify the position-attribute you have to update the index-attribute accordingly.

Or you can use geometry.toNonIndexed() to convert the "position + index" format to the "just position" format.

Also have a look at the Geometry.mergeVertices() function, which does exactly what you are doing, only for regular (not Buffer-) Geometries. This is also called when building a regular SphereGeometry, maybe that already helps?