blob: 378ae51b0f28b2fc4a88702fe573b52e7b5608d0 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/vr/elements/repositioner.h"
#include <memory>
#include "base/strings/stringprintf.h"
#include "cc/test/geometry_test_utils.h"
#include "chrome/browser/vr/test/animation_utils.h"
#include "chrome/browser/vr/test/constants.h"
#include "chrome/browser/vr/ui_scene.h"
#include "chrome/browser/vr/ui_scene_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/transform.h"
namespace vr {
namespace {
constexpr float kTestRepositionDistance = 2.f;
void CheckRepositionedCorrectly(size_t test_case_index,
UiElement* element,
const gfx::Vector3dF& head_up_vector,
const gfx::Point3F& expected_center,
const gfx::Vector3dF& expected_right_vector) {
SCOPED_TRACE(base::StringPrintf("Test case index = %zd", test_case_index));
gfx::Point3F center = element->GetCenter();
EXPECT_NEAR(center.x(), expected_center.x(), kEpsilon);
EXPECT_NEAR(center.y(), expected_center.y(), kEpsilon);
EXPECT_NEAR(center.z(), expected_center.z(), kEpsilon);
gfx::Vector3dF right_vector = {1, 0, 0};
element->world_space_transform().TransformVector(&right_vector);
EXPECT_VECTOR3DF_NEAR(right_vector, expected_right_vector, kEpsilon);
}
} // namespace
TEST(Repositioner, RepositionNegativeZWithReticle) {
UiScene scene;
auto child = std::make_unique<UiElement>();
child->SetTranslate(0, 0, -kTestRepositionDistance);
auto* element = child.get();
auto parent = std::make_unique<Repositioner>(kTestRepositionDistance);
auto* repositioner = parent.get();
parent->AddChild(std::move(child));
scene.AddUiElement(kRoot, std::move(parent));
repositioner->set_laser_origin(gfx::Point3F(1, -1, 0));
struct TestCase {
TestCase(gfx::Vector3dF v,
gfx::Vector3dF u,
gfx::Point3F p,
gfx::Vector3dF r)
: laser_direction(v),
head_up_vector(u),
expected_element_center(p),
expected_right_vector(r) {}
gfx::Vector3dF laser_direction;
gfx::Vector3dF head_up_vector;
gfx::Point3F expected_element_center;
gfx::Vector3dF expected_right_vector;
};
std::vector<TestCase> test_cases = {
{{-2, 2.41421f, -1},
{0, 1, 0},
{-1, 1.41421f, -1},
{0.707107f, 0, -0.707107f}},
{{-2, 2.41421f, 1},
{0, 1, 0},
{-1, 1.41421f, 1},
{-0.707107f, 0, -0.707107f}},
{{0, 2.41421f, 1},
{0, 1, 0},
{1, 1.41421f, 1},
{-0.707107f, 0, 0.707107f}},
{{0, 2.41421f, -1},
{0, 1, 0},
{1, 1.41421f, -1},
{0.707107f, 0, 0.707107f}},
{{-2, -0.41421f, -1},
{0, 1, 0},
{-1, -1.41421f, -1},
{0.707107f, 0, -0.707107f}},
{{-2, -0.41421f, 1},
{0, 1, 0},
{-1, -1.41421f, 1},
{-0.707107f, 0, -0.707107f}},
{{0, -0.41421f, 1},
{0, 1, 0},
{1, -1.41421f, 1},
{-0.707107f, 0, 0.707107f}},
{{0, -0.41421f, -1},
{0, 1, 0},
{1, -1.41421f, -1},
{0.707107f, 0, 0.707107f}},
{{-1, 3, 0}, {0, 0, 1}, {0, kTestRepositionDistance, 0}, {1, 0, 0}},
{{-1, -1, 0}, {0, 0, -1}, {0, -kTestRepositionDistance, 0}, {1, 0, 0}},
{{-1, 1, 2}, {-1, 0, 0}, {0, 0, kTestRepositionDistance}, {0, -1, 0}},
{{-1, 1, -2}, {-1, 0, 0}, {0, 0, -kTestRepositionDistance}, {0, 1, 0}},
{{-1, 1, -2}, {-1, 0, 0}, {0, 0, -kTestRepositionDistance}, {0, 1, 0}},
};
for (size_t i = 0; i < test_cases.size(); i++) {
TestCase test_case = test_cases[i];
repositioner->set_laser_direction(test_case.laser_direction);
gfx::Quaternion quat{{0, 1, 0}, test_case.head_up_vector};
gfx::Transform head_pose(quat);
scene.OnBeginFrame(MsToTicks(0), head_pose);
// Before enable repositioner, child element should NOT have rotation.
CheckRepositionedCorrectly(i, element, test_case.head_up_vector,
{0, 0, -kTestRepositionDistance}, {1, 0, 0});
}
repositioner->set_enable(true);
for (size_t i = 0; i < test_cases.size(); i++) {
TestCase test_case = test_cases[i];
repositioner->set_laser_direction(test_case.laser_direction);
gfx::Quaternion quat{test_case.head_up_vector, {0, 1, 0}};
gfx::Transform head_pose(quat);
scene.OnBeginFrame(MsToTicks(0), head_pose);
CheckRepositionedCorrectly(i, element, test_case.head_up_vector,
test_case.expected_element_center,
test_case.expected_right_vector);
}
}
} // namespace vr