OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrAAConvexTessellator.h" | 8 #include "GrAAConvexTessellator.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkPath.h" | 10 #include "SkPath.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 fRings[1].rewind(); | 118 fRings[1].rewind(); |
119 #endif | 119 #endif |
120 } | 120 } |
121 | 121 |
122 void GrAAConvexTessellator::computeBisectors() { | 122 void GrAAConvexTessellator::computeBisectors() { |
123 fBisectors.setCount(fNorms.count()); | 123 fBisectors.setCount(fNorms.count()); |
124 | 124 |
125 int prev = fBisectors.count() - 1; | 125 int prev = fBisectors.count() - 1; |
126 for (int cur = 0; cur < fBisectors.count(); prev = cur, ++cur) { | 126 for (int cur = 0; cur < fBisectors.count(); prev = cur, ++cur) { |
127 fBisectors[cur] = fNorms[cur] + fNorms[prev]; | 127 fBisectors[cur] = fNorms[cur] + fNorms[prev]; |
128 fBisectors[cur].normalize(); | 128 if (!fBisectors[cur].normalize()) { |
129 fBisectors[cur].negate(); // make the bisector face in | 129 SkASSERT(SkPoint::kLeft_Side == fSide || SkPoint::kRight_Side == fSi
de); |
| 130 fBisectors[cur].setOrthog(fNorms[cur], (SkPoint::Side)-fSide); |
| 131 SkVector other; |
| 132 other.setOrthog(fNorms[prev], fSide); |
| 133 fBisectors[cur] += other; |
| 134 SkAssertResult(fBisectors[cur].normalize()); |
| 135 } else { |
| 136 fBisectors[cur].negate(); // make the bisector face in |
| 137 } |
130 | 138 |
131 SkASSERT(SkScalarNearlyEqual(1.0f, fBisectors[cur].length())); | 139 SkASSERT(SkScalarNearlyEqual(1.0f, fBisectors[cur].length())); |
132 } | 140 } |
133 } | 141 } |
134 | 142 |
135 // The general idea here is to, conceptually, start with the original polygon an
d slide | 143 // The general idea here is to, conceptually, start with the original polygon an
d slide |
136 // the vertices along the bisectors until the first intersection. At that | 144 // the vertices along the bisectors until the first intersection. At that |
137 // point two of the edges collapse and the process repeats on the new polygon. | 145 // point two of the edges collapse and the process repeats on the new polygon. |
138 // The polygon state is captured in the Ring class while the GrAAConvexTessellat
or | 146 // The polygon state is captured in the Ring class while the GrAAConvexTessellat
or |
139 // controls the iteration. The CandidateVerts holds the formative points for the | 147 // controls the iteration. The CandidateVerts holds the formative points for the |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 | 628 |
621 void GrAAConvexTessellator::validate() const { | 629 void GrAAConvexTessellator::validate() const { |
622 SkASSERT(fPts.count() == fDepths.count()); | 630 SkASSERT(fPts.count() == fDepths.count()); |
623 SkASSERT(fPts.count() == fMovable.count()); | 631 SkASSERT(fPts.count() == fMovable.count()); |
624 SkASSERT(0 == (fIndices.count() % 3)); | 632 SkASSERT(0 == (fIndices.count() % 3)); |
625 } | 633 } |
626 | 634 |
627 ////////////////////////////////////////////////////////////////////////////// | 635 ////////////////////////////////////////////////////////////////////////////// |
628 void GrAAConvexTessellator::Ring::init(const GrAAConvexTessellator& tess) { | 636 void GrAAConvexTessellator::Ring::init(const GrAAConvexTessellator& tess) { |
629 this->computeNormals(tess); | 637 this->computeNormals(tess); |
630 this->computeBisectors(); | 638 this->computeBisectors(tess); |
631 SkASSERT(this->isConvex(tess)); | 639 SkASSERT(this->isConvex(tess)); |
632 } | 640 } |
633 | 641 |
634 void GrAAConvexTessellator::Ring::init(const SkTDArray<SkVector>& norms, | 642 void GrAAConvexTessellator::Ring::init(const SkTDArray<SkVector>& norms, |
635 const SkTDArray<SkVector>& bisectors) { | 643 const SkTDArray<SkVector>& bisectors) { |
636 for (int i = 0; i < fPts.count(); ++i) { | 644 for (int i = 0; i < fPts.count(); ++i) { |
637 fPts[i].fNorm = norms[i]; | 645 fPts[i].fNorm = norms[i]; |
638 fPts[i].fBisector = bisectors[i]; | 646 fPts[i].fBisector = bisectors[i]; |
639 } | 647 } |
640 } | 648 } |
641 | 649 |
642 // Compute the outward facing normal at each vertex. | 650 // Compute the outward facing normal at each vertex. |
643 void GrAAConvexTessellator::Ring::computeNormals(const GrAAConvexTessellator& te
ss) { | 651 void GrAAConvexTessellator::Ring::computeNormals(const GrAAConvexTessellator& te
ss) { |
644 for (int cur = 0; cur < fPts.count(); ++cur) { | 652 for (int cur = 0; cur < fPts.count(); ++cur) { |
645 int next = (cur + 1) % fPts.count(); | 653 int next = (cur + 1) % fPts.count(); |
646 | 654 |
647 fPts[cur].fNorm = tess.point(fPts[next].fIndex) - tess.point(fPts[cur].f
Index); | 655 fPts[cur].fNorm = tess.point(fPts[next].fIndex) - tess.point(fPts[cur].f
Index); |
648 SkDEBUGCODE(SkScalar len =) SkPoint::Normalize(&fPts[cur].fNorm); | 656 SkDEBUGCODE(SkScalar len =) SkPoint::Normalize(&fPts[cur].fNorm); |
649 SkASSERT(len > 0.0f); | 657 SkASSERT(len > 0.0f); |
650 fPts[cur].fNorm.setOrthog(fPts[cur].fNorm, tess.side()); | 658 fPts[cur].fNorm.setOrthog(fPts[cur].fNorm, tess.side()); |
651 | 659 |
652 SkASSERT(SkScalarNearlyEqual(1.0f, fPts[cur].fNorm.length())); | 660 SkASSERT(SkScalarNearlyEqual(1.0f, fPts[cur].fNorm.length())); |
653 } | 661 } |
654 } | 662 } |
655 | 663 |
656 void GrAAConvexTessellator::Ring::computeBisectors() { | 664 void GrAAConvexTessellator::Ring::computeBisectors(const GrAAConvexTessellator&
tess) { |
657 int prev = fPts.count() - 1; | 665 int prev = fPts.count() - 1; |
658 for (int cur = 0; cur < fPts.count(); prev = cur, ++cur) { | 666 for (int cur = 0; cur < fPts.count(); prev = cur, ++cur) { |
659 fPts[cur].fBisector = fPts[cur].fNorm + fPts[prev].fNorm; | 667 fPts[cur].fBisector = fPts[cur].fNorm + fPts[prev].fNorm; |
660 fPts[cur].fBisector.normalize(); | 668 if (!fPts[cur].fBisector.normalize()) { |
661 fPts[cur].fBisector.negate(); // make the bisector face in | 669 SkASSERT(SkPoint::kLeft_Side == tess.side() || SkPoint::kRight_Side
== tess.side()); |
| 670 fPts[cur].fBisector.setOrthog(fPts[cur].fNorm, (SkPoint::Side)-tess.
side()); |
| 671 SkVector other; |
| 672 other.setOrthog(fPts[prev].fNorm, tess.side()); |
| 673 fPts[cur].fBisector += other; |
| 674 SkAssertResult(fPts[cur].fBisector.normalize()); |
| 675 } else { |
| 676 fPts[cur].fBisector.negate(); // make the bisector face in |
| 677 } |
662 | 678 |
663 SkASSERT(SkScalarNearlyEqual(1.0f, fPts[cur].fBisector.length())); | 679 SkASSERT(SkScalarNearlyEqual(1.0f, fPts[cur].fBisector.length())); |
664 } | 680 } |
665 } | 681 } |
666 | 682 |
667 ////////////////////////////////////////////////////////////////////////////// | 683 ////////////////////////////////////////////////////////////////////////////// |
668 #ifdef SK_DEBUG | 684 #ifdef SK_DEBUG |
669 // Is this ring convex? | 685 // Is this ring convex? |
670 bool GrAAConvexTessellator::Ring::isConvex(const GrAAConvexTessellator& tess) co
nst { | 686 bool GrAAConvexTessellator::Ring::isConvex(const GrAAConvexTessellator& tess) co
nst { |
671 if (fPts.count() < 3) { | 687 if (fPts.count() < 3) { |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 SkString num; | 881 SkString num; |
866 num.printf("%d", i); | 882 num.printf("%d", i); |
867 canvas->drawText(num.c_str(), num.size(), | 883 canvas->drawText(num.c_str(), num.size(), |
868 this->point(i).fX, this->point(i).fY+(kPointRadius/2.0f
), | 884 this->point(i).fX, this->point(i).fY+(kPointRadius/2.0f
), |
869 paint); | 885 paint); |
870 } | 886 } |
871 } | 887 } |
872 | 888 |
873 #endif | 889 #endif |
874 | 890 |
OLD | NEW |