Changeset 294 for trunk/src/gfx/mesh_creator.cc
- Timestamp:
- 07/28/14 03:05:19 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gfx/mesh_creator.cc
r293 r294 162 162 } 163 163 } 164 165 struct vertex_g 166 { 167 nv::vec4 tangent; 168 }; 169 170 void 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 314 nv::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.