Changeset 456 for trunk/src/gfx/mesh_creator.cc
- Timestamp:
- 08/11/15 20:35:01 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gfx/mesh_creator.cc
r454 r456 113 113 } 114 114 } 115 } 116 117 nv::mesh_data_creator::mesh_data_creator( data_channel_set* data ) : m_data( data ) 118 { 119 initialize(); 115 120 } 116 121 … … 168 173 void nv::mesh_data_creator::flip_normals() 169 174 { 170 int ch_n = m_data->get_channel_index( slot::NORMAL ); 171 size_t n_offset = 0; 172 if ( ch_n == -1 ) return; 173 raw_data_channel_access channel( m_data, unsigned( ch_n ) ); 174 for ( const auto& cslot : channel.descriptor() ) 175 if ( cslot.vslot == slot::NORMAL ) 176 { 177 n_offset = cslot.offset; 178 } 179 175 if ( m_nrm_channel == nullptr ) return; 176 NV_ASSERT( m_nrm_type == FLOAT_VECTOR_3, "Unknown normal vector type!" ); 177 raw_data_channel_access channel( m_nrm_channel ); 180 178 for ( uint32 i = 0; i < channel.size(); ++i ) 181 179 { 182 vec3& normal = *reinterpret_cast<vec3*>( channel.raw_data() + channel.element_size() * i + n_offset );180 vec3& normal = *reinterpret_cast<vec3*>( channel.raw_data() + channel.element_size() * i + m_nrm_offset ); 183 181 normal = -normal; 184 182 } … … 186 184 187 185 186 void nv::mesh_data_creator::scale_texture( vec2 min, vec2 max ) 187 { 188 if ( m_tex_channel == nullptr ) return; 189 NV_ASSERT( m_tex_type == FLOAT_VECTOR_2, "Unknown texcoord vector type!" ); 190 raw_data_channel_access channel( m_tex_channel ); 191 vec2 scale = max - min; 192 for ( uint32 i = 0; i < channel.size(); ++i ) 193 { 194 vec2& tc = *reinterpret_cast<vec2*>( channel.raw_data() + channel.element_size() * i + m_tex_offset ); 195 tc = min + tc * scale; 196 } 197 } 198 188 199 void nv::mesh_data_creator::generate_tangents() 189 200 { 190 int p_offset = -1; 191 int n_offset = -1; 192 int t_offset = -1; 193 datatype i_type = NONE; 194 uint32 n_channel_index = 0; 195 196 const raw_data_channel* p_channel = nullptr; 197 raw_data_channel* n_channel = nullptr; 198 const raw_data_channel* t_channel = nullptr; 199 const raw_data_channel* i_channel = nullptr; 200 201 for ( uint32 c = 0; c < m_data->size(); ++c ) 202 { 203 const raw_data_channel* channel = m_data->get_channel(c); 204 205 for ( const auto& cslot : channel->descriptor() ) 206 switch ( cslot.vslot ) 207 { 208 case slot::POSITION : 209 if ( cslot.etype == FLOAT_VECTOR_3 ) 210 { 211 p_offset = int( cslot.offset ); 212 p_channel = channel; 213 } 214 break; 215 case slot::NORMAL : 216 if ( cslot.etype == FLOAT_VECTOR_3 ) 217 { 218 n_offset = int( cslot.offset ); 219 n_channel = data_channel_set_creator( m_data )[ c ]; 220 n_channel_index = c; 221 } 222 break; 223 case slot::TEXCOORD : 224 if ( cslot.etype == FLOAT_VECTOR_2 ) 225 { 226 t_offset = int( cslot.offset ); 227 t_channel = channel; 228 } 229 break; 230 case slot::INDEX : 231 { 232 i_type = cslot.etype; 233 i_channel = channel; 234 } 235 break; 236 case slot::TANGENT : return; 237 default : break; 238 } 239 } 240 if ( !p_channel || !n_channel || !t_channel ) return; 241 242 if ( p_channel->size() != n_channel->size() 243 || p_channel->size() % t_channel->size() != 0 244 || ( i_type != UINT && i_type != USHORT && i_type != NONE ) ) 201 if ( m_tan_channel != nullptr ) return; 202 if ( !m_pos_channel || !m_nrm_channel || !m_tex_channel ) return; 203 204 if ( m_pos_channel->size() != m_nrm_channel->size() 205 || m_pos_channel->size() % m_tex_channel->size() != 0 206 || ( m_idx_type != UINT && m_idx_type != USHORT && m_idx_type != NONE ) ) 245 207 { 246 208 return; 247 209 } 248 210 249 raw_data_channel g_channel = data_channel_creator::create< vertex_g >( p_channel->size() ); 211 NV_ASSERT( m_pos_type == FLOAT_VECTOR_3, "Unsupported position vector type!" ); 212 NV_ASSERT( m_nrm_type == FLOAT_VECTOR_3, "Unsupported normal vector type!" ); 213 NV_ASSERT( m_tex_type == FLOAT_VECTOR_2, "Unknown texcoord vector type!" ); 214 215 raw_data_channel g_channel = data_channel_creator::create< vertex_g >( m_pos_channel->size() ); 250 216 vec4* tangents = &( data_channel_access< vertex_g >( &g_channel ).data()[0].tangent ); 251 vec3* tangents2 = new vec3[ p_channel->size() ];252 uint32 tri_count = i_channel ? i_channel->size() / 3 : t_channel->size() / 3;253 uint32 vtx_count = p_channel->size();254 uint32 sets = p_channel->size() / t_channel->size();217 vec3* tangents2 = new vec3[ m_pos_channel->size() ]; 218 uint32 tri_count = m_idx_channel ? m_idx_channel->size() / 3 : m_tex_channel->size() / 3; 219 uint32 vtx_count = m_pos_channel->size(); 220 uint32 sets = m_pos_channel->size() / m_tex_channel->size(); 255 221 256 222 for ( unsigned int i = 0; i < tri_count; ++i ) … … 259 225 uint32 ti1 = 0; 260 226 uint32 ti2 = 0; 261 if ( i_type == UINT )262 { 263 const uint32* idata = reinterpret_cast<const uint32*>( i_channel->raw_data() );227 if ( m_idx_type == UINT ) 228 { 229 const uint32* idata = reinterpret_cast<const uint32*>( m_idx_channel->raw_data() ); 264 230 ti0 = idata[ i * 3 ]; 265 231 ti1 = idata[ i * 3 + 1 ]; 266 232 ti2 = idata[ i * 3 + 2 ]; 267 233 } 268 else if ( i_type == USHORT )269 { 270 const uint16* idata = reinterpret_cast<const uint16*>( i_channel->raw_data() );234 else if ( m_idx_type == USHORT ) 235 { 236 const uint16* idata = reinterpret_cast<const uint16*>( m_idx_channel->raw_data() ); 271 237 ti0 = idata[ i * 3 ]; 272 238 ti1 = idata[ i * 3 + 1 ]; 273 239 ti2 = idata[ i * 3 + 2 ]; 274 240 } 275 else // if ( i_type == NONE )241 else // if ( m_idx_type == NONE ) 276 242 { 277 243 ti0 = i * 3; … … 280 246 } 281 247 282 const vec2& w1 = *reinterpret_cast<const vec2*>( t_channel->raw_data() + t_channel->element_size()*ti0 + t_offset );283 const vec2& w2 = *reinterpret_cast<const vec2*>( t_channel->raw_data() + t_channel->element_size()*ti1 + t_offset );284 const vec2& w3 = *reinterpret_cast<const vec2*>( t_channel->raw_data() + t_channel->element_size()*ti2 + t_offset );248 const vec2& w1 = *reinterpret_cast<const vec2*>( m_tex_channel->raw_data() + m_tex_channel->element_size()*ti0 + m_tex_offset ); 249 const vec2& w2 = *reinterpret_cast<const vec2*>( m_tex_channel->raw_data() + m_tex_channel->element_size()*ti1 + m_tex_offset ); 250 const vec2& w3 = *reinterpret_cast<const vec2*>( m_tex_channel->raw_data() + m_tex_channel->element_size()*ti2 + m_tex_offset ); 285 251 vec2 st1 = w3 - w1; 286 252 vec2 st2 = w2 - w1; … … 290 256 for ( uint32 set = 0; set < sets; ++set ) 291 257 { 292 uint32 nti0 = t_channel->size() * set + ti0;293 uint32 nti1 = t_channel->size() * set + ti1;294 uint32 nti2 = t_channel->size() * set + ti2;295 const vec3& v1 = *reinterpret_cast<const vec3*>( p_channel->raw_data() + p_channel->element_size()*nti0 + p_offset );296 const vec3& v2 = *reinterpret_cast<const vec3*>( p_channel->raw_data() + p_channel->element_size()*nti1 + p_offset );297 const vec3& v3 = *reinterpret_cast<const vec3*>( p_channel->raw_data() + p_channel->element_size()*nti2 + p_offset );258 uint32 nti0 = m_tex_channel->size() * set + ti0; 259 uint32 nti1 = m_tex_channel->size() * set + ti1; 260 uint32 nti2 = m_tex_channel->size() * set + ti2; 261 const vec3& v1 = *reinterpret_cast<const vec3*>( m_pos_channel->raw_data() + m_pos_channel->element_size()*nti0 + m_pos_offset ); 262 const vec3& v2 = *reinterpret_cast<const vec3*>( m_pos_channel->raw_data() + m_pos_channel->element_size()*nti1 + m_pos_offset ); 263 const vec3& v3 = *reinterpret_cast<const vec3*>( m_pos_channel->raw_data() + m_pos_channel->element_size()*nti2 + m_pos_offset ); 298 264 vec3 xyz1 = v3 - v1; 299 265 vec3 xyz2 = v2 - v1; … … 319 285 for ( unsigned int i = 0; i < vtx_count; ++i ) 320 286 { 321 const vec3 n = *reinterpret_cast<const vec3*>( n_channel->raw_data() + n_channel->element_size()*i + n_offset );287 const vec3 n = *reinterpret_cast<const vec3*>( m_nrm_channel->raw_data() + m_nrm_channel->element_size()*i + m_nrm_offset ); 322 288 const vec3 t = vec3(tangents[i]); 323 289 if ( ! ( t.x == 0.0f && t.y == 0.0f && t.z == 0.0f ) ) … … 329 295 delete[] tangents2; 330 296 331 data_channel_set_creator( m_data ).set_channel( n_channel_index, merge_channels( *n_channel, g_channel ) ); 297 uint32 n_channel_index = m_data->get_channel_index( slot::NORMAL ); 298 data_channel_set_creator( m_data ).set_channel( n_channel_index, merge_channels( *m_nrm_channel, g_channel ) ); 299 initialize(); 300 } 301 302 void nv::mesh_data_creator::rotate_quadrant( uint8 rotation ) 303 { 304 if ( rotation % 4 == 0 ) return; 305 NV_ASSERT( m_pos_type == FLOAT_VECTOR_3, "Unsupported position vector type!" ); 306 NV_ASSERT( m_nrm_type == FLOAT_VECTOR_3, "Unsupported normal vector type!" ); 307 NV_ASSERT( m_tan_type == FLOAT_VECTOR_4, "Unsupported tangent vector type!" ); 308 309 float r11 = 0.f; 310 float r12 = 0.f; 311 float r21 = 0.f; 312 float r22 = 0.f; 313 314 switch ( rotation % 4 ) 315 { 316 case 1: r12 = -1.f; r21 = 1.f; break; 317 case 2: r11 = -1.f; r22 = -1.f; break; 318 case 3: r12 = 1.f; r21 = -1.f; break; 319 default: 320 break; 321 } 322 323 unsigned vtx_count = m_pos_channel->size(); 324 uint8* pos_data = raw_data_channel_access( m_pos_channel ).raw_data(); 325 uint8* nrm_data = raw_data_channel_access( m_nrm_channel ).raw_data(); 326 uint8* tan_data = raw_data_channel_access( m_tan_channel ).raw_data(); 327 for ( unsigned int i = 0; i < vtx_count; ++i ) 328 { 329 vec3& pos = *reinterpret_cast<vec3*>( pos_data + m_pos_channel->element_size() * i + m_pos_offset ); 330 vec3& nrm = *reinterpret_cast<vec3*>( nrm_data + m_nrm_channel->element_size() * i + m_nrm_offset ); 331 vec4& tan = *reinterpret_cast<vec4*>( tan_data + m_tan_channel->element_size() * i + m_tan_offset ); 332 333 pos = vec3( 334 pos.x * r11 + pos.z * r12, 335 pos.y, 336 pos.x * r21 + pos.z * r22 337 ); 338 nrm = vec3( 339 nrm.x * r11 + nrm.z * r12, 340 nrm.y, 341 nrm.x * r21 + nrm.z * r22 342 ); 343 tan = vec4( 344 tan.x * r11 + tan.z * r12, 345 tan.y, 346 tan.x * r21 + tan.z * r22, 347 1.0f // make sure this is proper 348 ); 349 } 350 351 352 } 353 354 void nv::mesh_data_creator::translate( vec3 offset ) 355 { 356 if ( m_pos_channel == nullptr ) return; 357 NV_ASSERT( m_pos_type == FLOAT_VECTOR_3, "Unsupported poosition vector type!" ); 358 raw_data_channel_access channel( m_pos_channel ); 359 for ( uint32 i = 0; i < channel.size(); ++i ) 360 { 361 vec3& p = *reinterpret_cast<vec3*>( channel.raw_data() + channel.element_size() * i + m_pos_offset ); 362 p = p + offset; 363 } 364 365 } 366 367 void nv::mesh_data_creator::initialize() 368 { 369 NV_ASSERT( m_data, "bad parameter!" ); 370 m_pos_channel = nullptr; 371 m_nrm_channel = nullptr; 372 m_tan_channel = nullptr; 373 m_tex_channel = nullptr; 374 m_idx_channel = nullptr; 375 376 m_pos_offset = -1; 377 m_nrm_offset = -1; 378 m_tan_offset = -1; 379 m_tex_offset = -1; 380 m_idx_offset = -1; 381 382 m_pos_type = NONE; 383 m_nrm_type = NONE; 384 m_tan_type = NONE; 385 m_tex_type = NONE; 386 m_idx_type = NONE; 387 388 for ( uint32 c = 0; c < m_data->size(); ++c ) 389 { 390 raw_data_channel* channel = data_channel_set_creator( m_data )[c]; 391 392 for ( const auto& cslot : channel->descriptor() ) 393 switch ( cslot.vslot ) 394 { 395 case slot::POSITION: 396 m_pos_type = cslot.etype; 397 m_pos_offset = int( cslot.offset ); 398 m_pos_channel = channel; 399 break; 400 case slot::NORMAL: 401 m_nrm_type = cslot.etype; 402 m_nrm_offset = int( cslot.offset ); 403 m_nrm_channel = channel; 404 break; 405 case slot::TANGENT: 406 m_tan_type = cslot.etype; 407 m_tan_offset = int( cslot.offset ); 408 m_tan_channel = channel; 409 break; 410 case slot::TEXCOORD: 411 m_tex_type = cslot.etype; 412 m_tex_offset = int( cslot.offset ); 413 m_tex_channel = channel; 414 break; 415 case slot::INDEX: 416 m_idx_type = cslot.etype; 417 m_idx_offset = int( cslot.offset ); 418 m_idx_channel = channel; 419 break; 420 default: break; 421 } 422 } 332 423 } 333 424 … … 344 435 raw_copy_n( b.raw_data() + i * b.element_size(), b.element_size(), raw_data_channel_access( &result ).raw_data() + i*desc.element_size() + a.element_size() ); 345 436 } 346 437 initialize(); 347 438 return result; 348 439 } … … 380 471 } 381 472 473 initialize(); 382 474 return result; 383 475 } … … 447 539 } 448 540 } 541 initialize(); 449 542 } 450 543
Note: See TracChangeset
for help on using the changeset viewer.