Changeset 287 for trunk/src/gfx/skeletal_mesh.cc
- Timestamp:
- 07/23/14 15:24:03 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gfx/skeletal_mesh.cc
r283 r287 11 11 12 12 13 nv::skeletal_mesh::skeletal_mesh( device* a_device, md5_mesh_data* a_mesh_data)13 nv::skeletal_mesh::skeletal_mesh( device* a_device, const mesh_data* a_mesh_data, const mesh_nodes_data* bones ) 14 14 : animated_mesh() 15 , m_mesh_data( nullptr ) 16 { 17 m_mesh_data = a_mesh_data->spawn(); 15 , m_data( a_mesh_data ) 16 { 17 const mesh_raw_channel* pnt_chan = a_mesh_data->get_channel<md5_vtx_pnt>(); 18 m_pntdata.assign( (const md5_vtx_pnt*)pnt_chan->data, pnt_chan->count ); 19 m_bone_offset.resize( bones->get_count() ); 20 for ( uint32 i = 0; i < bones->get_count(); ++i ) 21 { 22 m_bone_offset[i] = transform( bones->get_node(i)->transform ); 23 } 24 m_vtx_data = a_mesh_data->get_channel_data<md5_vtx_pntiw>(); 25 m_indices = a_mesh_data->get_count(); 18 26 m_va = a_device->create_vertex_array( a_mesh_data, nv::STREAM_DRAW ); 19 27 } … … 28 36 uint32 new_time = a_anim_time % anim_duration; 29 37 anim->update_skeleton( m_transform.data(), (float)new_time * 0.001f ); 30 m_mesh_data->apply( m_transform.data() ); 38 39 //m_mesh_data->apply( m_transform.data() ); 40 { 41 size_t skeleton_size = m_bone_offset.size(); 42 size_t vertex_count = m_pntdata.size(); 43 m_pos_offset.resize( skeleton_size ); 44 for ( unsigned int i = 0; i < skeleton_size; ++i ) 45 { 46 m_pos_offset[i] = m_transform[i] * m_bone_offset[i]; 47 } 48 49 std::fill( m_pntdata.raw_data(), m_pntdata.raw_data() + m_pntdata.raw_size(), 0 ); 50 for ( unsigned int i = 0; i < vertex_count; ++i ) 51 { 52 const md5_vtx_pntiw& vert = m_vtx_data[i]; 53 54 for ( size_t j = 0; j < 4; ++j ) 55 { 56 int index = vert.boneindex[j]; 57 float weight = vert.boneweight[j]; 58 const quat& orient = m_transform[index].get_orientation(); 59 const transform& offset = m_pos_offset[index]; 60 m_pntdata[i].position += offset.transformed( vert.position ) * weight; 61 m_pntdata[i].normal += ( orient * vert.normal ) * weight; 62 m_pntdata[i].tangent += ( orient * vert.tangent ) * weight; 63 } 64 } 65 } 66 31 67 vertex_buffer* vb = m_va->find_buffer( nv::slot::POSITION ); 32 68 vb->bind(); 33 vb->update( m_ mesh_data->data(), 0, m_mesh_data->size() );69 vb->update( m_pntdata.data(), 0, m_pntdata.raw_size() ); 34 70 vb->unbind(); 35 71 } … … 39 75 { 40 76 delete m_va; 41 delete m_mesh_data;42 77 } 43 78 … … 52 87 } 53 88 54 void nv::skeletal_animation_entry_gpu::update_skeleton( mat4* data, uint32 time ) 55 { 56 m_animation->animate( data, time ); 57 } 58 59 void nv::skeletal_animation_entry_gpu::prepare( const nmd_temp_model* m_model ) 60 { 61 m_animation->prepare( m_model ); 62 } 63 64 nv::skeletal_mesh_gpu::skeletal_mesh_gpu( device* a_device, const nmd_temp_model* a_model, uint32 index, bool primary ) 65 : animated_mesh(), m_primary( primary ), m_model( a_model ) 66 { 67 const mesh_data* data = a_model->get_data( index ); 68 m_va = a_device->create_vertex_array( data, nv::STATIC_DRAW ); 69 m_index_count = data->get_count(); 89 90 nv::skeletal_animation_entry_gpu::skeletal_animation_entry_gpu( const std::string& name, const mesh_nodes_data* anim, bool a_looping ) 91 : animation_entry( name ) 92 , m_node_data( anim ) 93 { 94 uint32 node_count = m_node_data->get_count(); 95 96 m_prepared = false; 97 m_looping = a_looping; 98 m_children = nullptr; 99 m_offsets = nullptr; 100 m_bone_ids = new sint16[ node_count ]; 101 102 if ( !m_node_data->is_flat() ) 103 { 104 m_children = new std::vector< uint32 >[ node_count ]; 105 for ( uint32 n = 0; n < node_count; ++n ) 106 { 107 const mesh_node_data* node = m_node_data->get_node(n); 108 if ( node->parent_id != -1 ) 109 { 110 m_children[ node->parent_id ].push_back( n ); 111 } 112 } 113 } 114 } 115 116 void nv::skeletal_animation_entry_gpu::update_skeleton( mat4* data, uint32 time ) const 117 { 118 float tick_time = ( time * 0.001f ) * m_node_data->get_frame_rate(); 119 float anim_time = fmodf( tick_time, m_node_data->get_duration() ); 120 121 if ( !m_node_data->is_flat() ) 122 { 123 animate_rec( data, anim_time, 0, mat4() ); 124 return; 125 } 126 127 for ( uint32 n = 0; n < m_node_data->get_count(); ++n ) 128 if ( m_bone_ids[n] >= 0 ) 129 { 130 const mesh_node_data* node = m_node_data->get_node(n); 131 nv::mat4 node_mat( node->transform ); 132 133 if ( node->data ) 134 { 135 node_mat = node->data->get_matrix( anim_time ); 136 } 137 138 sint16 bone_id = m_bone_ids[n]; 139 data[ bone_id ] = node_mat * m_offsets[ bone_id ]; 140 } 141 } 142 143 void nv::skeletal_animation_entry_gpu::prepare( const mesh_nodes_data* bones ) 144 { 145 if ( m_prepared ) return; 146 std::unordered_map< std::string, nv::uint16 > bone_names; 147 m_offsets = new mat4[ bones->get_count() ]; 148 for ( nv::uint16 bi = 0; bi < bones->get_count(); ++bi ) 149 { 150 const mesh_node_data* bone = bones->get_node(bi); 151 bone_names[ bone->name ] = bi; 152 m_offsets[bi] = bone->transform; 153 } 154 155 for ( uint32 n = 0; n < m_node_data->get_count(); ++n ) 156 { 157 const mesh_node_data* node = m_node_data->get_node(n); 158 sint16 bone_id = -1; 159 160 auto bi = bone_names.find( node->name ); 161 if ( bi != bone_names.end() ) 162 { 163 bone_id = bi->second; 164 } 165 m_bone_ids[n] = bone_id; 166 } 167 m_prepared = true; 168 } 169 170 void nv::skeletal_animation_entry_gpu::animate_rec( mat4* data, float time, uint32 node_id, const mat4& parent_mat ) const 171 { 172 // TODO: fix transforms, which are now embedded, 173 // see note in assimp_loader.cc:load_node 174 const mesh_node_data* node = m_node_data->get_node( node_id ); 175 mat4 node_mat( node->transform ); 176 177 if ( node->data ) 178 { 179 node_mat = node->data->get_matrix( time ); 180 } 181 182 mat4 global_mat = parent_mat * node_mat; 183 184 sint16 bone_id = m_bone_ids[ node_id ]; 185 if ( bone_id >= 0 ) 186 { 187 data[ bone_id ] = global_mat * m_offsets[ bone_id ]; 188 } 189 190 for ( auto child : m_children[ node_id ] ) 191 { 192 animate_rec( data, time, child, global_mat ); 193 } 194 } 195 196 nv::skeletal_animation_entry_gpu::~skeletal_animation_entry_gpu() 197 { 198 delete[] m_offsets; 199 delete[] m_children; 200 delete[] m_bone_ids; 201 } 202 203 nv::skeletal_mesh_gpu::skeletal_mesh_gpu( device* a_device, const mesh_data* a_mesh, const mesh_nodes_data* a_bone_data ) 204 : animated_mesh(), m_bone_data( a_bone_data ), m_transform( nullptr ) 205 { 206 m_va = a_device->create_vertex_array( a_mesh, nv::STATIC_DRAW ); 207 m_index_count = a_mesh->get_count(); 208 if ( m_bone_data ) 209 { 210 m_transform = new mat4[ m_bone_data->get_count() ]; 211 } 70 212 } 71 213 72 214 void nv::skeletal_mesh_gpu::run_animation( animation_entry* a_anim ) 73 215 { 74 if ( m_ primary&& a_anim != nullptr )216 if ( m_bone_data && a_anim != nullptr ) 75 217 { 76 218 skeletal_animation_entry_gpu * anim = (skeletal_animation_entry_gpu*)(a_anim); 77 m_transform.resize( m_model->get_bone_count() ); 78 anim->prepare( m_model ); 219 anim->prepare( m_bone_data ); 79 220 update_animation( a_anim, 0 ); 80 221 } … … 83 224 void nv::skeletal_mesh_gpu::update_animation( animation_entry* a_anim, uint32 a_anim_time ) 84 225 { 85 if ( m_ primary&& a_anim )226 if ( m_bone_data && a_anim ) 86 227 { 87 228 skeletal_animation_entry_gpu * anim = (skeletal_animation_entry_gpu*)a_anim; 88 anim->update_skeleton( m_transform .data(), a_anim_time );229 anim->update_skeleton( m_transform, a_anim_time ); 89 230 } 90 231 } … … 92 233 void nv::skeletal_mesh_gpu::update( program* a_program ) const 93 234 { 94 if (m_primary) 95 a_program->set_uniform_array( "nv_m_bones", m_transform ); 96 } 235 if ( m_bone_data ) 236 a_program->set_uniform_array( "nv_m_bones", m_transform, m_bone_data->get_count() ); 237 } 238 239 nv::transform nv::skeletal_mesh_gpu::get_node_transform( uint32 node_id ) const 240 { 241 return transform( m_transform[ node_id ] ); 242 } 243 244 nv::mat4 nv::skeletal_mesh_gpu::get_node_matrix( uint32 node_id ) const 245 { 246 return m_transform[ node_id ]; 247 }
Note: See TracChangeset
for help on using the changeset viewer.