| 557 | #endif |
| 558 | |
| 559 | bool MeshData::GenerateTangents(float smoothingAngle) |
| 560 | { |
| 561 | if (Positions.IsEmpty() || Indices.IsEmpty()) |
| 562 | { |
| 563 | LOG(Warning, "Missing vertex or index data to generate tangents."); |
| 564 | return true; |
| 565 | } |
| 566 | if (Normals.IsEmpty() || UVs.IsEmpty()) |
| 567 | { |
| 568 | LOG(Warning, "Missing normals or texcoords data to generate tangents."); |
| 569 | return true; |
| 570 | } |
| 571 | PROFILE_CPU(); |
| 572 | |
| 573 | const auto startTime = Platform::GetTimeSeconds(); |
| 574 | const int32 vertexCount = Positions.Count(); |
| 575 | const int32 indexCount = Indices.Count(); |
| 576 | Tangents.Resize(vertexCount, false); |
| 577 | smoothingAngle = Math::Clamp(smoothingAngle, 0.0f, 45.0f); |
| 578 | |
| 579 | #if USE_MIKKTSPACE |
| 580 | SMikkTSpaceInterface callbacks = { |
| 581 | GetNumFaces, |
| 582 | GetNumVerticesOfFace, |
| 583 | GetPosition, |
| 584 | GetNormal, |
| 585 | GetTexCoord, |
| 586 | SetTSpaceBasic, |
| 587 | nullptr |
| 588 | }; |
| 589 | const SMikkTSpaceContext context = { &callbacks, this }; |
| 590 | BitangentSigns.Resize(vertexCount, false); |
| 591 | genTangSpace(&context, 180.0f - smoothingAngle); |
| 592 | #else |
| 593 | const float angleEpsilon = 0.9999f; |
| 594 | BitArray<> vertexDone; |
| 595 | vertexDone.Resize(vertexCount); |
| 596 | vertexDone.SetAll(false); |
| 597 | |
| 598 | const Float3* meshNorm = Normals.Get(); |
| 599 | const Float2* meshTex = UVs[0].Get(); |
| 600 | Float3* meshTang = Tangents.Get(); |
| 601 | |
| 602 | // Calculate the tangent per-triangle |
| 603 | Float3 min, max; |
| 604 | min = max = Positions[Indices[0]]; |
| 605 | for (int32 i = 0; i < indexCount; i += 3) |
| 606 | { |
| 607 | const int32 p0 = Indices[i + 0], p1 = Indices[i + 1], p2 = Indices[i + 2]; |
| 608 | |
| 609 | const Float3 v0 = Positions[p0]; |
| 610 | const Float3 v1 = Positions[p1]; |
| 611 | const Float3 v2 = Positions[p2]; |
| 612 | |
| 613 | Float3::Min(min, v0, min); |
| 614 | Float3::Min(min, v1, min); |
| 615 | Float3::Min(min, v2, min); |
| 616 |
no test coverage detected