| 540 | } |
| 541 | |
| 542 | int Triangulate(OpenFbxImporterData& data, const ofbx::GeometryData& geom, const ofbx::GeometryPartition::Polygon& polygon, int* triangulatedIndices) |
| 543 | { |
| 544 | if (polygon.vertex_count < 3) |
| 545 | return 0; |
| 546 | else if (polygon.vertex_count == 3) |
| 547 | { |
| 548 | triangulatedIndices[0] = polygon.from_vertex; |
| 549 | triangulatedIndices[1] = polygon.from_vertex + 1; |
| 550 | triangulatedIndices[2] = polygon.from_vertex + 2; |
| 551 | return 3; |
| 552 | } |
| 553 | else if (polygon.vertex_count == 4) |
| 554 | { |
| 555 | triangulatedIndices[0] = polygon.from_vertex + 0; |
| 556 | triangulatedIndices[1] = polygon.from_vertex + 1; |
| 557 | triangulatedIndices[2] = polygon.from_vertex + 2; |
| 558 | triangulatedIndices[3] = polygon.from_vertex + 0; |
| 559 | triangulatedIndices[4] = polygon.from_vertex + 2; |
| 560 | triangulatedIndices[5] = polygon.from_vertex + 3; |
| 561 | return 6; |
| 562 | } |
| 563 | |
| 564 | const ofbx::Vec3Attributes& positions = geom.getPositions(); |
| 565 | Float3 normal = ToFloat3(geom.getNormals().get(polygon.from_vertex)); |
| 566 | |
| 567 | // Check if the polygon is convex |
| 568 | int lastSign = 0; |
| 569 | bool isConvex = true; |
| 570 | for (int i = 0; i < polygon.vertex_count; i++) |
| 571 | { |
| 572 | Float3 v1 = ToFloat3(positions.get(polygon.from_vertex + i)); |
| 573 | Float3 v2 = ToFloat3(positions.get(polygon.from_vertex + (i + 1) % polygon.vertex_count)); |
| 574 | Float3 v3 = ToFloat3(positions.get(polygon.from_vertex + (i + 2) % polygon.vertex_count)); |
| 575 | |
| 576 | // The winding order of all triangles must be same for polygon to be considered convex |
| 577 | int sign; |
| 578 | Float3 c = Float3::Cross(v1 - v2, v3 - v2); |
| 579 | if (c.LengthSquared() == 0.0f) |
| 580 | continue; |
| 581 | else if (Math::NotSameSign(c.X, normal.X) || Math::NotSameSign(c.Y, normal.Y) || Math::NotSameSign(c.Z, normal.Z)) |
| 582 | sign = 1; |
| 583 | else |
| 584 | sign = -1; |
| 585 | if ((sign < 0 && lastSign > 0) || (sign > 0 && lastSign < 0)) |
| 586 | { |
| 587 | isConvex = false; |
| 588 | break; |
| 589 | } |
| 590 | lastSign += sign; |
| 591 | } |
| 592 | |
| 593 | // Fast-path for convex case |
| 594 | if (isConvex) |
| 595 | { |
| 596 | for (int i = 0; i < polygon.vertex_count - 2; i++) |
| 597 | { |
| 598 | triangulatedIndices[i * 3 + 0] = polygon.from_vertex; |
| 599 | triangulatedIndices[i * 3 + 1] = polygon.from_vertex + (i + 1) % polygon.vertex_count; |
no test coverage detected