| 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 |