Changeset 294


Ignore:
Timestamp:
07/28/14 03:05:19 (11 years ago)
Author:
epyon
Message:
  • mesh_creator -- very robust tangent generation mechanism
  • keyframed_mesh - support for meshes with tangent data
  • minor cleanups
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/formats/assimp_loader.hh

    r293 r294  
    2828                virtual size_t get_nodes_data_count() const;
    2929                virtual mesh_nodes_data* release_mesh_nodes_data( size_t index = 0 );
    30                 mesh_nodes_data* release_animation( size_t index );
    3130                void scene_report() const;
    3231        private:
  • trunk/nv/gfx/keyframed_mesh.hh

    r288 r294  
    3636                        vec3 normal;
    3737                };
     38                struct vertex_pnt
     39                {
     40                        vec3 position;
     41                        vec3 normal;
     42                        vec4 tangent;
     43                };
    3844                struct vertex_t
    3945                {
     
    4147                };
    4248
    43                 const mesh_data*       m_mesh_data;
    44                 const mesh_nodes_data* m_tag_map;
     49                const mesh_data*        m_mesh_data;
     50                const mesh_nodes_data*  m_tag_map;
     51                const mesh_raw_channel* m_vchannel;
    4552
    4653                uint32 m_last_frame;
    4754                uint32 m_next_frame;
     55                uint32 m_vsize;
    4856                f32    m_interpolation;
     57                bool   m_has_tangent;
    4958                bool   m_active;
    5059
     
    6372                int m_loc_next_position;
    6473                int m_loc_next_normal;
     74                int m_loc_next_tangent;
    6575
    6676                uint32 m_gpu_last_frame;
     
    7383                keyframed_mesh_cpu( device* a_device, const mesh_data* a_data, const mesh_nodes_data* a_tag_map );
    7484                void update( uint32 ms );
     85                ~keyframed_mesh_cpu();
    7586        private:
    76                 std::vector<vertex_pn> m_vertex;
    77                 vertex_buffer*         m_vb;
     87                uint8*         m_data;
     88                vertex_buffer* m_vb;
    7889        };
    7990
  • trunk/nv/gfx/mesh_creator.hh

    r293 r294  
    2121                // assumes that position and normal is vec3, tangent is vec4
    2222                void transform( float scale, const mat3& r33 );
     23                // TODO: this could generate normals too
     24                void generate_tangents();
    2325        private:
     26                mesh_raw_channel* merge_channels( mesh_raw_channel* a, mesh_raw_channel* b );
     27
    2428                mesh_data* m_data;
    2529        };
     
    4448                // assumes that keys are equally spaced
    4549                void pre_transform_keys() { mesh_nodes_creator( m_pack->m_nodes ).pre_transform_keys(); }
     50                void generate_tangents()
     51                {
     52                        for ( size_t m = 0; m < m_pack->m_count; ++m )
     53                                mesh_data_creator( &(m_pack->m_meshes[m]) ).generate_tangents();
     54                }
     55
    4656                // assumes that keys are equally spaced
    4757                void merge_keys() { mesh_nodes_creator( m_pack->m_nodes ).merge_keys(); }
     
    5161                        for ( size_t m = 0; m < m_pack->m_count; ++m )
    5262                                mesh_data_creator( &(m_pack->m_meshes[m]) ).transform( scale, r33 );
    53                         mesh_nodes_creator( m_pack->m_nodes ).transform( scale, r33 );
     63                        if ( m_pack->m_nodes )
     64                                mesh_nodes_creator( m_pack->m_nodes ).transform( scale, r33 );
    5465                }
    5566        private:
  • trunk/nv/interface/mesh_data.hh

    r293 r294  
    8383        {
    8484                friend class mesh_creator;
     85                friend class mesh_data_creator;
    8586        public:
    8687                explicit mesh_data() : m_index_channel( nullptr ) {}
  • trunk/src/formats/assimp_loader.cc

    r293 r294  
    339339}
    340340
    341 mesh_nodes_data* nv::assimp_loader::release_animation( size_t index )
     341mesh_nodes_data* nv::assimp_loader::release_mesh_nodes_data( size_t index /*= 0*/ )
    342342{
    343343        if ( m_scene == nullptr ) return nullptr;
     
    476476        }
    477477
    478         mesh_nodes_data* nodes = ( has_bones ? release_merged_bones( meshes ) : release_animation(0) );
     478        mesh_nodes_data* nodes = ( has_bones ? release_merged_bones( meshes ) : release_mesh_nodes_data(0) );
    479479        return new mesh_data_pack( m_mesh_count, meshes, nodes );
    480480}
     
    487487}
    488488
    489 mesh_nodes_data* nv::assimp_loader::release_mesh_nodes_data( size_t index /*= 0 */ )
    490 {
    491         return release_animation( index );
    492 }
    493 
     489
  • trunk/src/gfx/keyframed_mesh.cc

    r288 r294  
    2828        m_index_count  = m_mesh_data->get_index_channel()->count;
    2929        m_vertex_count = m_mesh_data->get_channel<vertex_t>()->count;
    30         m_frame_count  = m_mesh_data->get_channel<vertex_pn>()->count / m_vertex_count;
     30        m_vchannel     = m_mesh_data->get_channel<vertex_pnt>();
     31        m_vsize        = sizeof( vertex_pnt );
     32        m_has_tangent  = true;
     33        if ( m_vchannel == nullptr )
     34        {
     35                m_vchannel     = m_mesh_data->get_channel<vertex_pn>();
     36                m_has_tangent  = false;
     37                m_vsize        = sizeof( vertex_pn );
     38        }
     39        m_frame_count  = m_vchannel->count / m_vertex_count;
    3140}
    3241
     
    116125nv::keyframed_mesh_gpu::keyframed_mesh_gpu( device* a_device, const mesh_data* a_data, const mesh_nodes_data* a_tag_map, program* a_program )
    117126        : keyframed_mesh( a_device, a_data, a_tag_map )
    118         , m_loc_next_position( 0 )
    119         , m_loc_next_normal( 0 )
     127        , m_loc_next_position( -1 )
     128        , m_loc_next_normal( -1 )
     129        , m_loc_next_tangent( -1 )
    120130        , m_gpu_last_frame( 0xFFFFFFFF )
    121131        , m_gpu_next_frame( 0xFFFFFFFF )
     
    123133        m_loc_next_position = a_program->get_attribute( "nv_next_position" )->get_location();
    124134        m_loc_next_normal   = a_program->get_attribute( "nv_next_normal" )->get_location();
     135        m_loc_next_tangent  = a_program->try_get_attribute_location( "nv_next_tangent" );
    125136        m_va = a_device->create_vertex_array( a_data, STATIC_DRAW );
    126137        vertex_buffer* vb = m_va->find_buffer( slot::POSITION );
    127         m_va->add_vertex_buffer( m_loc_next_position, vb, FLOAT, 3, 0,              sizeof( vertex_pn ), false );
    128         m_va->add_vertex_buffer( m_loc_next_normal,   vb, FLOAT, 3, sizeof( vec3 ), sizeof( vertex_pn ), false );
     138        m_va->add_vertex_buffer( m_loc_next_position, vb, FLOAT, 3, 0, m_vsize, false );
     139        m_va->add_vertex_buffer( m_loc_next_normal,   vb, FLOAT, 3, sizeof( vec3 ), m_vsize, false );
     140        if ( m_has_tangent )
     141                m_va->add_vertex_buffer( m_loc_next_tangent, vb, FLOAT, 4, 2*sizeof( vec3 ), m_vsize, false );
    129142}
    130143
     
    136149        if ( m_gpu_last_frame != m_last_frame )
    137150        {
    138                 m_va->update_vertex_buffer( slot::POSITION, m_last_frame * m_vertex_count * sizeof( vertex_pn ) );
    139                 m_va->update_vertex_buffer( slot::NORMAL,   m_last_frame * m_vertex_count * sizeof( vertex_pn ) + sizeof( vec3 ) );
     151                m_va->update_vertex_buffer( slot::POSITION, m_last_frame * m_vertex_count * m_vsize );
     152                m_va->update_vertex_buffer( slot::NORMAL,   m_last_frame * m_vertex_count * m_vsize + sizeof( vec3 ) );
     153                if ( m_has_tangent && m_loc_next_tangent != -1 )
     154                {
     155                        m_va->update_vertex_buffer( slot::TANGENT,   m_last_frame * m_vertex_count * m_vsize + 2*sizeof( vec3 ) );
     156                }
    140157                m_gpu_last_frame = m_last_frame;
    141158        }
    142159        if ( m_gpu_next_frame != m_next_frame )
    143160        {
    144                 m_va->update_vertex_buffer( m_loc_next_position, m_next_frame * m_vertex_count * sizeof( vertex_pn ) );
    145                 m_va->update_vertex_buffer( m_loc_next_normal,   m_next_frame * m_vertex_count * sizeof( vertex_pn ) + sizeof( vec3 ) );
     161                m_va->update_vertex_buffer( m_loc_next_position, m_next_frame * m_vertex_count * m_vsize );
     162                m_va->update_vertex_buffer( m_loc_next_normal,   m_next_frame * m_vertex_count * m_vsize + sizeof( vec3 ) );
     163                m_va->update_vertex_buffer( m_loc_next_tangent,   m_next_frame * m_vertex_count * m_vsize + 2*sizeof( vec3 ) );
    146164                m_gpu_next_frame = m_next_frame;
    147165        }
     
    151169        : keyframed_mesh( a_device, a_data, a_tag_map )
    152170{
    153         m_vb = a_device->create_vertex_buffer( nv::STATIC_DRAW, m_vertex_count * sizeof( vertex_pn ), (void*)m_mesh_data->get_channel<vertex_pn>()->data );
    154         m_va->add_vertex_buffers( m_vb, m_mesh_data->get_channel<vertex_pn>() );
     171        m_vb = a_device->create_vertex_buffer( nv::STATIC_DRAW, m_vertex_count * m_vsize, (void*)m_vchannel->data );
     172        m_va->add_vertex_buffers( m_vb, m_vchannel );
    155173
    156174        nv::vertex_buffer* vb = a_device->create_vertex_buffer( nv::STATIC_DRAW, m_vertex_count * sizeof( nv::vec2 ), (void*)m_mesh_data->get_channel<vertex_t>()->data );
     
    160178        m_va->set_index_buffer( ib, m_mesh_data->get_index_channel()->desc.slots[0].etype, true );
    161179
    162         m_vertex.resize( m_vertex_count );
     180        m_data = new uint8[ m_vertex_count * m_vsize ];
    163181}
    164182
     
    167185        animated_mesh::update( ms );
    168186
    169         const vertex_pn* data = m_mesh_data->get_channel_data<vertex_pn>();
    170         const vertex_pn* prev = data + m_vertex_count * m_last_frame;
    171         const vertex_pn* next = data + m_vertex_count * m_next_frame;
    172 
    173         for ( size_t i = 0; i < m_vertex_count; ++i )
    174         {
    175                 m_vertex[i].position = glm::mix( prev[i].position, next[i].position, m_interpolation );
    176                 m_vertex[i].normal   = glm::mix( prev[i].normal,   next[i].normal,   m_interpolation );
     187        // TODO: this could be done generic for any data
     188        if ( m_has_tangent )
     189        {
     190                const vertex_pnt* data = m_mesh_data->get_channel_data<vertex_pnt>();
     191                const vertex_pnt* prev = data + m_vertex_count * m_last_frame;
     192                const vertex_pnt* next = data + m_vertex_count * m_next_frame;
     193                      vertex_pnt* vtx  = (vertex_pnt*)m_data;
     194                for ( size_t i = 0; i < m_vertex_count; ++i )
     195                {
     196                        vtx[i].position = glm::mix( prev[i].position, next[i].position, m_interpolation );
     197                        vtx[i].normal   = glm::mix( prev[i].normal,   next[i].normal,   m_interpolation );
     198                        vtx[i].tangent  = glm::mix( prev[i].tangent,  next[i].tangent,   m_interpolation );
     199                }
     200        }
     201        else
     202        {
     203                const vertex_pn* data = m_mesh_data->get_channel_data<vertex_pn>();
     204                const vertex_pn* prev = data + m_vertex_count * m_last_frame;
     205                const vertex_pn* next = data + m_vertex_count * m_next_frame;
     206                      vertex_pn* vtx  = (vertex_pn*)m_data;
     207
     208                for ( size_t i = 0; i < m_vertex_count; ++i )
     209                {
     210                        vtx[i].position = glm::mix( prev[i].position, next[i].position, m_interpolation );
     211                        vtx[i].normal   = glm::mix( prev[i].normal,   next[i].normal,   m_interpolation );
     212                }
    177213        }
    178214
    179215        m_vb->bind();
    180         m_vb->update( m_vertex.data(), 0, m_vertex_count * sizeof( vertex_pn ) );
     216        m_vb->update( m_data, 0, m_vertex_count * m_vsize );
    181217        m_vb->unbind();
    182218}
     219
     220nv::keyframed_mesh_cpu::~keyframed_mesh_cpu()
     221{
     222        delete[] m_data;
     223}
  • trunk/src/gfx/mesh_creator.cc

    r293 r294  
    162162        }
    163163}
     164
     165struct vertex_g
     166{
     167        nv::vec4 tangent;
     168};
     169
     170void nv::mesh_data_creator::generate_tangents()
     171{
     172        int p_offset = -1;
     173        int n_offset = -1;
     174        int t_offset = -1;
     175        datatype i_type = NONE;
     176        uint32 n_channel_index = 0;
     177
     178        const mesh_raw_channel* p_channel = nullptr;
     179              mesh_raw_channel* n_channel = nullptr;
     180        const mesh_raw_channel* t_channel = nullptr;
     181        const mesh_raw_channel* i_channel = nullptr;
     182
     183        for ( uint32 c = 0; c < m_data->get_channel_count(); ++c )
     184        {
     185                const mesh_raw_channel* channel = m_data->get_channel(c);
     186                const vertex_descriptor& desc   = channel->desc;
     187                for ( uint32 i = 0; i < desc.count; ++i )
     188                        switch ( desc.slots[i].vslot )
     189                {
     190                        case slot::POSITION :
     191                                if ( desc.slots[i].etype == FLOAT_VECTOR_3 )
     192                                {
     193                                        p_offset  = desc.slots[i].offset;
     194                                        p_channel = channel;
     195                                }
     196                                break;
     197                        case slot::NORMAL   : if ( desc.slots[i].etype == FLOAT_VECTOR_3 )
     198                                {
     199                                        n_offset  = desc.slots[i].offset;
     200                                        n_channel = m_data->m_channels[ c ];
     201                                        n_channel_index = c;
     202                                }
     203                                break;
     204                        case slot::TEXCOORD : if ( desc.slots[i].etype == FLOAT_VECTOR_2 )
     205                                {
     206                                        t_offset  = desc.slots[i].offset;
     207                                        t_channel = channel;
     208                                }
     209                                break;
     210                        case slot::INDEX    :
     211                                {
     212                                        i_type    = desc.slots[i].etype;
     213                                        i_channel = channel;
     214                                }
     215                                break;
     216                        case slot::TANGENT  : return;
     217                        default             : break;
     218                }
     219        }
     220        if ( !p_channel || !n_channel || !t_channel ) return;
     221
     222        if ( p_channel->count != n_channel->count || p_channel->count % t_channel->count != 0 || ( i_type != UINT && i_type != USHORT && i_type != NONE ) )
     223        {
     224                return;
     225        }
     226
     227        mesh_raw_channel* g_channel = mesh_raw_channel::create<vertex_g>( p_channel->count );
     228        vec4* tangents              = (vec4*)g_channel->data;
     229        vec3* tangents2             = new vec3[ p_channel->count ];
     230        uint32 tri_count = i_channel ? i_channel->count / 3 : t_channel->count / 3;
     231        uint32 vtx_count = p_channel->count;
     232        uint32 sets      = p_channel->count / t_channel->count;
     233
     234        for ( unsigned int i = 0; i < tri_count; ++i )
     235        {
     236                uint32 ti0 = 0;
     237                uint32 ti1 = 0;
     238                uint32 ti2 = 0;
     239                if ( i_type == UINT )
     240                {
     241                        const uint32* idata = (const uint32*)i_channel->data;
     242                        ti0 = idata[ i * 3 ];
     243                        ti1 = idata[ i * 3 + 1 ];
     244                        ti2 = idata[ i * 3 + 2 ];
     245                }
     246                else if ( i_type == USHORT )
     247                {
     248                        const uint16* idata = (const uint16*)i_channel->data;
     249                        ti0 = idata[ i * 3 ];
     250                        ti1 = idata[ i * 3 + 1 ];
     251                        ti2 = idata[ i * 3 + 2 ];
     252                }
     253                else // if ( i_type == NONE )
     254                {
     255                        ti0 = i * 3;
     256                        ti1 = i * 3 + 1;
     257                        ti2 = i * 3 + 2;
     258                }
     259
     260                const vec2& w1 = *((vec2*)(t_channel->data + t_channel->desc.size*ti0 + t_offset ));
     261                const vec2& w2 = *((vec2*)(t_channel->data + t_channel->desc.size*ti1 + t_offset ));
     262                const vec2& w3 = *((vec2*)(t_channel->data + t_channel->desc.size*ti2 + t_offset ));
     263                vec2 st1 = w3 - w1;
     264                vec2 st2 = w2 - w1;
     265                float stst = (st1.x * st2.y - st2.x * st1.y);
     266                float coef = ( stst != 0.0f ? 1.0f / stst : 0.0f );
     267
     268                for ( uint32 set = 0; set < sets; ++set )
     269                {
     270                        uint32 nti0 = t_channel->count * set + ti0;
     271                        uint32 nti1 = t_channel->count * set + ti1;
     272                        uint32 nti2 = t_channel->count * set + ti2;
     273                        vec3 v1 = *((vec3*)(p_channel->data + p_channel->desc.size*nti0 + p_offset ));
     274                        vec3 v2 = *((vec3*)(p_channel->data + p_channel->desc.size*nti1 + p_offset ));
     275                        vec3 v3 = *((vec3*)(p_channel->data + p_channel->desc.size*nti2 + p_offset ));
     276                        vec3 xyz1 = v3 - v1;
     277                        vec3 xyz2 = v2 - v1;
     278
     279                        //glm::vec3 normal = glm::cross( xyz1, xyz2 );
     280                        //
     281                        //vtcs[ ti0 ].normal += normal;
     282                        //vtcs[ ti1 ].normal += normal;
     283                        //vtcs[ ti2 ].normal += normal;
     284                        vec3 tangent  = (( xyz1 * st2.y ) - ( xyz2 * st1.y )) * coef;
     285                        vec3 tangent2 = (( xyz2 * st1.x ) - ( xyz1 * st2.x )) * coef;
     286
     287                        tangents[nti0] = vec4( vec3( tangents[nti0] ) + tangent, 0 );
     288                        tangents[nti1] = vec4( vec3( tangents[nti1] ) + tangent, 0 );
     289                        tangents[nti2] = vec4( vec3( tangents[nti2] ) + tangent, 0 );
     290
     291                        tangents2[nti0] += tangent2;
     292                        tangents2[nti1] += tangent2;
     293                        tangents2[nti2] += tangent2;
     294                }
     295        }
     296
     297        for ( unsigned int i = 0; i < vtx_count; ++i )
     298        {
     299                const vec3 n = *((vec3*)(n_channel->data + n_channel->desc.size*i + n_offset ));
     300                const vec3 t = vec3(tangents[i]);
     301                if ( ! ( t.x == 0.0f && t.y == 0.0f && t.z == 0.0f ) )
     302                {
     303                        tangents[i]    = vec4( glm::normalize(t - n * glm::dot( n, t )), 0.0f );
     304                        tangents[i][3] = (glm::dot(glm::cross(n, t), tangents2[i]) < 0.0f) ? -1.0f : 1.0f;
     305                }
     306        }
     307        delete tangents2;
     308
     309        m_data->m_channels[ n_channel_index ] = merge_channels( n_channel, g_channel );
     310        delete n_channel;
     311        delete g_channel;
     312}
     313
     314nv::mesh_raw_channel* nv::mesh_data_creator::merge_channels( mesh_raw_channel* a, mesh_raw_channel* b )
     315{
     316        NV_ASSERT( a->count == b->count, "merge_channel - bad channels!" );
     317        vertex_descriptor adesc = a->desc;
     318        vertex_descriptor bdesc = b->desc;
     319        uint32            count = a->count;
     320
     321        vertex_descriptor desc  = a->desc;
     322        for ( uint32 i = 0; i < bdesc.count; i++ )
     323        {
     324                desc.slots[desc.count+i] = bdesc.slots[i];
     325                desc.slots[desc.count+i].offset += desc.size;
     326        }
     327        desc.size  += bdesc.size;
     328        desc.count += bdesc.count;
     329        uint8* data = new uint8[ count * desc.size ];
     330        for ( uint32 i = 0; i < count; ++i )
     331        {
     332                std::copy_n( a->data + i * adesc.size, adesc.size, data + i*desc.size );
     333                std::copy_n( b->data + i * bdesc.size, bdesc.size, data + i*desc.size + adesc.size );
     334        }
     335        mesh_raw_channel* result = new mesh_raw_channel;
     336        result->count = count;
     337        result->desc  = desc;
     338        result->data  = data;
     339        return result;
     340}
Note: See TracChangeset for help on using the changeset viewer.