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 #ifndef GrAAConvexTessellator_DEFINED | 8 #ifndef GrAAFlatteningConvexTessellator_DEFINED |
9 #define GrAAConvexTessellator_DEFINED | 9 #define GrAAFlatteningConvexTessellator_DEFINED |
10 | 10 |
11 #include "SkColor.h" | 11 #include "SkColor.h" |
12 #include "SkPoint.h" | 12 #include "SkPoint.h" |
13 #include "SkScalar.h" | 13 #include "SkScalar.h" |
14 #include "SkTDArray.h" | 14 #include "SkTDArray.h" |
15 | 15 |
16 class SkCanvas; | 16 class SkCanvas; |
17 class SkMatrix; | 17 class SkMatrix; |
18 class SkPath; | 18 class SkPath; |
19 | 19 |
20 //#define GR_AA_CONVEX_TESSELLATOR_VIZ 1 | 20 //#define GR_AA_FLATTENING_CONVEX_TESSELLATOR_VIZ 1 |
21 | 21 |
22 class GrAAConvexTessellator; | 22 class GrAAFlatteningConvexTessellator; |
23 | 23 |
robertphillips
2015/05/27 18:10:54
Does this class really diverge enough that we need
| |
24 // The AAConvexTessellator holds the global pool of points and the triangulation | 24 // The AAConvexTessellator holds the global pool of points and the triangulation |
25 // that connects them. It also drives the tessellation process. | 25 // that connects them. It also drives the tessellation process. |
26 // The outward facing normals of the original polygon are stored (in 'fNorms') t o service | 26 // The outward facing normals of the original polygon are stored (in 'fNorms') t o service |
27 // computeDepthFromEdge requests. | 27 // computeDepthFromEdge requests. |
28 class GrAAConvexTessellator { | 28 class GrAAFlatteningConvexTessellator { |
29 public: | 29 public: |
30 GrAAConvexTessellator(SkScalar targetDepth = 0.5f) | 30 GrAAFlatteningConvexTessellator(SkScalar targetDepth = 0.5f) |
31 : fSide(SkPoint::kOn_Side) | 31 : fSide(SkPoint::kOn_Side) |
32 , fTargetDepth(targetDepth) { | 32 , fTargetDepth(targetDepth) { |
33 } | 33 } |
34 | 34 |
35 void setTargetDepth(SkScalar targetDepth) { fTargetDepth = targetDepth; } | 35 void setTargetDepth(SkScalar targetDepth) { fTargetDepth = targetDepth; } |
36 SkScalar targetDepth() const { return fTargetDepth; } | 36 SkScalar targetDepth() const { return fTargetDepth; } |
37 | 37 |
38 SkPoint::Side side() const { return fSide; } | 38 SkPoint::Side side() const { return fSide; } |
39 | 39 |
40 bool tessellate(const SkMatrix& m, const SkPath& path); | 40 bool tessellate(const SkMatrix& m, const SkPath& path); |
41 | 41 |
42 // The next five should only be called after tessellate to extract the resul t | 42 // The next five should only be called after tessellate to extract the resul t |
43 int numPts() const { return fPts.count(); } | 43 int numPts() const { return fPts.count(); } |
44 int numIndices() const { return fIndices.count(); } | 44 int numIndices() const { return fIndices.count(); } |
45 | 45 |
46 const SkPoint& lastPoint() const { return fPts.top(); } | 46 const SkPoint& lastPoint() const { return fPts.top(); } |
47 const SkPoint& point(int index) const { return fPts[index]; } | 47 const SkPoint& point(int index) const { return fPts[index]; } |
48 int index(int index) const { return fIndices[index]; } | 48 int index(int index) const { return fIndices[index]; } |
49 SkScalar depth(int index) const {return fDepths[index]; } | 49 SkScalar depth(int index) const {return fDepths[index]; } |
50 | 50 |
51 #if GR_AA_CONVEX_TESSELLATOR_VIZ | 51 #if GR_AA_FLATTENING_CONVEX_TESSELLATOR_VIZ |
52 void draw(SkCanvas* canvas) const; | 52 void draw(SkCanvas* canvas) const; |
53 #endif | 53 #endif |
54 | 54 |
55 // The tessellator can be reused for multiple paths by rewinding in between | 55 // The tessellator can be reused for multiple paths by rewinding in between |
56 void rewind(); | 56 void rewind(); |
57 | 57 |
58 private: | 58 private: |
59 // CandidateVerts holds the vertices for the next ring while they are | 59 // CandidateVerts holds the vertices for the next ring while they are |
60 // being generated. Its main function is to de-dup the points. | 60 // being generated. Its main function is to de-dup the points. |
61 class CandidateVerts { | 61 class CandidateVerts { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 | 125 |
126 int numPts() const { return fPts.count(); } | 126 int numPts() const { return fPts.count(); } |
127 | 127 |
128 void addIdx(int index, int origEdgeId) { | 128 void addIdx(int index, int origEdgeId) { |
129 struct PointData* pt = fPts.push(); | 129 struct PointData* pt = fPts.push(); |
130 pt->fIndex = index; | 130 pt->fIndex = index; |
131 pt->fOrigEdgeId = origEdgeId; | 131 pt->fOrigEdgeId = origEdgeId; |
132 } | 132 } |
133 | 133 |
134 // init should be called after all the indices have been added (via addI dx) | 134 // init should be called after all the indices have been added (via addI dx) |
135 void init(const GrAAConvexTessellator& tess); | 135 void init(const GrAAFlatteningConvexTessellator& tess); |
136 void init(const SkTDArray<SkVector>& norms, const SkTDArray<SkVector>& b isectors); | 136 void init(const SkTDArray<SkVector>& norms, const SkTDArray<SkVector>& b isectors); |
137 | 137 |
138 const SkPoint& norm(int index) const { return fPts[index].fNorm; } | 138 const SkPoint& norm(int index) const { return fPts[index].fNorm; } |
139 const SkPoint& bisector(int index) const { return fPts[index].fBisector; } | 139 const SkPoint& bisector(int index) const { return fPts[index].fBisector; } |
140 int index(int index) const { return fPts[index].fIndex; } | 140 int index(int index) const { return fPts[index].fIndex; } |
141 int origEdgeID(int index) const { return fPts[index].fOrigEdgeId; } | 141 int origEdgeID(int index) const { return fPts[index].fOrigEdgeId; } |
142 | 142 |
143 #if GR_AA_CONVEX_TESSELLATOR_VIZ | 143 #if GR_AA_FLATTENING_CONVEX_TESSELLATOR_VIZ |
144 void draw(SkCanvas* canvas, const GrAAConvexTessellator& tess) const; | 144 void draw(SkCanvas* canvas, const GrAAFlatteningConvexTessellator& tess) const; |
145 #endif | 145 #endif |
146 | 146 |
147 private: | 147 private: |
148 void computeNormals(const GrAAConvexTessellator& result); | 148 void computeNormals(const GrAAFlatteningConvexTessellator& result); |
149 void computeBisectors(const GrAAConvexTessellator& tess); | 149 void computeBisectors(const GrAAFlatteningConvexTessellator& tess); |
150 | 150 |
151 SkDEBUGCODE(bool isConvex(const GrAAConvexTessellator& tess) const;) | 151 SkDEBUGCODE(bool isConvex(const GrAAFlatteningConvexTessellator& tess) c onst;) |
152 | 152 |
153 struct PointData { | 153 struct PointData { |
154 SkPoint fNorm; | 154 SkPoint fNorm; |
155 SkPoint fBisector; | 155 SkPoint fBisector; |
156 int fIndex; | 156 int fIndex; |
157 int fOrigEdgeId; | 157 int fOrigEdgeId; |
158 }; | 158 }; |
159 | 159 |
160 SkTDArray<PointData> fPts; | 160 SkTDArray<PointData> fPts; |
161 }; | 161 }; |
162 | 162 |
163 bool movable(int index) const { return fMovable[index]; } | 163 bool movable(int index) const { return fMovable[index]; } |
164 | 164 |
165 // Movable points are those that can be slid along their bisector. | 165 // Movable points are those that can be slid along their bisector. |
166 // Basically, a point is immovable if it is part of the original | 166 // Basically, a point is immovable if it is part of the original |
167 // polygon or it results from the fusing of two bisectors. | 167 // polygon or it results from the fusing of two bisectors. |
168 int addPt(const SkPoint& pt, SkScalar depth, bool movable); | 168 int addPt(const SkPoint& pt, SkScalar depth, bool movable, bool isCurve); |
169 void popLastPt(); | 169 void popLastPt(); |
170 void popFirstPtShuffle(); | 170 void popFirstPtShuffle(); |
171 | 171 |
172 void updatePt(int index, const SkPoint& pt, SkScalar depth); | 172 void updatePt(int index, const SkPoint& pt, SkScalar depth); |
173 | 173 |
174 void addTri(int i0, int i1, int i2); | 174 void addTri(int i0, int i1, int i2); |
175 | 175 |
176 void reservePts(int count) { | 176 void reservePts(int count) { |
177 fPts.setReserve(count); | 177 fPts.setReserve(count); |
178 fDepths.setReserve(count); | 178 fDepths.setReserve(count); |
179 fMovable.setReserve(count); | 179 fMovable.setReserve(count); |
180 } | 180 } |
181 | 181 |
182 SkScalar computeDepthFromEdge(int edgeIdx, const SkPoint& p) const; | 182 SkScalar computeDepthFromEdge(int edgeIdx, const SkPoint& p) const; |
183 | 183 |
184 bool computePtAlongBisector(int startIdx, const SkPoint& bisector, | 184 bool computePtAlongBisector(int startIdx, const SkPoint& bisector, |
185 int edgeIdx, SkScalar desiredDepth, | 185 int edgeIdx, SkScalar desiredDepth, |
186 SkPoint* result) const; | 186 SkPoint* result) const; |
187 | 187 |
188 void lineTo(const SkMatrix& m, SkPoint p, bool isCurve); | |
189 | |
190 void quadTo(const SkMatrix& m, SkPoint* pts); | |
bsalomon
2015/05/27 17:11:07
just as documentation, it'd be nice to have pts[2]
ethannicholas
2015/05/27 19:22:30
Done.
| |
191 | |
192 void cubicTo(const SkMatrix& m, SkPoint* pts); | |
193 | |
194 void conicTo(const SkMatrix& m, SkPoint* pts, SkScalar w); | |
195 | |
188 void terminate(const Ring& lastRing); | 196 void terminate(const Ring& lastRing); |
189 | 197 |
190 // return false on failure/degenerate path | 198 // return false on failure/degenerate path |
191 bool extractFromPath(const SkMatrix& m, const SkPath& path); | 199 bool extractFromPath(const SkMatrix& m, const SkPath& path); |
192 void computeBisectors(); | 200 void computeBisectors(); |
193 | 201 |
194 void fanRing(const Ring& ring); | 202 void fanRing(const Ring& ring); |
195 void createOuterRing(); | 203 void createOuterRing(); |
196 | 204 |
197 Ring* getNextRing(Ring* lastRing); | 205 Ring* getNextRing(Ring* lastRing); |
(...skipping 12 matching lines...) Expand all Loading... | |
210 SkTDArray<SkPoint> fPts; | 218 SkTDArray<SkPoint> fPts; |
211 SkTDArray<SkScalar> fDepths; | 219 SkTDArray<SkScalar> fDepths; |
212 // movable points are those that can be slid further along their bisector | 220 // movable points are those that can be slid further along their bisector |
213 SkTDArray<bool> fMovable; | 221 SkTDArray<bool> fMovable; |
214 | 222 |
215 // The outward facing normals for the original polygon | 223 // The outward facing normals for the original polygon |
216 SkTDArray<SkVector> fNorms; | 224 SkTDArray<SkVector> fNorms; |
217 // The inward facing bisector at each point in the original polygon. Only | 225 // The inward facing bisector at each point in the original polygon. Only |
218 // needed for exterior ring creation and then handed off to the initial ring . | 226 // needed for exterior ring creation and then handed off to the initial ring . |
219 SkTDArray<SkVector> fBisectors; | 227 SkTDArray<SkVector> fBisectors; |
228 | |
229 // Tracks whether a given point is interior to a curve. Such points are | |
230 // assumed to have shallow curvature. | |
231 SkTDArray<bool> fIsCurve; | |
232 | |
220 SkPoint::Side fSide; // winding of the original polygon | 233 SkPoint::Side fSide; // winding of the original polygon |
221 | 234 |
222 // The triangulation of the points | 235 // The triangulation of the points |
223 SkTDArray<int> fIndices; | 236 SkTDArray<int> fIndices; |
224 | 237 |
225 Ring fInitialRing; | 238 Ring fInitialRing; |
226 #if GR_AA_CONVEX_TESSELLATOR_VIZ | 239 #if GR_AA_FLATTENING_CONVEX_TESSELLATOR_VIZ |
227 // When visualizing save all the rings | 240 // When visualizing save all the rings |
228 SkTDArray<Ring*> fRings; | 241 SkTDArray<Ring*> fRings; |
229 #else | 242 #else |
230 Ring fRings[2]; | 243 Ring fRings[2]; |
231 #endif | 244 #endif |
232 CandidateVerts fCandidateVerts; | 245 CandidateVerts fCandidateVerts; |
233 | 246 |
234 SkScalar fTargetDepth; | 247 SkScalar fTargetDepth; |
235 | 248 |
249 SkTDArray<SkPoint> fPointBuffer; | |
250 | |
236 // If some goes wrong with the inset computation the tessellator will | 251 // If some goes wrong with the inset computation the tessellator will |
237 // truncate the creation of the inset polygon. In this case the depth | 252 // truncate the creation of the inset polygon. In this case the depth |
238 // check will complain. | 253 // check will complain. |
239 SkDEBUGCODE(bool fShouldCheckDepths;) | 254 SkDEBUGCODE(bool fShouldCheckDepths;) |
240 }; | 255 }; |
241 | 256 |
242 | 257 |
243 #endif | 258 #endif |
244 | 259 |
OLD | NEW |