Exemplo n.º 1
0
Arquivo: Mesh.cpp Projeto: 9heart/DT3
void Mesh::collapse_verts (void)
{
    const DTuint HASH_TABLE_SIZE = 1021;
    DTsize num_old_verts = _vertex_stream.size();
    DTsize num_new_verts = 0;
        
    //
    // Rebuild the mesh
    //
    
    std::vector<Vector3>		vertex_stream;
    std::vector<Vector3>		normals_stream;
    std::vector<Vector3>		tangents_stream;
    std::vector<Color4b>		colors_stream;
    std::vector<Vector2>        uvs_stream_0;
    std::vector<Vector2>        uvs_stream_1;
    std::vector<WeightsIndex>   weights_index_stream;
    std::vector<Vector4>        weights_strength_stream;

    if (_vertex_stream.size() > 0)              vertex_stream.resize(num_old_verts);
    if (_normals_stream.size() > 0)             normals_stream.resize(num_old_verts);
    if (_tangents_stream.size() > 0)            tangents_stream.resize(num_old_verts);
    if (_colors_stream.size() > 0)              colors_stream.resize(num_old_verts);
    if (_uvs_stream_0.size())                   uvs_stream_0.resize(num_old_verts);
    if (_uvs_stream_1.size() > 0)               uvs_stream_1.resize(num_old_verts);
    if (_weights_index_stream.size() > 0)       weights_index_stream.resize(num_old_verts);
    if (_weights_strength_stream.size() > 0)    weights_strength_stream.resize(num_old_verts);
    
    // Hash all vertices
    std::list<std::pair<DTuint, DTuint>> vert_hashes[HASH_TABLE_SIZE];   // new index, old index
    for (DTuint i = 0; i < num_old_verts; ++i) {
    
        DTuint h = hash_vertex(i);
        
        // Add vertex only if unique
        std::list<std::pair<DTuint, DTuint>> &list = vert_hashes[h % HASH_TABLE_SIZE];
        std::list<std::pair<DTuint, DTuint>>::iterator j;
        
        for (j = list.begin(); j != list.end(); ++j) {
            if (j->second == i)
                continue;
        
            if (equal_vertex(j->second, i))
                break;
        }

        // It is unique so add the vertex to the new geometry
        if (j == list.end()) {
            if (vertex_stream.size() > 0)           vertex_stream[num_new_verts] = _vertex_stream[i];
            if (normals_stream.size() > 0)          normals_stream[num_new_verts] = _normals_stream[i];
            if (tangents_stream.size() > 0)			tangents_stream[num_new_verts] = _tangents_stream[i];
            if (colors_stream.size() > 0)           colors_stream[num_new_verts] = _colors_stream[i];
            if (uvs_stream_0.size() > 0)            uvs_stream_0[num_new_verts] = _uvs_stream_0[i];
            if (uvs_stream_1.size() > 0)            uvs_stream_1[num_new_verts] = _uvs_stream_1[i];
            if (weights_index_stream.size() > 0)    weights_index_stream[num_new_verts] = _weights_index_stream[i];
            if (weights_strength_stream.size() > 0) weights_strength_stream[num_new_verts] = _weights_strength_stream[i];
                    
            vert_hashes[h % HASH_TABLE_SIZE].push_back( std::make_pair(num_new_verts, i) );
            
            ++num_new_verts;
        }
    }
    
    // Time to re-wire the face indices
    for (DTuint f = 0; f < _indices_stream.size(); ++f) {
        DTuint &v0 = _indices_stream[f].v[0];
        DTuint &v1 = _indices_stream[f].v[1];
        DTuint &v2 = _indices_stream[f].v[2];
        
        ASSERT(v0 < num_old_verts);
        ASSERT(v1 < num_old_verts);
        ASSERT(v2 < num_old_verts);
    
        DTuint h0 = hash_vertex(v0);
        DTuint h1 = hash_vertex(v1);
        DTuint h2 = hash_vertex(v2);
        
        // Add vertex only if unique
        std::list<std::pair<DTuint, DTuint>> &list0 = vert_hashes[h0 % HASH_TABLE_SIZE];
        std::list<std::pair<DTuint, DTuint>> &list1 = vert_hashes[h1 % HASH_TABLE_SIZE];
        std::list<std::pair<DTuint, DTuint>> &list2 = vert_hashes[h2 % HASH_TABLE_SIZE];

        std::list<std::pair<DTuint, DTuint>>::iterator j;
        
        for (j = list0.begin(); j != list0.end(); ++j) {
            if (equal_vertex(j->second, v0)) {
                v0 = j->first;
                break;
            }
        }
                
        ASSERT(j != list0.end());
        ASSERT(v0 < num_new_verts);

        for (j = list1.begin(); j != list1.end(); ++j) {
            if (equal_vertex(j->second, v1)) {
                v1 = j->first;
                break;
            }
        }

        ASSERT(j != list1.end());
        ASSERT(v1 < num_new_verts);

        for (j = list2.begin(); j != list2.end(); ++j) {
            if (equal_vertex(j->second, v2)) {
                v2 = j->first;
                break;
            }
        }

        ASSERT(j != list2.end());
        ASSERT(v2 < num_new_verts);

    } 
    
                
	if (vertex_stream.size() > 0)           vertex_stream.resize(num_new_verts);
	if (normals_stream.size() > 0)          normals_stream.resize(num_new_verts);
	if (tangents_stream.size() > 0)			tangents_stream.resize(num_new_verts);
	if (colors_stream.size() > 0)           colors_stream.resize(num_new_verts);
	if (uvs_stream_0.size() > 0)            uvs_stream_0.resize(num_new_verts);
	if (uvs_stream_1.size() > 0)            uvs_stream_1.resize(num_new_verts);
	if (weights_index_stream.size() > 0)    weights_index_stream.resize(num_new_verts);
	if (weights_strength_stream.size() > 0) weights_strength_stream.resize(num_new_verts);
    
    _vertex_stream = vertex_stream;
    _normals_stream = normals_stream;
    _tangents_stream = tangents_stream;
    _colors_stream = colors_stream;
    _uvs_stream_0 = uvs_stream_0;
    _uvs_stream_1 = uvs_stream_1;
    _weights_index_stream = weights_index_stream;
    _weights_strength_stream = weights_strength_stream;
    
    LOG_MESSAGE << "Old size: " << num_old_verts;
    LOG_MESSAGE << "New size: " << num_new_verts;

}
Exemplo n.º 2
0
Arquivo: Mesh.cpp Projeto: UIKit0/DT3
void Mesh::generate_normals (void)
{
    ASSERT(_vertex_stream.size() > 0);

    const DTuint HASH_TABLE_SIZE = 1021;

    _normals_stream.clear();
    _normals_stream.resize(_vertex_stream.size(), Vector3(0.0F,0.0F,0.0F));
    
    // Fill hash table
    std::list<DTuint> vert_hashes[HASH_TABLE_SIZE];
    
    for (DTuint i = 0; i < _vertex_stream.size(); ++i) {
        DTuint h = hash_vertex (i, true);
        
        vert_hashes[h % HASH_TABLE_SIZE].push_back(i);
    }

    // Accumulate normals
	for (DTuint i = 0; i < _index_stream.size(); ++i) {
		DTuint ai,bi,ci;
		
		ai = _index_stream[i].v[0];
		bi = _index_stream[i].v[1];
		ci = _index_stream[i].v[2];
		
		ASSERT(ai < _vertex_stream.size());
		ASSERT(bi < _vertex_stream.size());
		ASSERT(ci < _vertex_stream.size());
		
		Vector3 n = Vector3::cross(_vertex_stream[bi] - _vertex_stream[ai], _vertex_stream[ci] - _vertex_stream[ai]);
		n.normalize();
        
        // Hashes of vertex positions
        DTuint h0 = hash_vertex(ai, true);
        DTuint h1 = hash_vertex(bi, true);
        DTuint h2 = hash_vertex(ci, true);
        
        // Get hash entries for verts
        std::list<DTuint> &list0 = vert_hashes[h0 % HASH_TABLE_SIZE];
        std::list<DTuint> &list1 = vert_hashes[h1 % HASH_TABLE_SIZE];
        std::list<DTuint> &list2 = vert_hashes[h2 % HASH_TABLE_SIZE];
        
        for (auto j : list0) {
            if (equal_vertex(ai, j, true))
                _normals_stream[j] += n;
        }

        for (auto j : list1) {
            if (equal_vertex(bi, j, true))
                _normals_stream[j] += n;
        }

        for (auto j : list2) {
            if (equal_vertex(ci, j, true))
                _normals_stream[j] += n;
        }
		
	}
	
	for (DTuint i = 0; i < _vertex_stream.size(); ++i)
		if (_normals_stream[i] != Vector3(0.0F,0.0F,0.0F))
			_normals_stream[i].normalize();
		
}