OLD | NEW |
| (Empty) |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CC_MATH_UTIL_H_ | |
6 #define CC_MATH_UTIL_H_ | |
7 | |
8 #include <cmath> | |
9 | |
10 #include "base/logging.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "cc/cc_export.h" | |
13 #include "ui/gfx/point_f.h" | |
14 #include "ui/gfx/point3_f.h" | |
15 #include "ui/gfx/size.h" | |
16 #include "ui/gfx/transform.h" | |
17 | |
18 namespace base { | |
19 class Value; | |
20 } | |
21 | |
22 namespace gfx { | |
23 class QuadF; | |
24 class Rect; | |
25 class RectF; | |
26 class Transform; | |
27 class Vector2dF; | |
28 } | |
29 | |
30 namespace cc { | |
31 | |
32 struct HomogeneousCoordinate { | |
33 HomogeneousCoordinate(double newX, double newY, double newZ, double newW) | |
34 : x(newX) | |
35 , y(newY) | |
36 , z(newZ) | |
37 , w(newW) | |
38 { | |
39 } | |
40 | |
41 bool shouldBeClipped() const | |
42 { | |
43 return w <= 0; | |
44 } | |
45 | |
46 gfx::PointF cartesianPoint2d() const | |
47 { | |
48 if (w == 1) | |
49 return gfx::PointF(x, y); | |
50 | |
51 // For now, because this code is used privately only by MathUtil, it sho
uld never be called when w == 0, and we do not yet need to handle that case. | |
52 DCHECK(w); | |
53 double invW = 1.0 / w; | |
54 return gfx::PointF(x * invW, y * invW); | |
55 } | |
56 | |
57 gfx::Point3F cartesianPoint3d() const | |
58 { | |
59 if (w == 1) | |
60 return gfx::Point3F(x, y, z); | |
61 | |
62 // For now, because this code is used privately only by MathUtil, it sho
uld never be called when w == 0, and we do not yet need to handle that case. | |
63 DCHECK(w); | |
64 double invW = 1.0 / w; | |
65 return gfx::Point3F(x * invW, y * invW, z * invW); | |
66 } | |
67 | |
68 double x; | |
69 double y; | |
70 double z; | |
71 double w; | |
72 }; | |
73 | |
74 class CC_EXPORT MathUtil { | |
75 public: | |
76 static const double PI_DOUBLE; | |
77 static const float PI_FLOAT; | |
78 static const double EPSILON; | |
79 | |
80 static double Deg2Rad(double deg) { return deg * PI_DOUBLE / 180; } | |
81 static double Rad2Deg(double rad) { return rad * 180 / PI_DOUBLE; } | |
82 | |
83 static float Deg2Rad(float deg) { return deg * PI_FLOAT / 180; } | |
84 static float Rad2Deg(float rad) { return rad * 180 / PI_FLOAT; } | |
85 | |
86 static float Round(float f) { return (f > 0.f) ? std::floor(f + 0.5f) : std
::ceil(f - 0.5f); } | |
87 static double Round(double d) { return (d > 0.0) ? std::floor(d + 0.5) : st
d::ceil(d - 0.5); } | |
88 | |
89 // Background: Existing transform code does not do the right thing in | |
90 // mapRect / mapQuad / projectQuad when there is a perspective projection th
at causes | |
91 // one of the transformed vertices to go to w < 0. In those cases, it is nec
essary to | |
92 // perform clipping in homogeneous coordinates, after applying the transform
, before | |
93 // dividing-by-w to convert to cartesian coordinates. | |
94 // | |
95 // These functions return the axis-aligned rect that encloses the correctly
clipped, | |
96 // transformed polygon. | |
97 static gfx::Rect mapClippedRect(const gfx::Transform&, const gfx::Rect&); | |
98 static gfx::RectF mapClippedRect(const gfx::Transform&, const gfx::RectF&); | |
99 static gfx::RectF projectClippedRect(const gfx::Transform&, const gfx::RectF
&); | |
100 | |
101 // Returns an array of vertices that represent the clipped polygon. After re
turning, indexes from | |
102 // 0 to numVerticesInClippedQuad are valid in the clippedQuad array. Note th
at | |
103 // numVerticesInClippedQuad may be zero, which means the entire quad was cli
pped, and | |
104 // none of the vertices in the array are valid. | |
105 static void mapClippedQuad(const gfx::Transform&, const gfx::QuadF& srcQuad,
gfx::PointF clippedQuad[8], int& numVerticesInClippedQuad); | |
106 | |
107 static gfx::RectF computeEnclosingRectOfVertices(gfx::PointF vertices[], int
numVertices); | |
108 static gfx::RectF computeEnclosingClippedRect(const HomogeneousCoordinate& h
1, const HomogeneousCoordinate& h2, const HomogeneousCoordinate& h3, const Homog
eneousCoordinate& h4); | |
109 | |
110 // NOTE: These functions do not do correct clipping against w = 0 plane, but
they | |
111 // correctly detect the clipped condition via the boolean clipped. | |
112 static gfx::QuadF mapQuad(const gfx::Transform&, const gfx::QuadF&, bool& cl
ipped); | |
113 static gfx::PointF mapPoint(const gfx::Transform&, const gfx::PointF&, bool&
clipped); | |
114 static gfx::Point3F mapPoint(const gfx::Transform&, const gfx::Point3F&, boo
l& clipped); | |
115 static gfx::QuadF projectQuad(const gfx::Transform&, const gfx::QuadF&, bool
& clipped); | |
116 static gfx::PointF projectPoint(const gfx::Transform&, const gfx::PointF&, b
ool& clipped); | |
117 | |
118 static gfx::Vector2dF computeTransform2dScaleComponents(const gfx::Transform
&, float fallbackValue); | |
119 | |
120 // Returns the smallest angle between the given two vectors in degrees. Neit
her vector is | |
121 // assumed to be normalized. | |
122 static float smallestAngleBetweenVectors(gfx::Vector2dF, gfx::Vector2dF); | |
123 | |
124 // Projects the |source| vector onto |destination|. Neither vector is assume
d to be normalized. | |
125 static gfx::Vector2dF projectVector(gfx::Vector2dF source, gfx::Vector2dF de
stination); | |
126 | |
127 // Conversion to value. | |
128 static scoped_ptr<base::Value> asValue(gfx::Size s); | |
129 static scoped_ptr<base::Value> asValue(gfx::PointF q); | |
130 static scoped_ptr<base::Value> asValue(gfx::QuadF q); | |
131 | |
132 // Returns a base::Value representation of the floating point value. | |
133 // If the value is inf, returns max double/float representation. | |
134 static scoped_ptr<base::Value> asValueSafely(double value); | |
135 static scoped_ptr<base::Value> asValueSafely(float value); | |
136 | |
137 }; | |
138 | |
139 } // namespace cc | |
140 | |
141 #endif // CC_MATH_UTIL_H_ | |
OLD | NEW |