initial import
[vuplus_webkit] / Source / WebCore / platform / graphics / gpu / LoopBlinnLocalTriangulator.h
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef LoopBlinnLocalTriangulator_h
27 #define LoopBlinnLocalTriangulator_h
28
29 #include "FloatPoint.h"
30 #include "FloatPoint3D.h"
31 #include "LoopBlinnConstants.h"
32 #include <wtf/Assertions.h>
33 #include <wtf/Noncopyable.h>
34
35 namespace WebCore {
36
37 // Performs a localized triangulation of the triangle mesh
38 // corresponding to the four control point vertices of a cubic curve
39 // segment.
40 class LoopBlinnLocalTriangulator {
41     WTF_MAKE_NONCOPYABLE(LoopBlinnLocalTriangulator);
42 public:
43     // The vertices that the triangulator operates upon, containing both
44     // the position information as well as the cubic texture
45     // coordinates.
46     class Vertex {
47         WTF_MAKE_NONCOPYABLE(Vertex);
48     public:
49         Vertex()
50         {
51             resetFlags();
52         }
53
54         const FloatPoint& xyCoordinates() const
55         {
56             return m_xyCoordinates;
57         }
58
59         const FloatPoint3D& klmCoordinates() const
60         {
61             return m_klmCoordinates;
62         }
63
64         // Sets the position and texture coordinates of the vertex.
65         void set(float x, float y,
66                  float k, float l, float m)
67         {
68             m_xyCoordinates.set(x, y);
69             m_klmCoordinates.set(k, l, m);
70         }
71
72         // Flags for walking from the start vertex to the end vertex.
73         bool end()
74         {
75             return m_end;
76         }
77
78         void setEnd(bool end)
79         {
80             m_end = end;
81         }
82
83         bool marked()
84         {
85             return m_marked;
86         }
87
88         void setMarked(bool marked)
89         {
90             m_marked = marked;
91         }
92
93         bool interior()
94         {
95             return m_interior;
96         }
97
98         void setInterior(bool interior)
99         {
100             m_interior = interior;
101         }
102
103         void resetFlags()
104         {
105             m_end = false;
106             m_marked = false;
107             m_interior = false;
108         }
109
110     private:
111         // 2D coordinates of the vertex in the plane.
112         FloatPoint m_xyCoordinates;
113         // Cubic texture coordinates for rendering the curve.
114         FloatPoint3D m_klmCoordinates;
115
116         // Flags for walking from the start vertex to the end vertex.
117         bool m_end;
118         bool m_marked;
119         bool m_interior;
120     };
121
122     // The triangles the Triangulator produces.
123     class Triangle {
124     public:
125         Triangle()
126         {
127             m_vertices[0] = 0;
128             m_vertices[1] = 0;
129             m_vertices[2] = 0;
130         }
131
132         // Gets the vertex at the given index, 0 <= index < 3.
133         Vertex* getVertex(int index)
134         {
135             ASSERT(index >= 0 && index < 3);
136             return m_vertices[index];
137         }
138
139         // Returns true if this triangle contains the given vertex (by
140         // identity, not geometrically).
141         bool contains(Vertex* v);
142
143         // Returns the vertex following the current one in the specified
144         // direction, counterclockwise or clockwise.
145         Vertex* nextVertex(Vertex* current, bool traverseCounterClockwise);
146
147         // Sets the vertices of this triangle, potentially reordering them
148         // to produce a canonical orientation.
149         void setVertices(Vertex* v0,
150                          Vertex* v1,
151                          Vertex* v2)
152         {
153             m_vertices[0] = v0;
154             m_vertices[1] = v1;
155             m_vertices[2] = v2;
156             makeCounterClockwise();
157         }
158
159     private:
160         // Returns the index [0..2] associated with the given vertex, or
161         // -1 if not found.
162         int indexForVertex(Vertex* vertex);
163
164         // Reorders the vertices in this triangle to make them
165         // counterclockwise when viewed in the 2D plane, in order to
166         // achieve a canonical ordering.
167         void makeCounterClockwise();
168
169         // Note: these are raw pointers because they point to the
170         // m_vertices contained in the surrounding triangulator.
171         Vertex* m_vertices[3];
172     };
173
174     LoopBlinnLocalTriangulator();
175
176     // Resets the triangulator's state. After each triangulation and
177     // before the next, call this to re-initialize the internal
178     // vertices' state.
179     void reset();
180
181     // Returns a mutable vertex stored in the triangulator. Use this to
182     // set up the vertices before a triangulation.
183     Vertex* getVertex(int index)
184     {
185         ASSERT(index >= 0 && index < 4);
186         return &m_vertices[index];
187     }
188
189     enum InsideEdgeComputation {
190         ComputeInsideEdges,
191         DontComputeInsideEdges
192     };
193
194     // Once the vertices' contents have been set up, call triangulate()
195     // to recompute the triangles.
196     //
197     // If computeInsideEdges is ComputeInsideEdges, then sideToFill
198     // will be used to determine which side of the cubic curve defined
199     // by the four control points is to be filled.
200     //
201     // The triangulation obeys the following guarantees:
202     //   - If the convex hull is a quadrilateral, then the shortest edge
203     //     will be chosen for the cut into two triangles.
204     //   - If one of the vertices is contained in the triangle spanned
205     //     by the other three, three triangles will be produced.
206     void triangulate(InsideEdgeComputation computeInsideEdges,
207                      LoopBlinnConstants::FillSide sideToFill);
208
209     // Number of triangles computed by triangulate().
210     int numberOfTriangles() const
211     {
212         return m_numberOfTriangles;
213     }
214
215     // Returns the computed triangle at index, 0 <= index < numberOfTriangles().
216     Triangle* getTriangle(int index)
217     {
218         ASSERT(index >= 0 && index < m_numberOfTriangles);
219         return &m_triangles[index];
220     }
221
222     // Number of vertices facing the inside of the shape, if
223     // ComputeInsideEdges was passed when triangulate() was called.
224     int numberOfInteriorVertices() const
225     {
226         return m_numberOfInteriorVertices;
227     }
228
229     // Fetches the given interior vertex, 0 <= index < numberOfInteriorVertices().
230     Vertex* getInteriorVertex(int index)
231     {
232         ASSERT(index >= 0 && index < m_numberOfInteriorVertices);
233         return m_interiorVertices[index];
234     }
235
236 private:
237     void triangulateHelper(LoopBlinnConstants::FillSide sideToFill);
238
239     // Adds a triangle to the triangulation.
240     void addTriangle(Vertex* v0, Vertex* v1, Vertex* v2);
241
242     // Adds a vertex to the list of interior vertices.
243     void addInteriorVertex(Vertex* v);
244
245     // Indicates whether the edge between vertex v0 and v1 is shared
246     // between two or more triangles.
247     bool isSharedEdge(Vertex* v0, Vertex* v1);
248
249     // The vertices being triangulated.
250     Vertex m_vertices[4];
251
252     // The vertices corresponding to the edges facing the inside of the
253     // shape, in order from the start vertex to the end vertex. The more
254     // general triangulation algorithm tessellates this interior region.
255     Vertex* m_interiorVertices[4];
256     // The number of interior vertices that are valid for the current
257     // triangulation.
258     int m_numberOfInteriorVertices;
259
260     // There can be at most three triangles computed by this local
261     // algorithm, which occurs when one of the vertices is contained in
262     // the triangle spanned by the other three. Most of the time the
263     // algorithm computes two triangles.
264     Triangle m_triangles[3];
265     int m_numberOfTriangles;
266 };
267
268 } // namespace WebCore
269
270 #endif // LoopBlinnLocalTriangulator_h