OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/vr_shell/ui_elements.h" | 5 #include "chrome/browser/android/vr_shell/ui_elements.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
11 #include "chrome/browser/android/vr_shell/animation.h" | 11 #include "chrome/browser/android/vr_shell/animation.h" |
12 #include "chrome/browser/android/vr_shell/easing.h" | 12 #include "chrome/browser/android/vr_shell/easing.h" |
| 13 #include "device/vr/vr_math.h" |
13 | 14 |
14 namespace vr_shell { | 15 namespace vr_shell { |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 bool GetRayPlaneDistance(const gvr::Vec3f& ray_origin, | 19 bool GetRayPlaneDistance(const gfx::Point3F& ray_origin, |
19 const gvr::Vec3f& ray_vector, | 20 const gfx::Vector3dF& ray_vector, |
20 const gvr::Vec3f& plane_origin, | 21 const gfx::Point3F& plane_origin, |
21 const gvr::Vec3f& plane_normal, | 22 const gfx::Vector3dF& plane_normal, |
22 float* distance) { | 23 float* distance) { |
23 float denom = vr_shell::VectorDot(ray_vector, plane_normal); | 24 float denom = gfx::DotProduct(ray_vector, plane_normal); |
24 if (denom == 0) { | 25 if (denom == 0) { |
25 return false; | 26 return false; |
26 } | 27 } |
27 gvr::Vec3f rel; | 28 gfx::Vector3dF rel = ray_origin - plane_origin; |
28 rel.x = ray_origin.x - plane_origin.x; | 29 *distance = -gfx::DotProduct(plane_normal, rel) / denom; |
29 rel.y = ray_origin.y - plane_origin.y; | |
30 rel.z = ray_origin.z - plane_origin.z; | |
31 *distance = -vr_shell::VectorDot(plane_normal, rel) / denom; | |
32 return true; | 30 return true; |
33 } | 31 } |
34 | 32 |
35 } // namespace | 33 } // namespace |
36 | 34 |
37 Transform::Transform() { | 35 Transform::Transform() { |
38 MakeIdentity(); | 36 MakeIdentity(); |
39 } | 37 } |
40 | 38 |
41 void Transform::MakeIdentity() { | 39 void Transform::MakeIdentity() { |
42 SetIdentityM(to_world); | 40 vr::SetIdentityM(&to_world); |
43 } | 41 } |
44 | 42 |
45 void Transform::Rotate(gvr::Quatf quat) { | 43 void Transform::Rotate(const vr::Quatf& quat) { |
46 // TODO(klausw): use specialized rotation code? Constructing the matrix | 44 // TODO(klausw): use specialized rotation code? Constructing the matrix |
47 // via axis-angle quaternion is inefficient. | 45 // via axis-angle quaternion is inefficient. |
48 gvr::Mat4f forward = QuatToMatrix(quat); | 46 vr::Mat4f forward; |
49 to_world = MatrixMul(forward, to_world); | 47 vr::QuatToMatrix(quat, &forward); |
| 48 vr::MatrixMul(forward, to_world, &to_world); |
50 } | 49 } |
51 | 50 |
52 void Transform::Rotate(float ax, float ay, float az, float rad) { | 51 void Transform::Rotate(const vr::RotationAxisAngle& axis_angle) { |
53 Rotate(QuatFromAxisAngle({ax, ay, az}, rad)); | 52 Rotate(vr::QuatFromAxisAngle(axis_angle)); |
54 } | 53 } |
55 | 54 |
56 void Transform::Translate(float tx, float ty, float tz) { | 55 void Transform::Translate(const gfx::Vector3dF& translation) { |
57 TranslateM(to_world, to_world, tx, ty, tz); | 56 vr::TranslateM(to_world, translation, &to_world); |
58 } | 57 } |
59 | 58 |
60 void Transform::Scale(float sx, float sy, float sz) { | 59 void Transform::Scale(const gfx::Vector3dF& scale) { |
61 ScaleM(to_world, to_world, sx, sy, sz); | 60 vr::ScaleM(to_world, scale, &to_world); |
62 } | 61 } |
63 | 62 |
64 const gvr::Mat4f& WorldRectangle::TransformMatrix() const { | 63 const vr::Mat4f& WorldRectangle::TransformMatrix() const { |
65 return transform_.to_world; | 64 return transform_.to_world; |
66 } | 65 } |
67 | 66 |
68 gvr::Vec3f WorldRectangle::GetCenter() const { | 67 gfx::Point3F WorldRectangle::GetCenter() const { |
69 const gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; | 68 const gfx::Point3F kOrigin(0.0f, 0.0f, 0.0f); |
70 return MatrixVectorMul(transform_.to_world, kOrigin); | 69 return kOrigin + vr::GetTranslation(transform_.to_world); |
71 } | 70 } |
72 | 71 |
73 gvr::Vec2f WorldRectangle::GetUnitRectangleCoordinates( | 72 gfx::PointF WorldRectangle::GetUnitRectangleCoordinates( |
74 const gvr::Vec3f& world_point) { | 73 const gfx::Point3F& world_point) { |
75 const gvr::Mat4f& transform = transform_.to_world; | 74 // TODO(acondor): Simplify the math in this function. |
76 gvr::Vec3f origin = MatrixVectorMul(transform, gvr::Vec3f({0, 0, 0})); | 75 const vr::Mat4f& transform = transform_.to_world; |
77 gvr::Vec3f xAxis = MatrixVectorMul(transform, gvr::Vec3f({1, 0, 0})); | 76 gfx::Vector3dF origin = |
78 gvr::Vec3f yAxis = MatrixVectorMul(transform, gvr::Vec3f({0, 1, 0})); | 77 vr::MatrixVectorMul(transform, gfx::Vector3dF(0, 0, 0)); |
79 xAxis = VectorSubtract(xAxis, origin); | 78 gfx::Vector3dF x_axis = |
80 yAxis = VectorSubtract(yAxis, origin); | 79 vr::MatrixVectorMul(transform, gfx::Vector3dF(1, 0, 0)); |
81 gvr::Vec3f point = VectorSubtract(world_point, origin); | 80 gfx::Vector3dF y_axis = |
| 81 vr::MatrixVectorMul(transform, gfx::Vector3dF(0, 1, 0)); |
| 82 x_axis.Subtract(origin); |
| 83 y_axis.Subtract(origin); |
| 84 gfx::Point3F point = world_point - origin; |
| 85 gfx::Vector3dF v_point(point.x(), point.y(), point.z()); |
82 | 86 |
83 float x = VectorDot(point, xAxis) / VectorDot(xAxis, xAxis); | 87 float x = gfx::DotProduct(v_point, x_axis) / gfx::DotProduct(x_axis, x_axis); |
84 float y = VectorDot(point, yAxis) / VectorDot(yAxis, yAxis); | 88 float y = gfx::DotProduct(v_point, y_axis) / gfx::DotProduct(y_axis, y_axis); |
85 return {x, y}; | 89 return gfx::PointF(x, y); |
86 } | 90 } |
87 | 91 |
88 gvr::Vec3f WorldRectangle::GetNormal() const { | 92 gfx::Vector3dF WorldRectangle::GetNormal() const { |
89 const gvr::Vec3f kNormalOrig = {0.0f, 0.0f, -1.0f}; | 93 const gfx::Vector3dF kNormalOrig = {0.0f, 0.0f, -1.0f}; |
90 return MatrixVectorRotate(transform_.to_world, kNormalOrig); | 94 return vr::MatrixVectorRotate(transform_.to_world, kNormalOrig); |
91 } | 95 } |
92 | 96 |
93 bool WorldRectangle::GetRayDistance(const gvr::Vec3f& ray_origin, | 97 bool WorldRectangle::GetRayDistance(const gfx::Point3F& ray_origin, |
94 const gvr::Vec3f& ray_vector, | 98 const gfx::Vector3dF& ray_vector, |
95 float* distance) const { | 99 float* distance) const { |
96 return GetRayPlaneDistance(ray_origin, ray_vector, GetCenter(), GetNormal(), | 100 return GetRayPlaneDistance(ray_origin, ray_vector, GetCenter(), GetNormal(), |
97 distance); | 101 distance); |
98 } | 102 } |
99 | 103 |
100 ContentRectangle::ContentRectangle() = default; | 104 ContentRectangle::ContentRectangle() = default; |
101 | 105 |
102 ContentRectangle::~ContentRectangle() = default; | 106 ContentRectangle::~ContentRectangle() = default; |
103 | 107 |
104 void ContentRectangle::Animate(const base::TimeTicks& time) { | 108 void ContentRectangle::Animate(const base::TimeTicks& time) { |
105 for (auto& it : animations) { | 109 for (auto& it : animations) { |
106 Animation& animation = *it; | 110 Animation& animation = *it; |
107 if (time < animation.start) | 111 if (time < animation.start) |
108 continue; | 112 continue; |
109 | 113 |
110 // If |from| is not specified, start at the current values. | 114 // If |from| is not specified, start at the current values. |
111 if (animation.from.size() == 0) { | 115 if (animation.from.size() == 0) { |
112 switch (animation.property) { | 116 switch (animation.property) { |
113 case Animation::COPYRECT: | 117 case Animation::COPYRECT: |
114 animation.from.push_back(copy_rect.x); | 118 animation.from.push_back(copy_rect.x()); |
115 animation.from.push_back(copy_rect.y); | 119 animation.from.push_back(copy_rect.y()); |
116 animation.from.push_back(copy_rect.width); | 120 animation.from.push_back(copy_rect.width()); |
117 animation.from.push_back(copy_rect.height); | 121 animation.from.push_back(copy_rect.height()); |
118 break; | 122 break; |
119 case Animation::SIZE: | 123 case Animation::SIZE: |
120 animation.from.push_back(size.x); | 124 animation.from.push_back(size.x()); |
121 animation.from.push_back(size.y); | 125 animation.from.push_back(size.y()); |
122 break; | 126 break; |
123 case Animation::SCALE: | 127 case Animation::SCALE: |
124 animation.from.push_back(scale.x); | 128 animation.from.push_back(scale.x()); |
125 animation.from.push_back(scale.y); | 129 animation.from.push_back(scale.y()); |
126 animation.from.push_back(scale.z); | 130 animation.from.push_back(scale.z()); |
127 break; | 131 break; |
128 case Animation::ROTATION: | 132 case Animation::ROTATION: |
129 animation.from.push_back(rotation.x); | 133 animation.from.push_back(rotation.x); |
130 animation.from.push_back(rotation.y); | 134 animation.from.push_back(rotation.y); |
131 animation.from.push_back(rotation.z); | 135 animation.from.push_back(rotation.z); |
132 animation.from.push_back(rotation.angle); | 136 animation.from.push_back(rotation.angle); |
133 break; | 137 break; |
134 case Animation::TRANSLATION: | 138 case Animation::TRANSLATION: |
135 animation.from.push_back(translation.x); | 139 animation.from.push_back(translation.x()); |
136 animation.from.push_back(translation.y); | 140 animation.from.push_back(translation.y()); |
137 animation.from.push_back(translation.z); | 141 animation.from.push_back(translation.z()); |
138 break; | 142 break; |
139 case Animation::OPACITY: | 143 case Animation::OPACITY: |
140 animation.from.push_back(opacity); | 144 animation.from.push_back(opacity); |
141 break; | 145 break; |
142 } | 146 } |
143 } | 147 } |
144 CHECK_EQ(animation.from.size(), animation.to.size()); | 148 CHECK_EQ(animation.from.size(), animation.to.size()); |
145 | 149 |
146 std::vector<float> values(animation.from.size()); | 150 std::vector<float> values(animation.from.size()); |
147 for (std::size_t i = 0; i < animation.from.size(); ++i) { | 151 for (std::size_t i = 0; i < animation.from.size(); ++i) { |
148 if (animation.to[i] == animation.from[i] || | 152 if (animation.to[i] == animation.from[i] || |
149 time >= (animation.start + animation.duration)) { | 153 time >= (animation.start + animation.duration)) { |
150 values[i] = animation.to[i]; | 154 values[i] = animation.to[i]; |
151 continue; | 155 continue; |
152 } | 156 } |
153 double value = animation.easing->CalculateValue( | 157 double value = animation.easing->CalculateValue( |
154 (time - animation.start).InMillisecondsF() / | 158 (time - animation.start).InMillisecondsF() / |
155 animation.duration.InMillisecondsF()); | 159 animation.duration.InMillisecondsF()); |
156 values[i] = | 160 values[i] = |
157 animation.from[i] + (value * (animation.to[i] - animation.from[i])); | 161 animation.from[i] + (value * (animation.to[i] - animation.from[i])); |
158 } | 162 } |
159 switch (animation.property) { | 163 switch (animation.property) { |
160 case Animation::COPYRECT: | 164 case Animation::COPYRECT: |
161 CHECK_EQ(animation.from.size(), 4u); | 165 CHECK_EQ(animation.from.size(), 4u); |
162 copy_rect.x = values[0]; | 166 copy_rect.SetRect(values[0], values[1], values[2], values[3]); |
163 copy_rect.y = values[1]; | |
164 copy_rect.width = values[2]; | |
165 copy_rect.height = values[3]; | |
166 break; | 167 break; |
167 case Animation::SIZE: | 168 case Animation::SIZE: |
168 CHECK_EQ(animation.from.size(), 2u); | 169 CHECK_EQ(animation.from.size(), 2u); |
169 size.x = values[0]; | 170 size.set_x(values[0]); |
170 size.y = values[1]; | 171 size.set_y(values[1]); |
171 break; | 172 break; |
172 case Animation::SCALE: | 173 case Animation::SCALE: |
173 CHECK_EQ(animation.from.size(), 3u); | 174 CHECK_EQ(animation.from.size(), 3u); |
174 scale.x = values[0]; | 175 scale = {values[0], values[1], values[2]}; |
175 scale.y = values[1]; | |
176 scale.z = values[2]; | |
177 break; | 176 break; |
178 case Animation::ROTATION: | 177 case Animation::ROTATION: |
179 CHECK_EQ(animation.from.size(), 4u); | 178 CHECK_EQ(animation.from.size(), 4u); |
180 rotation.x = values[0]; | 179 rotation.x = values[0]; |
181 rotation.y = values[1]; | 180 rotation.y = values[1]; |
182 rotation.z = values[2]; | 181 rotation.z = values[2]; |
183 rotation.angle = values[3]; | 182 rotation.angle = values[3]; |
184 break; | 183 break; |
185 case Animation::TRANSLATION: | 184 case Animation::TRANSLATION: |
186 CHECK_EQ(animation.from.size(), 3u); | 185 CHECK_EQ(animation.from.size(), 3u); |
187 translation.x = values[0]; | 186 translation = {values[0], values[1], values[2]}; |
188 translation.y = values[1]; | |
189 translation.z = values[2]; | |
190 break; | 187 break; |
191 case Animation::OPACITY: | 188 case Animation::OPACITY: |
192 CHECK_EQ(animation.from.size(), 1u); | 189 CHECK_EQ(animation.from.size(), 1u); |
193 opacity = values[0]; | 190 opacity = values[0]; |
194 break; | 191 break; |
195 } | 192 } |
196 } | 193 } |
197 for (auto it = animations.begin(); it != animations.end();) { | 194 for (auto it = animations.begin(); it != animations.end();) { |
198 const Animation& animation = **it; | 195 const Animation& animation = **it; |
199 if (time >= (animation.start + animation.duration)) { | 196 if (time >= (animation.start + animation.duration)) { |
200 it = animations.erase(it); | 197 it = animations.erase(it); |
201 } else { | 198 } else { |
202 ++it; | 199 ++it; |
203 } | 200 } |
204 } | 201 } |
205 } | 202 } |
206 | 203 |
207 bool ContentRectangle::IsVisible() const { | 204 bool ContentRectangle::IsVisible() const { |
208 return visible && computed_opacity > 0.0f; | 205 return visible && computed_opacity > 0.0f; |
209 } | 206 } |
210 | 207 |
211 bool ContentRectangle::IsHitTestable() const { | 208 bool ContentRectangle::IsHitTestable() const { |
212 return IsVisible() && hit_testable; | 209 return IsVisible() && hit_testable; |
213 } | 210 } |
214 | 211 |
215 } // namespace vr_shell | 212 } // namespace vr_shell |
OLD | NEW |