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