1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #include "ModeSelector.h"
18*ec779b8eSAndroid Build Coastguard Worker
19*ec779b8eSAndroid Build Coastguard Worker #include <gtest/gtest.h>
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include "media/QuaternionUtil.h"
22*ec779b8eSAndroid Build Coastguard Worker #include "TestUtil.h"
23*ec779b8eSAndroid Build Coastguard Worker
24*ec779b8eSAndroid Build Coastguard Worker namespace android {
25*ec779b8eSAndroid Build Coastguard Worker namespace media {
26*ec779b8eSAndroid Build Coastguard Worker namespace {
27*ec779b8eSAndroid Build Coastguard Worker
28*ec779b8eSAndroid Build Coastguard Worker using Eigen::Quaternionf;
29*ec779b8eSAndroid Build Coastguard Worker using Eigen::Vector3f;
30*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,Initial)31*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, Initial) {
32*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options;
33*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
34*ec779b8eSAndroid Build Coastguard Worker
35*ec779b8eSAndroid Build Coastguard Worker selector.calculate(0);
36*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::STATIC, selector.getActualMode());
37*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), Pose3f());
38*ec779b8eSAndroid Build Coastguard Worker }
39*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,InitialWorldRelative)40*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, InitialWorldRelative) {
41*ec779b8eSAndroid Build Coastguard Worker const Pose3f worldToHead({1, 2, 3}, Quaternionf::UnitRandom());
42*ec779b8eSAndroid Build Coastguard Worker
43*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options;
44*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options, HeadTrackingMode::WORLD_RELATIVE);
45*ec779b8eSAndroid Build Coastguard Worker
46*ec779b8eSAndroid Build Coastguard Worker selector.setWorldToHeadPose(0, worldToHead);
47*ec779b8eSAndroid Build Coastguard Worker selector.setScreenStable(0, true);
48*ec779b8eSAndroid Build Coastguard Worker selector.calculate(0);
49*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::WORLD_RELATIVE, selector.getActualMode());
50*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), worldToHead.inverse());
51*ec779b8eSAndroid Build Coastguard Worker }
52*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,InitialScreenRelative)53*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, InitialScreenRelative) {
54*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToHead({1, 2, 3}, Quaternionf::UnitRandom());
55*ec779b8eSAndroid Build Coastguard Worker
56*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options;
57*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options, HeadTrackingMode::SCREEN_RELATIVE);
58*ec779b8eSAndroid Build Coastguard Worker
59*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToHeadPose(0, screenToHead);
60*ec779b8eSAndroid Build Coastguard Worker selector.calculate(0);
61*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::SCREEN_RELATIVE, selector.getActualMode());
62*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), screenToHead.inverse());
63*ec779b8eSAndroid Build Coastguard Worker }
64*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,WorldRelative)65*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, WorldRelative) {
66*ec779b8eSAndroid Build Coastguard Worker const Pose3f worldToHead({1, 2, 3}, Quaternionf::UnitRandom());
67*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToStage({4, 5, 6}, Quaternionf::UnitRandom());
68*ec779b8eSAndroid Build Coastguard Worker
69*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options;
70*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
71*ec779b8eSAndroid Build Coastguard Worker
72*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToStagePose(screenToStage);
73*ec779b8eSAndroid Build Coastguard Worker selector.setDesiredMode(HeadTrackingMode::WORLD_RELATIVE);
74*ec779b8eSAndroid Build Coastguard Worker selector.setWorldToHeadPose(0, worldToHead);
75*ec779b8eSAndroid Build Coastguard Worker selector.setScreenStable(0, true);
76*ec779b8eSAndroid Build Coastguard Worker selector.calculate(0);
77*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::WORLD_RELATIVE, selector.getActualMode());
78*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), worldToHead.inverse() * screenToStage);
79*ec779b8eSAndroid Build Coastguard Worker }
80*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,WorldRelativeUnstable)81*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, WorldRelativeUnstable) {
82*ec779b8eSAndroid Build Coastguard Worker const Pose3f worldToHead({1, 2, 3}, Quaternionf::UnitRandom());
83*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToStage({4, 5, 6}, Quaternionf::UnitRandom());
84*ec779b8eSAndroid Build Coastguard Worker
85*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options{.freshnessTimeout = 100};
86*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
87*ec779b8eSAndroid Build Coastguard Worker
88*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToStagePose(screenToStage);
89*ec779b8eSAndroid Build Coastguard Worker selector.setDesiredMode(HeadTrackingMode::WORLD_RELATIVE);
90*ec779b8eSAndroid Build Coastguard Worker selector.setWorldToHeadPose(0, worldToHead);
91*ec779b8eSAndroid Build Coastguard Worker selector.setScreenStable(0, false);
92*ec779b8eSAndroid Build Coastguard Worker selector.calculate(10);
93*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::STATIC, selector.getActualMode());
94*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), screenToStage);
95*ec779b8eSAndroid Build Coastguard Worker }
96*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,WorldRelativeStableStale)97*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, WorldRelativeStableStale) {
98*ec779b8eSAndroid Build Coastguard Worker const Pose3f worldToHead({1, 2, 3}, Quaternionf::UnitRandom());
99*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToStage({4, 5, 6}, Quaternionf::UnitRandom());
100*ec779b8eSAndroid Build Coastguard Worker
101*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options{.freshnessTimeout = 100};
102*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
103*ec779b8eSAndroid Build Coastguard Worker
104*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToStagePose(screenToStage);
105*ec779b8eSAndroid Build Coastguard Worker selector.setDesiredMode(HeadTrackingMode::WORLD_RELATIVE);
106*ec779b8eSAndroid Build Coastguard Worker selector.setWorldToHeadPose(100, worldToHead);
107*ec779b8eSAndroid Build Coastguard Worker selector.setScreenStable(0, true);
108*ec779b8eSAndroid Build Coastguard Worker selector.calculate(101);
109*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::STATIC, selector.getActualMode());
110*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), screenToStage);
111*ec779b8eSAndroid Build Coastguard Worker }
112*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,WorldRelativeStale)113*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, WorldRelativeStale) {
114*ec779b8eSAndroid Build Coastguard Worker const Pose3f worldToHead({1, 2, 3}, Quaternionf::UnitRandom());
115*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToStage({4, 5, 6}, Quaternionf::UnitRandom());
116*ec779b8eSAndroid Build Coastguard Worker
117*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options{.freshnessTimeout = 100};
118*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
119*ec779b8eSAndroid Build Coastguard Worker
120*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToStagePose(screenToStage);
121*ec779b8eSAndroid Build Coastguard Worker selector.setDesiredMode(HeadTrackingMode::WORLD_RELATIVE);
122*ec779b8eSAndroid Build Coastguard Worker selector.setWorldToHeadPose(0, worldToHead);
123*ec779b8eSAndroid Build Coastguard Worker selector.calculate(101);
124*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::STATIC, selector.getActualMode());
125*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), screenToStage);
126*ec779b8eSAndroid Build Coastguard Worker }
127*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,ScreenRelative)128*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, ScreenRelative) {
129*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToHead({1, 2, 3}, Quaternionf::UnitRandom());
130*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToStage({4, 5, 6}, Quaternionf::UnitRandom());
131*ec779b8eSAndroid Build Coastguard Worker
132*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options;
133*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
134*ec779b8eSAndroid Build Coastguard Worker
135*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToStagePose(screenToStage);
136*ec779b8eSAndroid Build Coastguard Worker selector.setDesiredMode(HeadTrackingMode::SCREEN_RELATIVE);
137*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToHeadPose(0, screenToHead);
138*ec779b8eSAndroid Build Coastguard Worker selector.calculate(0);
139*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::SCREEN_RELATIVE, selector.getActualMode());
140*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), screenToHead.inverse() * screenToStage);
141*ec779b8eSAndroid Build Coastguard Worker }
142*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,ScreenRelativeStaleToWorldRelative)143*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, ScreenRelativeStaleToWorldRelative) {
144*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToHead({1, 2, 3}, Quaternionf::UnitRandom());
145*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToStage({4, 5, 6}, Quaternionf::UnitRandom());
146*ec779b8eSAndroid Build Coastguard Worker const Pose3f worldToHead({7, 8, 9}, Quaternionf::UnitRandom());
147*ec779b8eSAndroid Build Coastguard Worker
148*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options{.freshnessTimeout = 100};
149*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
150*ec779b8eSAndroid Build Coastguard Worker
151*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToStagePose(screenToStage);
152*ec779b8eSAndroid Build Coastguard Worker selector.setDesiredMode(HeadTrackingMode::SCREEN_RELATIVE);
153*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToHeadPose(0, screenToHead);
154*ec779b8eSAndroid Build Coastguard Worker selector.setWorldToHeadPose(50, worldToHead);
155*ec779b8eSAndroid Build Coastguard Worker selector.setScreenStable(50, true);
156*ec779b8eSAndroid Build Coastguard Worker selector.calculate(101);
157*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::WORLD_RELATIVE, selector.getActualMode());
158*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), worldToHead.inverse() * screenToStage);
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker
TEST(ModeSelector,ScreenRelativeInvalidToWorldRelative)161*ec779b8eSAndroid Build Coastguard Worker TEST(ModeSelector, ScreenRelativeInvalidToWorldRelative) {
162*ec779b8eSAndroid Build Coastguard Worker const Pose3f screenToStage({4, 5, 6}, Quaternionf::UnitRandom());
163*ec779b8eSAndroid Build Coastguard Worker const Pose3f worldToHead({7, 8, 9}, Quaternionf::UnitRandom());
164*ec779b8eSAndroid Build Coastguard Worker
165*ec779b8eSAndroid Build Coastguard Worker ModeSelector::Options options;
166*ec779b8eSAndroid Build Coastguard Worker ModeSelector selector(options);
167*ec779b8eSAndroid Build Coastguard Worker
168*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToStagePose(screenToStage);
169*ec779b8eSAndroid Build Coastguard Worker
170*ec779b8eSAndroid Build Coastguard Worker selector.setDesiredMode(HeadTrackingMode::SCREEN_RELATIVE);
171*ec779b8eSAndroid Build Coastguard Worker selector.setScreenToHeadPose(50, std::nullopt);
172*ec779b8eSAndroid Build Coastguard Worker selector.setWorldToHeadPose(50, worldToHead);
173*ec779b8eSAndroid Build Coastguard Worker selector.setScreenStable(50, true);
174*ec779b8eSAndroid Build Coastguard Worker selector.calculate(101);
175*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(HeadTrackingMode::WORLD_RELATIVE, selector.getActualMode());
176*ec779b8eSAndroid Build Coastguard Worker EXPECT_EQ(selector.getHeadToStagePose(), worldToHead.inverse() * screenToStage);
177*ec779b8eSAndroid Build Coastguard Worker }
178*ec779b8eSAndroid Build Coastguard Worker
179*ec779b8eSAndroid Build Coastguard Worker } // namespace
180*ec779b8eSAndroid Build Coastguard Worker } // namespace media
181*ec779b8eSAndroid Build Coastguard Worker } // namespace android
182