Home | History | Annotate | Download | only in gpu
      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
    271