1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <limits>
19 
20 #include "HeadTrackingMode.h"
21 #include "Pose.h"
22 #include "Twist.h"
23 
24 namespace android {
25 namespace media {
26 
27 /**
28  * Main entry-point for this library.
29  * This interfaces encompasses all the processing required for determining the head-to-stage pose
30  * used for audio virtualization.
31  * The usage involves periodic setting of the inputs, calling calculate() and obtaining the outputs.
32  * This class is not thread-safe, but thread-compatible.
33  */
34 class HeadTrackingProcessor {
35   public:
36     virtual ~HeadTrackingProcessor() = default;
37 
38     struct Options {
39         float maxTranslationalVelocity = std::numeric_limits<float>::infinity();
40         float maxRotationalVelocity = std::numeric_limits<float>::infinity();
41         float translationalDriftTimeConstant = std::numeric_limits<float>::infinity();
42         float rotationalDriftTimeConstant = std::numeric_limits<float>::infinity();
43         int64_t freshnessTimeout = std::numeric_limits<int64_t>::max();
44         float predictionDuration = 0;
45     };
46 
47     /** Sets the desired head-tracking mode. */
48     virtual void setDesiredMode(HeadTrackingMode mode) = 0;
49 
50     /**
51      * Sets the world-to-head pose and head twist (velocity).
52      * headTwist is given in the head coordinate frame.
53      */
54     virtual void setWorldToHeadPose(int64_t timestamp, const Pose3f& worldToHead,
55                                     const Twist3f& headTwist) = 0;
56 
57     /**
58      * Sets the world-to-screen pose.
59      */
60     virtual void setWorldToScreenPose(int64_t timestamp, const Pose3f& worldToScreen) = 0;
61 
62     /**
63      * Set the screen-to-stage pose, used in all modes.
64      */
65     virtual void setScreenToStagePose(const Pose3f& screenToStage) = 0;
66 
67     /**
68      * Sets the display orientation.
69      * Orientation is expressed in the angle of rotation from the physical "up" side of the screen
70      * to the logical "up" side of the content displayed the screen. Counterclockwise angles, as
71      * viewed while facing the screen are positive.
72      */
73     virtual void setDisplayOrientation(float physicalToLogicalAngle) = 0;
74 
75     /**
76      * Process all the previous inputs and update the outputs.
77      */
78     virtual void calculate(int64_t timestamp) = 0;
79 
80     /**
81      * Get the aggregate head-to-stage pose (primary output of this module).
82      */
83     virtual Pose3f getHeadToStagePose() const = 0;
84 
85     /**
86      * Get the actual head-tracking mode (which may deviate from the desired one as mentioned in the
87      * class documentation above).
88      */
89     virtual HeadTrackingMode getActualMode() const = 0;
90 
91     /**
92      * This causes the current poses for both the head and/or screen to be considered "center".
93      */
94     virtual void recenter(bool recenterHead = true, bool recenterScreen = true) = 0;
95 };
96 
97 /**
98  * Creates an instance featuring a default implementation of the HeadTrackingProcessor interface.
99  */
100 std::unique_ptr<HeadTrackingProcessor> createHeadTrackingProcessor(
101         const HeadTrackingProcessor::Options& options,
102         HeadTrackingMode initialMode = HeadTrackingMode::STATIC);
103 
104 }  // namespace media
105 }  // namespace android
106