- /* see if this normal has already been voted */
- for( k = 0; k < numVotes; k++ )
- {
- _pico_subtract_vec( plane, votes[ k ], diff );
- if( fabs( diff[ 0 ] ) < EQUAL_NORMAL_EPSILON &&
- fabs( diff[ 1 ] ) < EQUAL_NORMAL_EPSILON &&
- fabs( diff[ 2 ] ) < EQUAL_NORMAL_EPSILON )
- break;
- }
-
- /* add a new vote? */
- if( k == numVotes && numVotes < MAX_NORMAL_VOTES )
- {
- _pico_copy_vec( plane, votes[ numVotes ] );
- numVotes++;
- }
+ return index;
+ }
+}
+
+picoIndex_t UniqueIndices_insert( UniqueIndices* self, picoIndex_t value ){
+ if ( self->tree.data == self->tree.last ) {
+ binarytree_extend( &self->tree );
+ indexarray_push_back( &self->indices, value );
+ return 0;
+ }
+ else
+ {
+ return UniqueIndices_find_or_insert( self, value );
+ }
+}
+
+typedef struct picoSmoothVertices_s picoSmoothVertices_t;
+struct picoSmoothVertices_s
+{
+ picoVec3_t* xyz;
+ picoIndex_t* smoothingGroups;
+};
+
+int lessSmoothVertex( void* data, picoIndex_t first, picoIndex_t second ){
+ picoSmoothVertices_t* smoothVertices = data;
+
+ if ( smoothVertices->xyz[first][0] != smoothVertices->xyz[second][0] ) {
+ return smoothVertices->xyz[first][0] < smoothVertices->xyz[second][0];
+ }
+ if ( smoothVertices->xyz[first][1] != smoothVertices->xyz[second][1] ) {
+ return smoothVertices->xyz[first][1] < smoothVertices->xyz[second][1];
+ }
+ if ( smoothVertices->xyz[first][2] != smoothVertices->xyz[second][2] ) {
+ return smoothVertices->xyz[first][2] < smoothVertices->xyz[second][2];
+ }
+ if ( smoothVertices->smoothingGroups[first] != smoothVertices->smoothingGroups[second] ) {
+ return smoothVertices->smoothingGroups[first] < smoothVertices->smoothingGroups[second];
+ }
+ return 0;
+}
+
+void _pico_vertices_combine_shared_normals( picoVec3_t* xyz, picoIndex_t* smoothingGroups, picoVec3_t* normals, picoIndex_t numVertices ){
+ UniqueIndices vertices;
+ IndexArray indices;
+ picoSmoothVertices_t smoothVertices = { xyz, smoothingGroups };
+ UniqueIndices_init( &vertices, lessSmoothVertex, &smoothVertices );
+ UniqueIndices_reserve( &vertices, numVertices );
+ indexarray_reserve( &indices, numVertices );
+
+
+ {
+ picoIndex_t i = 0;
+ for (; i < numVertices; ++i )
+ {
+ size_t size = UniqueIndices_size( &vertices );
+ picoIndex_t index = UniqueIndices_insert( &vertices, i );
+ if ( (size_t)index != size ) {
+ float* normal = normals[vertices.indices.data[index]];
+ _pico_add_vec( normal, normals[i], normal );