| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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_scene.h" | 5 #include "chrome/browser/android/vr_shell/ui_scene.h" |
| 6 | 6 |
| 7 #define _USE_MATH_DEFINES // For M_PI in MSVC. | 7 #define _USE_MATH_DEFINES // For M_PI in MSVC. |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/android/vr_shell/animation.h" | 14 #include "chrome/browser/android/vr_shell/animation.h" |
| 15 #include "chrome/browser/android/vr_shell/easing.h" | 15 #include "chrome/browser/android/vr_shell/easing.h" |
| 16 #include "chrome/browser/android/vr_shell/ui_elements.h" | 16 #include "chrome/browser/android/vr_shell/ui_element.h" |
| 17 #include "device/vr/vr_math.h" | 17 #include "device/vr/vr_math.h" |
| 18 #include "device/vr/vr_types.h" | 18 #include "device/vr/vr_types.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 20 |
| 21 #define TOLERANCE 0.0001 | 21 #define TOLERANCE 0.0001 |
| 22 | 22 |
| 23 #define EXPECT_VEC3F_NEAR(a, b) \ | 23 #define EXPECT_VEC3F_NEAR(a, b) \ |
| 24 EXPECT_NEAR(a.x(), b.x(), TOLERANCE); \ | 24 EXPECT_NEAR(a.x(), b.x(), TOLERANCE); \ |
| 25 EXPECT_NEAR(a.y(), b.y(), TOLERANCE); \ | 25 EXPECT_NEAR(a.y(), b.y(), TOLERANCE); \ |
| 26 EXPECT_NEAR(a.z(), b.z(), TOLERANCE); | 26 EXPECT_NEAR(a.z(), b.z(), TOLERANCE); |
| 27 | 27 |
| 28 namespace vr_shell { | 28 namespace vr_shell { |
| 29 | 29 |
| 30 namespace { | 30 namespace { |
| 31 | 31 |
| 32 base::TimeTicks usToTicks(uint64_t us) { | 32 base::TimeTicks usToTicks(uint64_t us) { |
| 33 return base::TimeTicks::FromInternalValue(us); | 33 return base::TimeTicks::FromInternalValue(us); |
| 34 } | 34 } |
| 35 | 35 |
| 36 base::TimeDelta usToDelta(uint64_t us) { | 36 base::TimeDelta usToDelta(uint64_t us) { |
| 37 return base::TimeDelta::FromInternalValue(us); | 37 return base::TimeDelta::FromInternalValue(us); |
| 38 } | 38 } |
| 39 | 39 |
| 40 void addElement(UiScene* scene, int id) { | 40 void addElement(UiScene* scene, int id) { |
| 41 auto element = base::MakeUnique<ContentRectangle>(); | 41 auto element = base::MakeUnique<UiElement>(); |
| 42 element->id = id; | 42 element->id = id; |
| 43 scene->AddUiElement(std::move(element)); | 43 scene->AddUiElement(std::move(element)); |
| 44 } | 44 } |
| 45 | 45 |
| 46 void addAnimation(UiScene* scene, | 46 void addAnimation(UiScene* scene, |
| 47 int element_id, | 47 int element_id, |
| 48 int animation_id, | 48 int animation_id, |
| 49 Animation::Property property) { | 49 Animation::Property property) { |
| 50 std::unique_ptr<easing::Easing> easing = base::MakeUnique<easing::Linear>(); | 50 std::unique_ptr<easing::Easing> easing = base::MakeUnique<easing::Linear>(); |
| 51 std::vector<float> from = {}; | 51 std::vector<float> from = {}; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 } | 107 } |
| 108 | 108 |
| 109 // This test creates a parent and child UI element, each with their own | 109 // This test creates a parent and child UI element, each with their own |
| 110 // transformations, and ensures that the child's computed total transform | 110 // transformations, and ensures that the child's computed total transform |
| 111 // incorporates the parent's transform as well as its own. | 111 // incorporates the parent's transform as well as its own. |
| 112 TEST(UiScene, ParentTransformAppliesToChild) { | 112 TEST(UiScene, ParentTransformAppliesToChild) { |
| 113 UiScene scene; | 113 UiScene scene; |
| 114 | 114 |
| 115 // Add a parent element, with distinct transformations. | 115 // Add a parent element, with distinct transformations. |
| 116 // Size of the parent should be ignored by the child. | 116 // Size of the parent should be ignored by the child. |
| 117 auto element = base::MakeUnique<ContentRectangle>(); | 117 auto element = base::MakeUnique<UiElement>(); |
| 118 element->id = 0; | 118 element->id = 0; |
| 119 element->size = {1000, 1000, 1}; | 119 element->size = {1000, 1000, 1}; |
| 120 element->scale = {3, 3, 1}; | 120 element->scale = {3, 3, 1}; |
| 121 element->rotation = {0, 0, 1, M_PI / 2}; | 121 element->rotation = {0, 0, 1, M_PI / 2}; |
| 122 element->translation = {6, 1, 0}; | 122 element->translation = {6, 1, 0}; |
| 123 scene.AddUiElement(std::move(element)); | 123 scene.AddUiElement(std::move(element)); |
| 124 | 124 |
| 125 // Add a child to the parent, with different transformations. | 125 // Add a child to the parent, with different transformations. |
| 126 element = base::MakeUnique<ContentRectangle>(); | 126 element = base::MakeUnique<UiElement>(); |
| 127 element->id = 1; | 127 element->id = 1; |
| 128 element->parent_id = 0; | 128 element->parent_id = 0; |
| 129 element->size = {1, 1, 1}; | 129 element->size = {1, 1, 1}; |
| 130 element->scale = {2, 2, 1}; | 130 element->scale = {2, 2, 1}; |
| 131 element->rotation = {0, 0, 1, M_PI / 2}; | 131 element->rotation = {0, 0, 1, M_PI / 2}; |
| 132 element->translation = {3, 0, 0}; | 132 element->translation = {3, 0, 0}; |
| 133 scene.AddUiElement(std::move(element)); | 133 scene.AddUiElement(std::move(element)); |
| 134 const ContentRectangle* child = scene.GetUiElementById(1); | 134 const UiElement* child = scene.GetUiElementById(1); |
| 135 | 135 |
| 136 const gfx::Vector3dF origin(0, 0, 0); | 136 const gfx::Vector3dF origin(0, 0, 0); |
| 137 const gfx::Vector3dF point(1, 0, 0); | 137 const gfx::Vector3dF point(1, 0, 0); |
| 138 | 138 |
| 139 scene.UpdateTransforms(usToTicks(0)); | 139 scene.UpdateTransforms(usToTicks(0)); |
| 140 auto new_origin = vr::MatrixVectorMul(child->TransformMatrix(), origin); | 140 auto new_origin = vr::MatrixVectorMul(child->TransformMatrix(), origin); |
| 141 auto new_point = vr::MatrixVectorMul(child->TransformMatrix(), point); | 141 auto new_point = vr::MatrixVectorMul(child->TransformMatrix(), point); |
| 142 EXPECT_VEC3F_NEAR(gfx::Vector3dF(6, 10, 0), new_origin); | 142 EXPECT_VEC3F_NEAR(gfx::Vector3dF(6, 10, 0), new_origin); |
| 143 EXPECT_VEC3F_NEAR(gfx::Vector3dF(0, 10, 0), new_point); | 143 EXPECT_VEC3F_NEAR(gfx::Vector3dF(0, 10, 0), new_point); |
| 144 } | 144 } |
| 145 | 145 |
| 146 TEST(UiScene, Opacity) { | 146 TEST(UiScene, Opacity) { |
| 147 UiScene scene; | 147 UiScene scene; |
| 148 | 148 |
| 149 auto element = base::MakeUnique<ContentRectangle>(); | 149 auto element = base::MakeUnique<UiElement>(); |
| 150 element->id = 0; | 150 element->id = 0; |
| 151 element->opacity = 0.5; | 151 element->opacity = 0.5; |
| 152 scene.AddUiElement(std::move(element)); | 152 scene.AddUiElement(std::move(element)); |
| 153 | 153 |
| 154 element = base::MakeUnique<ContentRectangle>(); | 154 element = base::MakeUnique<UiElement>(); |
| 155 element->id = 1; | 155 element->id = 1; |
| 156 element->parent_id = 0; | 156 element->parent_id = 0; |
| 157 element->opacity = 0.5; | 157 element->opacity = 0.5; |
| 158 scene.AddUiElement(std::move(element)); | 158 scene.AddUiElement(std::move(element)); |
| 159 | 159 |
| 160 scene.UpdateTransforms(usToTicks(0)); | 160 scene.UpdateTransforms(usToTicks(0)); |
| 161 EXPECT_EQ(scene.GetUiElementById(0)->computed_opacity, 0.5f); | 161 EXPECT_EQ(scene.GetUiElementById(0)->computed_opacity, 0.5f); |
| 162 EXPECT_EQ(scene.GetUiElementById(1)->computed_opacity, 0.25f); | 162 EXPECT_EQ(scene.GetUiElementById(1)->computed_opacity, 0.25f); |
| 163 } | 163 } |
| 164 | 164 |
| 165 TEST(UiScene, LockToFov) { | 165 TEST(UiScene, LockToFov) { |
| 166 UiScene scene; | 166 UiScene scene; |
| 167 | 167 |
| 168 auto element = base::MakeUnique<ContentRectangle>(); | 168 auto element = base::MakeUnique<UiElement>(); |
| 169 element->id = 0; | 169 element->id = 0; |
| 170 element->lock_to_fov = true; | 170 element->lock_to_fov = true; |
| 171 scene.AddUiElement(std::move(element)); | 171 scene.AddUiElement(std::move(element)); |
| 172 | 172 |
| 173 element = base::MakeUnique<ContentRectangle>(); | 173 element = base::MakeUnique<UiElement>(); |
| 174 element->id = 1; | 174 element->id = 1; |
| 175 element->parent_id = 0; | 175 element->parent_id = 0; |
| 176 element->lock_to_fov = false; | 176 element->lock_to_fov = false; |
| 177 scene.AddUiElement(std::move(element)); | 177 scene.AddUiElement(std::move(element)); |
| 178 | 178 |
| 179 scene.UpdateTransforms(usToTicks(0)); | 179 scene.UpdateTransforms(usToTicks(0)); |
| 180 EXPECT_EQ(scene.GetUiElementById(0)->computed_lock_to_fov, true); | 180 EXPECT_EQ(scene.GetUiElementById(0)->computed_lock_to_fov, true); |
| 181 EXPECT_EQ(scene.GetUiElementById(1)->computed_lock_to_fov, true); | 181 EXPECT_EQ(scene.GetUiElementById(1)->computed_lock_to_fov, true); |
| 182 } | 182 } |
| 183 | 183 |
| 184 typedef struct { | 184 typedef struct { |
| 185 XAnchoring x_anchoring; | 185 XAnchoring x_anchoring; |
| 186 YAnchoring y_anchoring; | 186 YAnchoring y_anchoring; |
| 187 float expected_x; | 187 float expected_x; |
| 188 float expected_y; | 188 float expected_y; |
| 189 } AnchoringTestCase; | 189 } AnchoringTestCase; |
| 190 | 190 |
| 191 class AnchoringTest : public ::testing::TestWithParam<AnchoringTestCase> {}; | 191 class AnchoringTest : public ::testing::TestWithParam<AnchoringTestCase> {}; |
| 192 | 192 |
| 193 TEST_P(AnchoringTest, VerifyCorrectPosition) { | 193 TEST_P(AnchoringTest, VerifyCorrectPosition) { |
| 194 UiScene scene; | 194 UiScene scene; |
| 195 | 195 |
| 196 // Create a parent element with non-unity size and scale. | 196 // Create a parent element with non-unity size and scale. |
| 197 auto element = base::MakeUnique<ContentRectangle>(); | 197 auto element = base::MakeUnique<UiElement>(); |
| 198 element->id = 0; | 198 element->id = 0; |
| 199 element->size = {2, 2, 1}; | 199 element->size = {2, 2, 1}; |
| 200 element->scale = {2, 2, 1}; | 200 element->scale = {2, 2, 1}; |
| 201 scene.AddUiElement(std::move(element)); | 201 scene.AddUiElement(std::move(element)); |
| 202 | 202 |
| 203 // Add a child to the parent, with anchoring. | 203 // Add a child to the parent, with anchoring. |
| 204 element = base::MakeUnique<ContentRectangle>(); | 204 element = base::MakeUnique<UiElement>(); |
| 205 element->id = 1; | 205 element->id = 1; |
| 206 element->parent_id = 0; | 206 element->parent_id = 0; |
| 207 element->x_anchoring = GetParam().x_anchoring; | 207 element->x_anchoring = GetParam().x_anchoring; |
| 208 element->y_anchoring = GetParam().y_anchoring; | 208 element->y_anchoring = GetParam().y_anchoring; |
| 209 scene.AddUiElement(std::move(element)); | 209 scene.AddUiElement(std::move(element)); |
| 210 | 210 |
| 211 scene.UpdateTransforms(usToTicks(0)); | 211 scene.UpdateTransforms(usToTicks(0)); |
| 212 const ContentRectangle* child = scene.GetUiElementById(1); | 212 const UiElement* child = scene.GetUiElementById(1); |
| 213 EXPECT_NEAR(child->GetCenter().x(), GetParam().expected_x, TOLERANCE); | 213 EXPECT_NEAR(child->GetCenter().x(), GetParam().expected_x, TOLERANCE); |
| 214 EXPECT_NEAR(child->GetCenter().y(), GetParam().expected_y, TOLERANCE); | 214 EXPECT_NEAR(child->GetCenter().y(), GetParam().expected_y, TOLERANCE); |
| 215 scene.RemoveUiElement(1); | 215 scene.RemoveUiElement(1); |
| 216 } | 216 } |
| 217 | 217 |
| 218 const std::vector<AnchoringTestCase> anchoring_test_cases = { | 218 const std::vector<AnchoringTestCase> anchoring_test_cases = { |
| 219 {XAnchoring::XNONE, YAnchoring::YNONE, 0, 0}, | 219 {XAnchoring::XNONE, YAnchoring::YNONE, 0, 0}, |
| 220 {XAnchoring::XLEFT, YAnchoring::YNONE, -2, 0}, | 220 {XAnchoring::XLEFT, YAnchoring::YNONE, -2, 0}, |
| 221 {XAnchoring::XRIGHT, YAnchoring::YNONE, 2, 0}, | 221 {XAnchoring::XRIGHT, YAnchoring::YNONE, 2, 0}, |
| 222 {XAnchoring::XNONE, YAnchoring::YTOP, 0, 2}, | 222 {XAnchoring::XNONE, YAnchoring::YTOP, 0, 2}, |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 EXPECT_FLOAT_EQ(300, animation->from[0]); | 445 EXPECT_FLOAT_EQ(300, animation->from[0]); |
| 446 EXPECT_FLOAT_EQ(301, animation->from[1]); | 446 EXPECT_FLOAT_EQ(301, animation->from[1]); |
| 447 EXPECT_FLOAT_EQ(302, animation->from[2]); | 447 EXPECT_FLOAT_EQ(302, animation->from[2]); |
| 448 EXPECT_FLOAT_EQ(303, animation->from[3]); | 448 EXPECT_FLOAT_EQ(303, animation->from[3]); |
| 449 | 449 |
| 450 EXPECT_EQ(usToTicks(22345000), animation->start); | 450 EXPECT_EQ(usToTicks(22345000), animation->start); |
| 451 EXPECT_EQ(usToDelta(54321000), animation->duration); | 451 EXPECT_EQ(usToDelta(54321000), animation->duration); |
| 452 } | 452 } |
| 453 | 453 |
| 454 } // namespace vr_shell | 454 } // namespace vr_shell |
| OLD | NEW |